gpt4 book ai didi

windows - 自移动批处理文件

转载 作者:可可西里 更新时间:2023-11-01 11:24:37 25 4
gpt4 key购买 nike

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

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

其中 move_me.bat 是放置在 c:\temp 中的同名批处理文件,将被移动到 d:\temp。

我得到了错误

The batch file cannot be found.

即使批处理文件移动了位置。所以我有点困惑。我需要抑制错误还是最好复制批处理文件并删除源代码?或者有更好的方法吗?

最佳答案

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

您可以像这样调用批处理文件来抑制错误:

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

但这也无意中抑制了所有其他错误消息。

无论如何,也许以下方法对您有用——这是脚本 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 2 访问)被复制(未移动)到新位置 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) copyed.)。 || operator仅在复制失败时才执行下一条命令。因此,当执行原始批处理文件时,复制会按预期完成。当复制的批处理文件运行时,copy 会尝试将批处理文件复制到自身,这会导致消息 The file cannot be copy to 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 查询是必需的,因为 movecopy 不同,如果源和目标相等,则不会返回错误。


这是一个批处理文件的全面解决方案,它可以自行移动并随后将控制权交给被移动的文件。看看所有的解释性注释,找出哪个批处理文件实例运行的代码:

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

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

2) 请注意,一旦读取和解析命令行或 block ,就会立即解析此类参数引用,因此在实际执行之前。

关于windows - 自移动批处理文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42861154/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com