【问题标题】:Avoid robocopy to reset errorlevel in batch避免 robocopy 批量重置错误级别
【发布时间】:2018-01-30 13:04:42
【问题描述】:

我们的编译系统使用robocopy 复制二进制依赖项。例如,一个假设的copy_dependencies.bat 文件可能是这样的:

@echo off
robocopy %PARAMETERS% src_path\Debug   dst_path\Debug   dep_name.dll
robocopy %PARAMETERS% src_path\Release dst_path\Release dep_name.dll

由于此类二进制文件不会影响编译的成功,但会影响最终可执行文件的执行,因此我们希望为它们添加错误检查(例如检查路径或文件名的更改)。我们的想法是在测试运行时尽快捕获它们,而不是在更深层次上捕获它们。

如果批处理返回非零错误级别,那么我们的编译系统会自动停止,我们的第一种方法是在每个批处理结束时检查错误级别:

@echo off
robocopy %PARAMETERS% src_path\Debug   dst_path\Debug   dep_name.dll
robocopy %PARAMETERS% src_path\Release dst_path\Release dep_name.dll

if errorlevel 8 exit /b
exit /b 0

注意:我们检查至少 8 的错误级别,因为较小的值只是对我们的警告(额外文件等)。这就是为什么我们最后还将错误级别重置为0

问题是robocopy 重置了错误级别,因此如果第一个命令失败,则不会报告。然后,下一个解决方案是检查每个调用:

@echo off
robocopy %PARAMETERS% src_path\Debug   dst_path\Debug   dep_name.dll
if errorlevel 8 exit /b
robocopy %PARAMETERS% src_path\Release dst_path\Release dep_name.dll
if errorlevel 8 exit /b

exit /b 0

这里的问题是我们必须更改数百个文件。

除了 replace-all-like 脚本这样做之外,还有什么更简洁的方法吗?类似于 robocopy 的标志,我们可以添加到 PARAMETERS 以避免重置?

另一种方法可能涉及批处理的执行标志,如果错误级别为 8 或更高,则自动退出脚本(因此我们可以在编译开始时设置它)。


附言

到目前为止,我正在发布我们最好的解决方案,但它仍然需要修改所有文件。更改批处理文件(特别是因为简单的模式)现在不是很耗时,但我想知道是否有不涉及此类更改的解决方案。谢谢!

【问题讨论】:

  • 恐怕robocopy 没有标志来保留以前的ErrorLevel 值。无论如何,你应该首先澄清你想要发生的事情,以防第一行 robocopy 失败,那么第二行是否应该仍然执行......
  • @aschipfl 谢谢!实际上,在我们的情况下,只要copy_dependendies.bat 失败(错误级别> 0),执行或不执行以下 robocopy 将是相同的,因为它是由编译检查的
  • 你到底为什么要使用批处理文件?为什么不直接打电话给robocopy.exe
  • @aschipfl 我们的 makefile 结构类似于:1) 签出/更新 2) 依赖项 3) 编译 4) 构建后操作。第 2 步可能意味着许多操作(数十个依赖项),因此它们包含在单独的每个项目脚本中
  • 这不仅仅是 robocopy。 每个 Windows 可执行文件都会重置错误级别。除非您专门编写了一个在启动之前保存错误级别的应用程序,但即便如此,您也必须在命令行上将错误级别传递给应用程序,因为任何应用程序都无法自动获取先前运行的应用程序的退出代码。

标签: windows batch-file robocopy errorlevel


【解决方案1】:

更新

正如 cmets 中的 @DodgyCodeException 所建议的那样,最好的解决方案似乎是在每个 robocopy 语句前加上一个单行条件,以便仅在错误级别未达到的情况下执行 robocopy以前养过。示例中显示的copy_dependencies.bat 现在是:

@echo off
if not errorlevel 8 robocopy %PARAMETERS% src_path\Debug   dst_path\Debug   dep_name.dll
if not errorlevel 8 robocopy %PARAMETERS% src_path\Release dst_path\Release dep_name.dll

if errorlevel 8 exit /b
exit /b 0

先前的解决方案包括使用传播错误级别的中间批次(此处称为 my_robocopy.bat):

@echo off
if errorlevel 8 exit /b
robocopy %PARAMETERS% %*
exit /b

示例中显示的copy_dependencies.bat 现在是:

@echo off
call %COMMON_PATH%\my_robocopy.bat src_path\Debug   dst_path\Debug   dep_name.dll
call %COMMON_PATH%\my_robocopy.bat src_path\Release dst_path\Release dep_name.dll

if errorlevel 8 exit /b
exit /b 0

【讨论】:

  • 或者,将原始行替换为 if not errorlevel 8 robocopy %PARAMETERS% src_path\Release dst_path\Release dep_name.dll。创建高于 8 的错误的第一个命令将导致其余行失败。然后只需检查最后的错误级别。
  • @DodgyCodeException 这正是我想要的,谢谢!如果您愿意,请将其作为单独的答案发布以接受它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-11
  • 1970-01-01
  • 2017-02-12
  • 2017-07-24
相关资源
最近更新 更多