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