我希望能够在 PowerShell 中运行的命令提示符脚本(即%ERRORLEVEL%
)的开头将cmd /c
环境变量(也称为“系统变量”)设置为任意值。每当人们想要设置%ERRORLEVEL%
(1)时,他们都会执行以下操作:
cmd /c "exit /b 3"
cmd /c "echo %ERRORLEVEL%"
但是,尽管在正常的命令提示符中运行上述命令时,
%ERRORLEVEL%
设置为3
,但是,如果在PowerShell中执行这些确切的行,则退出代码环境变量为,而不是设置为3
,并保持0
。此外,您无法执行以下操作:cmd /v:on /c "exit /b 3 & echo !ERRORLEVEL!"
exit
命令完全脱离命令执行范围(即cmd /c
),并且在运行&
之后没有其他命令。因此,我尝试在PowerShell中执行以下命令:
cmd /v:on /c "SET %ERRORLEVEL% = 4 & echo !ERRORLEVEL!"
预期的输出是
4
,但这始终输出0
。我无法弄清楚为什么我无法对SET
环境变量进行%ERRORLEVEL%
。我使用了延迟的命令执行(example here),但是在这里似乎没有任何麻烦。有人知道为什么
SET %ERRORLEVEL% = 4
命令不起作用吗? 如果您不是而不是能够使用
SET
环境变量,那么如何在如上所述的由&符号分隔的命令字符串(%ERRORLEVEL%
)中将&
设置为任意值?
最佳答案
如果要将最终退出代码存储在cmd.exe
变量中,以便以后与exit
一起使用,则不要尝试设置ERRORLEVEL
;相反,使用自定义变量名称;例如ec
(用于 e xit c ode):
# Execute in PowerShell
PS> cmd /v /c 'set "ec=3" & echo ... & exit /b !ec!'; $LASTEXITCODE
...
3
在
cmd.exe
一侧:set "ec=3"
将变量ec
设置为3
值"..."
中包含名称-值对,但可以清楚地描述值的结尾,并允许使用带有嵌入式特殊字符(例如&
)的值。 %ec%
(前扩展)或!ec!
(延迟扩展,如果通过setlocal enabledelayedexpansion
或通过命令行开关/v
-参见help setlocal
启用)echo ...
是代表其他命令exit /b !ec!
退出,变量ec
的值作为退出代码;请注意,由于延迟变量是在同一语句中设置的,因此必须通过延迟扩展将变量称为!ec!
而不是%ec%
。/b
(仅退出当前批处理文件)在这里没有区别;无论哪种方式,这种情况下的exit
语句都会确定cmd
实例的进程退出代码。 作为单个语句的一部分,使用
&
运算符对命令进行排序(无条件地依次执行)。在PowerShell端:
cmd.exe
的&
的类似物是;
,即语句分隔符-它允许您将多条语句放在一行上。 $LASTEXITCODE
是自动PowerShell变量,它包含最近执行的外部程序的进程退出代码,在本例中为cmd.exe
,其值为3
。 Does anyone have any idea why the command
SET %ERRORLEVEL% = 4
does not work?
总结关于问题的评论中的有用信息:
%ERRORLEVEL%
-cmd.exe
自动维护该变量以反射(reflect)最新命令的退出代码-请参阅底部。 =
变量分配中的cmd.exe
周围放置空格:=
之前的空格成为变量名称的一部分。 %...%
中(除非您要通过另一个变量(其值包含要分配给该变量的名称)来间接设置变量)。
set %ERRORLEVEL% = 4
通过
%ERRORLEVEL%
在命令序列的开头反射(reflect)0
,上述分配创建了一个字面名为0
(即%ERRORLEVEL%
的值,后跟一个空格)的变量,其值是 4
(即,一个空格后是4
) )。cmd.exe
中的变量:从根本上讲,除了下面讨论的异常(exception),
cmd.exe
中的变量都是环境变量。与Bash和PowerShell这样的shell不同,对于子进程看不到的shell本地变量没有单独的命名空间。
这具有以下含义:
%Path%
)与使用SET
命令定义的自定义变量共享相同的 namespace ,因此您必须注意名称冲突。 cmd.exe
session /批处理文件运行的子进程将继承在 session 中创建的自定义变量。setlocal
的使用不会改变它; setlocal
是cmd
的一种内部作用域机制,通过将其本地化到调用setlocal
的作用域(批处理文件),并通过后续的endlocal
调用或隐式地在其上删除它们,可以控制自定义环境变量的生存期。封闭批处理文件的末尾。 自定义变量是仅用于进程的环境变量,它们超出了
cmd.exe
进程的范围;必须通过注册表(例如setx.exe
实用程序)创建和修改持久性环境变量定义。除了预定义(持久)环境变量和自定义(仅 session )环境变量外,
cmd.exe
维护动态伪环境变量,例如%ERRORLEVEL%
和%RANDOM%
(请参见下面的列表):cmd.exe
本身维护的动态值... 注意:严格来说,仅在打开所谓的命令扩展名的情况下才启用这些动态变量,但是默认情况下是正确的(您可以使用
/E:OFF
禁用它们,但这是不明智的选择)。因为这些动态变量严格来说并不是子进程继承其副本的流程环境的一部分,所以它们不是环境变量,即使
help SET
在某种程度上将它们称为动态环境变量。您不应(也不能)修改这些变量。
如果尝试,真正发生的是用真实的,自定义的环境变量(根据定义具有静态值)来遮盖(覆盖)这些伪变量。
因此,依赖该名称的变量的后续代码将具有其通常的动态行为,因此可能会发生故障。
动态变量的列表,在Windows 10上通过
help SET
检索(添加了重点):If Command Extensions are enabled, then there are several dynamic environment variables that can be expanded but which don't show up in the list of variables displayed by
SET
. These variable values are computed dynamically each time the value of the variable is expanded. If the user explicitly defines a variable with one of these names, then that definition will override the dynamic one described below:
%CD%
- expands to the current directory string.%DATE%
- expands to current date using same format as DATE command.%TIME%
- expands to current time using same format as TIME command.%RANDOM%
- expands to a random decimal number between 0 and 32767.%ERRORLEVEL%
- expands to the current ERRORLEVEL value%CMDEXTVERSION%
- expands to the current Command Processor Extensions version number.%CMDCMDLINE%
- expands to the original command line that invoked the Command Processor.%HIGHESTNUMANODENUMBER%
- expands to the highest NUMA node number on this machine.
关于powershell - 如何在cmd/c中设置%ERRORLEVEL%?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60459093/