Windows命令提示符cmd
不會在內存中緩存不批處理文件,它通過線從文件中讀取行他們。因此,只要move
命令完成,您將收到錯誤,因爲無法再找到該文件。
你可以這樣調用批處理文件來取消錯誤:
"C:\temp\move_me.bat" 2> nul
但這supresses所有其他錯誤消息也無意的。
無論如何,或許下面的方法對你的作品 - 這是腳本C:\temp\move_me.bat
:
if /I "%~dp0"=="D:\temp\" exit /B
rem // (some other code here...)
copy "%~f0" "D:\temp\%~nx0"
"D:\temp\%~nx0" & del "%~f0"
首先,在對D:\temp\
檢查當前運行批處理文件的位置;如果相等,批處理文件立即終止。
最後,原來的批處理文件(由%~f0
訪問)被複制(不是移動)到新位置D:\temp
(文件名,%~nx0
,保持不變)。
下一行從新位置運行批處理文件,但不使用call
,這需要返回到調用批處理腳本,但這不是我們想要的。當前一個命令完成時,&
operator允許執行下一個命令。儘管未使用call
,但由於整行已被cmd
讀取和解析,所以仍然執行下一個命令。但執行控制現在位於批處理文件的新實例中,因此錯誤消息The batch file cannot be found.
不再出現。
上述if
查詢立即退出批處理文件副本的執行,所以其他代碼不會運行兩次。
如果你不想跳過複製的批處理文件的執行,刪除if
命令行和修改copy
命令行來得到這樣的:
rem // (some other code here...)
copy "%~f0" "D:\temp\%~nx0" > nul || exit /B
"D:\temp\%~nx0" & del "%~f0"
的> nul
portion抑制顯示信息(包括摘要1 file(s) copied.
)。只有在複製失敗的情況下,||
operator才執行下一個命令。所以當原始批處理文件執行時,複製按預期完成。當複製的批處理文件運行時,copy
會嘗試將批處理文件複製到其自身,從而導致消息The file cannot be copied onto itself.
(被> nul
抑制),並且出現一個錯誤,該錯誤會觸發exit /B
命令(由於||
)離開該批處理文件,所以最後一行不會被執行。
您也可以使用move
實現相同的行爲;因此,相關的代碼如下所示:
if /I "%~dp0"=="D:\temp\" exit /B
rem // (some other code here...)
move "%~f0" "D:\temp\%~nx0" & "D:\temp\%~nx0"
或者,如果你想要的其他代碼不會被跳過了移動腳本:
rem // (some other code here...)
if /I not "%~dp0"=="D:\temp\" move "%~f0" "D:\temp\%~nx0" & "D:\temp\%~nx0"
的if
查詢條件是:move
,而相比之下, copy
,如果源和目標相等,則不返回錯誤。
下面是一個批處理文件的全面解決方案,該文件自動移動並對移動的文件進行控制。看看所有的解釋性說明,找出哪些代碼是由什麼批處理文件實例上運行:
@echo off
rem // Define constants here:
set "_TARGET=D:%~pnx0" & rem /* (this defines the movement destination;
rem in your situation, the original batch file is
rem `C:\temp\move_me.bat`, so the target file is
rem `D:\temp\move_me.bat` (only drive changes)) */
rem // (code that runs for both batch file instances...)
echo Batch file: "%~f0"
echo [executed by both files before the movement check]
rem // Check whether current batch file is the moved one:
if /I "%~f0"=="%_TARGET%" (
rem // (code that runs for the moved batch file instance only...)
echo Batch file: "%~f0"
echo [executed only by the moved file]
) else (
rem // (code than runs for the original batch file instance only...)
echo Batch file: "%~f0"
echo [executed only by the original file]
rem // Actually move the batch file here, then give control to the moved one:
> nul move "%~f0" "%_TARGET%"
"%_TARGET%"
rem /* (code that runs for the original batch file instance only;
rem this is run after the moved batch file has finished;
rem you must not use `goto` herein as the target label cannot be found,
rem because the original file does no longer exist at this point!) */
echo Batch file: "%~f0"
echo [executed only by the original file, but after the moved one has finished]
)
rem // (code that runs for the moved batch file instance only...)
echo Batch file: "%~f0"
echo [executed only by the moved file after the movement check]
exit /B
1)注意parenthesised (
/)
並繼續行^
的代碼塊被認爲是單個命令行:
(
echo This entire parenthesised block is
echo considered as a single command line.
)
echo This continued line &^
echo as well.
2)注意,這樣的參數的引用被立即儘快解析爲一個命令線O r塊被讀取和解析,因此在它被實際執行之前。
'move'後面的行不再被識別,我想。也許你可以在':continuation'部分把'move'改成'copy'並用'del'刪除原來的批處理文件...... – aschipfl
...或者保留'move',但是簡單地用'&'連接下一行' ,那麼應該認識到... – aschipfl