[英]Windows command line: why environment variable is not available after &
Have a look at the following commands: why is the value of a not available immediately after the &
? 看一看下面的命令:为什么是一个不后,立即可用的价值
&
?
C:\>set a=
C:\>set a=3&echo %a%
%a%
C:\>echo %a%
3
C:\>set a=3&echo %a%
3
But when I do 但是,当我这样做
C:\>set a=
C:\>set a=3&set
a=3 is included in the listed variables! a = 3包含在列出的变量中!
I need this for a trick I learned here, to get the exit code of a command even output is piped: Windows command interpreter: how to obtain exit code of first piped command but I have to use it in a make script, that's why everything must be in one line! 我需要这个我在这里学到的技巧,获取命令的退出代码甚至输出管道: Windows命令解释器:如何获取第一个管道命令的退出代码,但我必须在make脚本中使用它,这就是为什么一切必须在一行! This is what I am trying to do:
这就是我想要做的:
target:
($(command) & call echo %%^^errorlevel%% ^>$(exitcodefile)) 2>&1 | tee $(logfile) & set /p errorlevel_make=<$(exitcodefile) & exit /B %errorlevel_make%
But errorlevel_make is always empty (the file with the exit code exists and contains the correct exit code). 但是errorlevel_make总是为空(带有退出代码的文件存在且包含正确的退出代码)。
Is this a bug in cmd? 这是cmd中的错误吗? Any ideas what I can do?
任何想法我能做什么?
The reason for the observed behaviour is how the command line is processed. 观察到的行为的原因是命令行的处理方式。
In first case set a=3&echo %a%
, when the line is interpreted BEFORE EXECUTING IT, all variables are replaced with their values. 在第一种情况下,
set a=3&echo %a%
,当在执行IT之前解释该行时,所有变量都将替换为它们的值。 a has no value until line executes, so it can not be substituted in echo a在行执行之前没有任何值,所以它不能在echo中替换
In second case, set a=3&set
, there is no variable substitution before execution. 在第二种情况下,
set a=3&set
,执行前没有变量替换。 So, when set is executed, a has the value asigned. 因此,当执行set时,a具有asigned值。
It's much easier to create a seperate batch file to solve this, as it isn't obvious even for experts. 创建一个单独的批处理文件来解决这个问题要容易得多,因为即使对于专家来说也不是很明显。
But in your case this should work 但在你的情况下这应该工作
target:
($(command) & call echo %^^^^errorlevel% >$(exitcodefile)) 2>&1 | tee $(logfile) & set /p errorlevel_make=<$(exitcodefile) & call exit /B %^errorlevel_make%
A seperate batch could look like 单独的批次可能看起来像
extBatch.bat extBatch.bat
@echo off
("%~1" & call echo %%^^errorlevel%% > "%~2") 2>&1 | tee "%~3" & set /p errorlevel_make=<"%~2"
exit /B %errorlevel_make%
Then you could start the batch from your make file 然后,您可以从make文件启动批处理
target:
extBatch.bat $(command) $(exitcodefile) $(logfile)
Inspired by the nice answer of jeb, I modified the code a little to be able to grab errorlevel for each side of the pipe, separately. 受到jeb的好答案的启发,我修改了一些代码,以便能够分别为管道的每一侧获取errorlevel。 For example you have the following pipe in your batch file:
例如,批处理文件中包含以下管道:
CD non_exisitng 2>&1 | FIND /V ""
ECHO Errorlevel @right: %errorlevel%
The errorlevel above refers to the right-hand side of the pipe only, and it indicates if the FIND command succeeded of not. 上面的错误级别仅指向管道的右侧,它指示FIND命令是否成功。 However, to be able to get the errorlevel of both sides, we can change the above code to something like this:
但是,为了能够获得双方的错误级别,我们可以将上面的代码更改为:
(CD non_exisitng & CALL ECHO %%^^errorlevel%% >err) 2>&1 | FIND /V ""
ECHO Errorlevel @right: %errorlevel%
SET /P err=<err
ECHO Errorlevel @left: %err%
output: 输出:
The system cannot find the path specified.
errorlevel @right: 0
errorlevel @left: 1
@OP: @OP:
I realize this comes a bit late, but might be helpful for others. 我意识到这有点晚了,但可能对其他人有所帮助。 In addition to jeb's method of an external batch file, the original problem can also be solved as one-liner:
除了jeb的外部批处理文件的方法,原始问题也可以解决为单行:
target:
($(command) & call echo %%^^errorlevel%% >$(exitcodefile)) 2>&1 | tee $(logfile) & set /p errorlevel_make=<$(exitcodefile) & cmd /c call exit /B %%errorlevel_make%%
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.