看一下以下命令:为什么&
之后的值不可用?
C:\>set a=
C:\>set a=3&echo %a%
%a%
C:\>echo %a%
3
C:\>set a=3&echo %a%
3
但是当我做的时候
C:\>set a=
C:\>set a=3&set
a = 3包含在列出的变量中!
我需要这个我在这里学到的技巧,获取命令的退出代码甚至输出管道: Windows command interpreter: how to obtain exit code of first piped command 但我必须在make脚本中使用它,这就是为什么一切都必须在一行! 这就是我想要做的事情:
target:
($(command) & call echo %%^^errorlevel%% ^>$(exitcodefile)) 2>&1 | tee $(logfile) & set /p errorlevel_make=<$(exitcodefile) & exit /B %errorlevel_make%
但是errorlevel_make总是为空(带有退出代码的文件存在且包含正确的退出代码)。
这是cmd中的错误吗?有什么想法我可以做什么?
答案 0 :(得分:12)
观察到的行为的原因是命令行的处理方式。
在第一种情况set a=3&echo %a%
中,当在执行IT之前解释该行时,所有变量都将替换为它们的值。 a在行执行之前没有值,所以它不能在echo
在第二种情况下,set a=3&set
,在执行之前没有变量替换。因此,当执行set时,a的值为asigned。
答案 1 :(得分:5)
创建一个单独的批处理文件来解决这个问题要容易得多,因为即使是专家也不会这么做。
但在你的情况下这应该有用
target:
($(command) & call echo %^^^^errorlevel% >$(exitcodefile)) 2>&1 | tee $(logfile) & set /p errorlevel_make=<$(exitcodefile) & call exit /B %^errorlevel_make%
单独的批次可能看起来像
<强> extBatch.bat 强>
@echo off
("%~1" & call echo %%^^errorlevel%% > "%~2") 2>&1 | tee "%~3" & set /p errorlevel_make=<"%~2"
exit /B %errorlevel_make%
然后你可以从你的make文件中启动批处理
target:
extBatch.bat $(command) $(exitcodefile) $(logfile)
答案 2 :(得分:0)
受到jeb的好答案的启发,我修改了一些代码,以便能够分别为管道的每一侧获取errorlevel。例如,批处理文件中包含以下管道:
CD non_exisitng 2>&1 | FIND /V ""
ECHO Errorlevel @right: %errorlevel%
上面的错误级别仅指向管道的右侧,它指示FIND命令是否成功。 但是,为了能够获得双方的错误级别,我们可以将上面的代码更改为:
(CD non_exisitng & CALL ECHO %%^^errorlevel%% >err) 2>&1 | FIND /V ""
ECHO Errorlevel @right: %errorlevel%
SET /P err=<err
ECHO Errorlevel @left: %err%
<强>输出:强>
The system cannot find the path specified.
errorlevel @right: 0
errorlevel @left: 1
@OP:
我意识到这有点晚了,但可能对其他人有所帮助。除了jeb的外部批处理文件的方法,原始问题也可以解决为单行:
target:
($(command) & call echo %%^^errorlevel%% >$(exitcodefile)) 2>&1 | tee $(logfile) & set /p errorlevel_make=<$(exitcodefile) & cmd /c call exit /B %%errorlevel_make%%