我已经在StackOverflow之类的线程上对此进行了大量调查,但是虽然我觉得我接近解决方案,但这个问题令我头疼。
我尝试做的事情:当连接特定的外部硬盘驱动器(通过WMIC上的VolumeSerialNumber区分)时,会找到驱动器号,并通过robocopy完成镜像。通过双击执行脚本。这就是我到目前为止所做的:
FOR /F "skip=1" %%i in ('wmic logicaldisk where VolumeSerialNumber^="XXXXXXXX" get deviceid 2^>nul') DO (
SET y=%%i
IF [%y%]==[] GOTO hdmissing
SET "backuphd=%%i"
GOTO endfor
)
:endfor
robocopy "C:\Users\Herbert\Documents" "%backuphd%\Backup\Documents" /MIR
ECHO Backup done
ECHO end
:hdmissing
ECHO Couldn't find external drive
:end
PAUSE
这样,永远不会检测到外部HD(%y%
始终为空字符串)。但是,如果我在同一个控制台会话中执行两次脚本,一切都按预期工作。但是我想让它在第一次执行时工作。
这是我迄今为止所尝试过的:
SET y=dummy
放在脚本的开头。总是找到HD,触发备份到C:如果HD实际上没有连接(显然SET y=%%i
没有改变y
?)%y%
更改为!y!
- 再次找到HD,答案 0 :(得分:2)
delayed expansion
问题的第3,576代,受污染环境的影响。
没有明显的setlocal
,因此y
在第一次运行后仍然在环境中设置 - 因此后来的运行特征与首次运行不同[&1;}现象。
在块语句(a parenthesised series of statements)
中,解析整个块并执行然后。块中的任何%var%
将在解析块时被该变量的值替换 - 在块执行之前 - 同样的事情适用于{{1 }}
因此,FOR ... DO (block)
将在遇到IF (something) else (somethingelse)
时使用%variables%
的值执行。
解决此问题的两种常见方法是1)使用IF
并使用setlocal enabledelayedexpansion
代替!var!
来访问已更改的%var%
或2}值以进行调用一个子程序,用于使用更改的值执行进一步处理。
您的案例中的密钥似乎没有var
和setlocal enabledelayeexpansion
- 因为!y!
就是那个 - 文字字符串!y!
,除非调用!y!
通过delayedexpansion
命令。
(话虽如此,
setlocal
会像
一样工作IF [%%i]==[] GOTO hdmissing
因为SET "y=%%i"
IF not defined y GOTO hdmissing
对if [not] defined var
的运行时值进行操作。 var
确保该行上的任何杂散尾随空格不包含在分配的值中
)
答案 1 :(得分:0)
正如Magoo已经指出的那样,!y!
无效,因为我忘了启用Delayed Expansion。然而,启用它需要你逃避某些角色,这对我来说似乎很烦人和乏味。可以将命令用双引号括在FOR循环中,就像在this question的两个编辑中所做的那样,但是我在解决它之后发现了不同的东西。
我所做的是移动块
IF [%y%]==[] GOTO hdmissing
SET "backuphd=%%i"
在:endfor
之后。这样,它就在for循环之外,%y%
会相应地扩展。
请注意,此解决方案的工作原理仅仅是因为我只需要一个项目,并且因为编程流程。
其他有用的方法可以在this question中找到。
但是,如果你想做同样的事情:没有WMIC的更容易(虽然不那么强大)解决方案可能包括
IF EXIST
进行检查,希望用户不要删除它,并且HD连接到相同的驱动器号。