自移动批处理文件 [英] Self-moving batch file

查看:78
本文介绍了自移动批处理文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种批处理文件在执行后将自身移动到已知位置的方法.自我移动-似乎是最恰当的名称,但我敢肯定有一个专门的术语.我想在所有其他代码运行后 移动批处理文件.

I'm looking for a way for a batch file to move itself to a known location after execution. Self-moving - seemed to be the most apt name but I'm sure there's a technical term for it. I want to move the batch file after all the other code has run.

move "C:\temp\move_me.bat"  "D:\temp\move_me.bat"  

move_me.bat是放置在c:\ temp中的同义批处理文件,该文件将移至d:\ temp.

Where move_me.bat is the eponymous batch file placed in c:\temp to be move to d:\temp.

我收到错误

找不到批处理文件.

The batch file cannot be found.

即使批处理文件已移动位置.所以我有点困惑.我需要抑制该错误,还是最好复制批处理文件并删除源?还是有更好的方法呢?

Even though the batch file moved location. So I'm a little confused. Do I need to supress the error or would it be best to copy the batch file and delete the source? Or is there a better way of doing this?

推荐答案

Windows命令提示符cmd不在内存中缓存批处理文件,而是逐行从 1 读取文件.因此,move命令完成后,您会立即收到错误消息,因为无法再找到该文件.

The Windows command prompt cmd does not cache batch files in memory, it reads them from the file line by line1. Therefore you receive an error as soon as the move command has been finished, because the file cannot be found any more.

您可以像这样调用批处理文件以消除该错误:

You can call the batch file like this to suppress the error:

"C:\temp\move_me.bat" 2> nul

但这会无意间抑制所有其他错误消息.

But this supresses every other error messages also unintentionally.

无论如何,也许以下方法对您有效-这是脚本C:\temp\move_me.bat:

Anyway, perhaps the following approach works for you -- this is the script 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\检查当前运行的批处理文件的位置;如果相等,则批处理文件将立即终止.

At first, the location of the currently run batch file is checked against D:\temp\; if it is equal, the batch file is immediately terminated.

最后,原始批处理文件(由访问) %~f0 2 )被复制(未移动)到新位置D:\temp(文件名

Finally, the original batch file (accessed by %~f02) is copied (not moved) to the new location D:\temp (the file name, %~nx0, remains the same).

下一行从新位置运行批处理文件,但不使用 call ,这是返回到调用批处理脚本所必需的,但这不是我们想要的. &运算符使下一个命令在前一个命令执行时执行一个完成.尽管未使用call,但由于cmd已读取并解析了整行,因此仍将执行下一条命令.但是执行控制现在位于批处理文件的新实例上,因此错误消息The batch file cannot be found.不再出现.

The next line runs the batch file from the new location, but without using call, which is needed to return to the calling batch script, but this is not what we want. The & operator lets the next command execute when the previous one is finished. Although call is not used, the next command is still executed as the entire line has already been read and parsed by cmd. But execution control is now at the new instance of the batch file, so the error message The batch file cannot be found. does no longer appear.

上述if查询立即退出了批处理文件副本的执行,因此其其他代码不会运行两次.

The aforementioned if query quits execution of the copy of the batch file immediately, so its other code does not run twice.

如果您不想跳过复制的批处理文件的执行,请删除if命令行并修改copy命令行以获取此信息:

In case you do not want to skip the execution of the copied batch file, remove the if command line and modify the copy command line to get this:

rem // (some other code here...)
copy "%~f0" "D:\temp\%~nx0" > nul || exit /B
"D:\temp\%~nx0" & del "%~f0"

> nul部分禁止显示消息(包括摘要1 file(s) copied.). ||运算符仅在以下情况下执行下一条命令:复制失败.因此,当执行原始批处理文件时,将按预期完成复制.复制的批处理文件运行时,copy尝试将批处理文件复制到自身上,这会导致出现消息The file cannot be copied onto itself.(被> nul抑制)并引发引发exit /B命令的错误(由于)离开批处理文件,因此不会尝试执行最后一行.

The > nul portion suppresses display messages (including the summary 1 file(s) copied.). The || operator executes the next command only in case the copying fails. So when the original batch file is executed, the copying is done as expected. When the copied batch file runs, copy tries to copy the batch file onto itself, which results in the message The file cannot be copied onto itself. (suppressed by > nul) and in an error that fires the exit /B command (due to ||) to leave the batch file, so the last line is not attempted to be executed.

您也可以使用move来实现相同的行为;因此相关代码如下:

You can achieve the same behaviour also using move; so the related code looks like this:

if /I "%~dp0"=="D:\temp\" exit /B
rem // (some other code here...)
move "%~f0" "D:\temp\%~nx0" & "D:\temp\%~nx0"

或者,如果您希望不为已移动的脚本跳过其他代码:

Or, if you want the other code not to be skipped for the moved script:

rem // (some other code here...)
if /I not "%~dp0"=="D:\temp\" move "%~f0" "D:\temp\%~nx0" & "D:\temp\%~nx0"

if查询是必需的,因为movecopy相反,如果源和目标相等,则不会返回错误.

The if query is necessary as move, in contrast to copy, does not return an error if source and destination are equal.

这是一个批处理文件的综合解决方案,该文件可自行移动并随后控制移动的文件.查看所有解释性说明,以了解哪些批处理文件实例运行了哪些代码:

Here is a comprehensive solution for a batch file that moves itself and gives control to the moved one afterwards. Take a look at all the explanatory remarks to find out what code is run by what batch file instance:

@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)请注意,带括号的代码(/)和连续行^被视为单个命令行:


1) Note that parenthesised blocks of code (/) and continued lines ^ are considered as a single command line:

(
    echo This entire parenthesised block is
    echo considered as a single command line.
)
echo This continued line & ^
echo as well.

2)请注意,这样的参数引用将在读取并解析了命令行或块后立即解析,因此在实际执行之前就被解析.

这篇关于自移动批处理文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆