【问题标题】:Skip when error occurs发生错误时跳过
【发布时间】:2009-12-27 18:37:23
【问题描述】:

我有以下批处理代码(cmd):

for /f "delims=" %%f in ('dir /b /s Example') do (
command
if %errorlevel%==1 (
command
SKIP
)
command
)

编辑: 为了让事情更清楚: for /f... 搜索名为“示例”的目录并循环搜索多个目录。 第一个command 是一个删除命令,它删除目录中的所有文件。 发生错误时发生的command 是一个echo 命令,它将有关错误的一些信息写入文本文件。 现在是洞skip 的东西;有时,由于access deniedthis file is in use by...,文件无法删除。通常,如果没有跳过的东西会发生什么,它只会停止命令并挂起。所以,我想做的是防止这种情况发生。或者,我想使用skip 之类的东西,所以它可以跳过文件并继续。所以我认为这个命令需要在delete 命令中传递。

我希望现在清楚了。

提前致谢。

【问题讨论】:

  • 当 for 可以为你遍历目录树时,调用 dir 是非常愚蠢的
  • 请更好地解释您需要什么。我试图用我的回答来猜测你的意图,但显然没有成功。那么,“跳过”是什么意思?也许您可以提供一个示例目录结构和批处理脚本在该目录结构上的预期行为。
  • 您对“skip”这个词的使用非常模棱两可。
  • @YourComputerHelpZ - 查看修改后的 fupsduck。感谢 Doc Brown 的 killtask 建议,我认为这应该对您有用。

标签: windows batch-file cmd skip


【解决方案1】:

像这样?

for /f "delims=" %%f in ('dir /b /s Example') do (
  command
  if not errorlevel 1 (
    command-for-success
  ) else (
    command-for-error
  )
)

【讨论】:

  • @Johannes -- 哇,我不知道“||”!看起来是编写简短替代方案的好方法。
  • 这并不是我真正想要的。我想让它跳过它,然后继续。该命令的作用是查找“示例”,然后删除该目录中的所有内容。问题是你不能很容易地“跳过”它。
  • 在批处理脚本中,也可以使用goto
  • @YourComputerHelpZ:当发生错误时,此解决方案确实会跳过“command-for-success”,而是执行“command-for-error”,并继续处理“example”中的下一个文件。请更好地解释您认为缺少什么。
【解决方案2】:

创建两个命令文件并运行 delex.cmd。未删除的文件和目录将记录到 delex.txt。挂起的那些将打开一个最小化的 cmd 窗口,该窗口会在使用 ping 延迟后被杀死(感谢 Doc Brown 的建议)。

delex2.cmd
----------
@echo off
del /q %1 
if exist %1 echo %1 not deleted!>>delex.txt 
exit 

delex.cmd
---------
@echo off
if exist delex.txt del delex.txt 
for /f "delims=" %%f in ('dir /s /b example') do start "delextaskkill" /min delex2.cmd "%%f"
ping 127.0.0.1 -n 3 -w 1000> nul
taskkill /fi "Windowtitle eq delextaskkill"> nul

测试:

\example
|   file1
|   file2
|   file3
|   file4
|   file5
|
\---example
        file1
        file2
        file3
        file4
        file5

【讨论】:

  • 我认为这个可以改进以在给定超时后关闭所有“挂起”窗口。为“开始”命令添加一个特殊的窗口标题。使用malektips.com/dos0017.html模拟“等待”命令(例如等待10秒后),使用taskkill /fi "Windowtitle eq " 杀死所有挂起的窗口。
【解决方案3】:

当使用del,出现“拒绝访问”或“此文件正在被...使用”时,%errorlevel%为0,所以测试%errolevel%是没有用的。也许以下简单的解决方案适用于您的情况:

for /f "delims=" %%f in ('dir /b /s Example') do (
    del %%f
    if exist %%f (
         echo "file not deleted"
    ) else (
         echo "file deleted"
    )
 ) 

【讨论】:

  • 但它不会跳过,是吗?
  • 我在“示例”目录中尝试了 3 个文件,一个写保护,两个正在使用,我得到 3 次“文件未删除”。如果这不是您所说的“跳过”,请提供更好的示例或解释。
【解决方案4】:

我相信这就是你想要的

for /f "delims=" %%f in ('dir /b /s Example') do (
  command
  if not errorlevel 1 (
    command
  ) else (
    command
    goto :eof
  )
)

【讨论】:

  • 这和@atzz 一样,再说一遍,看cmets,我不喜欢那种东西。
  • 这是我试图理解“跳过”的意思的最佳尝试。努力改进你的解释,因为如果你不这样做,你只会怀疑你真正重视一个好答案的数量。你对被理解缺乏兴趣只会与你的粗鲁相媲美。
【解决方案5】:

也许这比仅使用内置 cmd 处理更先进。为什么不考虑使用 Windows 脚本主机 (vbscript/jscript) 甚至 PowerShell?两者都可能为您提供所需的控制级别。

【讨论】:

    【解决方案6】:

    试试这个批处理文件:

    @echo off
    REM For each directory named 'Example' ...
    for /f "delims=" %%f in ('dir /b /s Example') do (
        REM .. enter the directory and delete all the files found there.
        pushd .
        cd %%f
        del /q *
        for /f "delims=" %%z in ('dir /b') do (
            REM Any files that still exist must have been inaccessable.  Log an error.
            echo Unable to delete file %%z > C:\logfile.txt
        )
        popd
    )
    

    使用以下目录结构进行测试:

    folder\
    |------Example\
    |      |-------file1 (write-protected)
    |      |-------file2
    |      |-------file3
    |------deeper\
           |-------Example\
                   |-------file4
                   |-------file5 (write-protected)
                   |-------file6
    

    运行批处理文件后,只剩下file1file5。为遇到的每个写保护文件打印“访问被拒绝”消息;如果这很烦人,您可以重定向批处理文件的输出,例如 script.bat > NUL 以隐藏它。

    【讨论】:

      【解决方案7】:

      所以在所有现有的答案都不能满足你之后,你绝对需要在你的批处理文件中跳过,我会再试一次:

      @echo off
      setlocal
      
      for /f "delims=" %%f in ('dir /b /s batch') do call :DoSomething %%f
      goto end
      
      :DoSomething
      echo Here i am: %1
      if %errorlevel%==1 goto :eof
      
      echo No error occured
      goto :eof
      
      :end
      endlocal
      

      诀窍在于,for 循环调用同一文件中的子函数并为其提供所需的参数。这个新的调用在新的上下文中运行,并且只能访问在给定顺序 do call :DoSomething 之后定义的变量。

      所以你必须用%1%2等来访问这里的变量。如果你想离开这个上下文,你必须创建一个goto :eof来跳转到文件的末尾(这个标记是预定义的在批处理模式下,不应出现在您的文件中),离开上下文并返回到 for 循环。

      运行整个循环后,我们只需跳转到:end 标记,稍微清理一下就完成了。

      【讨论】:

        【解决方案8】:

        以下内容在“dirname”目录树下递归查找您想要的文件扩展名,并针对该文件名执行 commandstuff.bat:

        for /r %i in (c:\dirname\*.ext) 做 命令“%i”

        Commandstuff.bat 看起来像这样:

        @ECHO 关闭
        del %1
        IF (%ERRORLEVEL% == 0) 转到结束
        :ERROR
        删除 %1 时出现回显错误

        :END
        回声结束

        这将运行 commandstuff.bat 来删除您想要的文件。当出现错误时,它会简单地回显文件详细信息并继续处理下一个文件。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-10-01
          • 1970-01-01
          • 2014-07-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-11-04
          相关资源
          最近更新 更多