2017-07-03 36 views
0

我试图做一个脚本,将不断在后台运行。它的目标是检测USB闪存驱动器,外部硬盘驱动器或任何可连接到计算机的可写设备。一旦检测到它,它会复制该设备根目录下的文件。这里是我的代码(回声线是为了更清晰的调试):Errorlevel变量在错误后不会更改..?

@echo off 
:loop 
for /F "tokens=1*" %%a in ('fsutil fsinfo drives') do (
    for %%c in (%%b) do (
     for /F "tokens=4" %%d in ('fsutil fsinfo drivetype %%c') do (
      if %%d equ amovible (
       echo Found out that %%c is removable. Trying to echo the content... 
       dir %%c >NUL 
       echo Error: %errorlevel% 
       if %errorlevel%==0 (
        echo Errorlevel is 0! Copying... 
        if not exist %%c\test.txt (
         copy .\test.txt %%c\test.txt 
         echo. 
        ) 
       ) else (
        echo Errorlevel isn't 0. Looks like the drive isn't here, or is unavailable. Aborting copying... 
        echo. 
       ) 
      ) 
     ) 
    ) 
) 
TIMEOUT 2 
goto :loop 

这就是问题所在。条件“if%errorlevel%== 0”应该检查“dir %% c> NUL”命令是否成功,所以如果errorlevel为0,这意味着设备上有一个文件系统,并且它不像空卡阅读器或空软盘驱动器。事情是当我执行我的代码时,errorlevel始终为0,我无法弄清楚为什么(“echo Error:%errorlevel%”告诉它)。所以文件test.txt在我的USB闪存驱动器上复制,所以这基本上工作,就是当它将文件复制到我的软盘驱动器,一个错误框显示,说我应该插入一个设备在阅读器,这就是为什么我想要做这个错误级别检查。

所以如果有人有解决方案,请帮助,我真的卡住了。 在此先感谢。

+1

您需要使用[延迟扩展(http://ss64.com/nt/delayedexpansion.html)(''的ErrorLevel),否则,你得到的'ErrorLevel'!当整个圆括号的块(循环)被解析时出现... – aschipfl

+0

哇,谢谢你!像魅力一样工作! – Alpha

+1

你当然可以使用经典的'如果不是错误级别1 ...',它不需要延迟扩展。 – LotPings

回答

2

您需要使用delayed expansion!ErrorLevel!),否则,你得到的ErrorLevel值存在当整个parenthesised块(也就是这里的嵌套for循环结构)进行解析。因为感叹号被延迟扩展功能消耗,我将使它只在那里实际需要,如:

@echo off 
setlocal EnableExtensions DisableDelayedExpansion 
:loop 
for /F "tokens=1*" %%a in ('fsutil fsinfo drives') do (
    for %%c in (%%b) do (
     for /F "tokens=4" %%d in ('fsutil fsinfo drivetype %%c') do (
      if "%%d"=="amovible" (
       echo Found out that %%c is removable. Trying to echo the content... 
       dir "%%~c" > nul 
       setlocal EnableDelayedExpansion 
       echo Error: !ErrorLevel! 
       if !ErrorLevel! equ 0 (
        endlocal 
        echo ErrorLevel is 0! Copying... 
        if not exist "%%~c\test.txt" (
         copy ".\test.txt" "%%~c\test.txt" 
         echo/ 
        ) 
       ) else (
        endlocal 
        echo ErrorLevel isn't 0. Looks like the drive isn't here, or is unavailable. Aborting copying... 
        echo/ 
       ) 
      ) 
     ) 
    ) 
) 
timeout 2 
goto :loop 
endlocal 

另外,由于dir也从未ErrorLevel为负值,你也可以使用if not errorlevel 1 syntax,意思是“如果不是ErrorLevel大于或等于1”,因此,“如果ErrorLevel小于1”(显然不能回声实际ErrorLevel值然后):

   ... 
       dir "%%~c" > nul 
       if not ErrorLevel 1 (
        echo ErrorLevel is 0! Copying... 
        if not exist "%%~c\test.txt" (
         copy ".\test.txt" "%%~c\test.txt" 
         echo/ 
        ) 
       ) else (
        echo ErrorLevel isn't 0. Looks like the drive isn't here, or is unavailable. Aborting copying... 
        echo/ 
       ) 
       ... 

另一种方法是使用conditional execution operators && and/or ||,它允许以下命令或块仅在上述命令返回零的退出代码的情况下执行(大部分时间,并且对于此处的dir命令,退出代码也是相同的值为ErrorLevel):

   ... 
       dir "%%~c" > nul && (
        echo ErrorLevel is 0! Copying... 
        if not exist "%%~c\test.txt" (
         copy ".\test.txt" "%%~c\test.txt" 
         echo/ 
        ) 
       ) || (
        echo ErrorLevel isn't 0. Looks like the drive isn't here, or is unavailable. Aborting copying... 
        echo/ 
       ) 
       ... 
+0

+1非常好的答案。我不明白为什么人们使用'if%ERRORLEVEL %== 0'或在一个命令块中if!ERRORLEVEL!== 0'而不是'如果不是errorlevel 1'来测试之前执行的命令/应用程序的退出代码是否为0(或否定),因为不扩展环境变量的方法自从MS-DOS起作用并且微软甚至编写了支持许多年前的文章,请参阅[测试批处理文件中的特定错误级别](https://support.microsoft.com/zh-cn/kb/69576)。 – Mofi

+0

谢谢@莫菲!是的,我完全同意,我认为即使在伪变量%ErrorLevel%被引入之前,如果ErrorLevel语法存在,无论如何,人们似乎仍然被这种语法所困惑;我相信如果ErrorLevel 1等于1,而不是ErrorErvel大于或等于1,那么错误地解释错误'ErrorLevel 1'“,所以他们更喜欢更明显的变体'如果%ErrorLevel%equ 1'等... – aschipfl

+0

+ aschipfl Ooooh,它是“大于或等于”?我不知道!我认为这只是“等于”,感谢提示男人^^! – Alpha