CMD中动态环境变量和普通环境变量的区别 [英] Difference between Dynamic Environment Variables and Normal Environment Variables in CMD

查看:34
本文介绍了CMD中动态环境变量和普通环境变量的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读一篇关于 ss64 的文章,内容涉及命令提示符中的环境变量.

I was reading an article on ss64 about Environment variables in Command Prompt.

本文后面有一个表格,其中列出了命令提示符中常见的环境变量.其中列出的一些变量被称为Volatile(只读).文章中的一句话说:-

Later in the article there exists a table which states environment variables found commonly in Command Prompt. Some of the variables listed there are termed as Volatile (Read Only). A sentence found in the article states:-

动态环境变量是只读的,每次扩展变量时都会计算.当所有变量都用 SET 列出时,这些将不会出现在列表中.不要试图直接设置动态变量.

Dynamic environment variables are read-only and are computed each time the variable is expanded. When all variables are listed with SET, these will not appear in the list. Do not attempt to directly SET a dynamic variable.

我理解了后面的两个陈述.但是第一个我看不懂.

I understood the later two statements. But i can't understand the first one.

怀疑:-

  • %userprofile% 是一个 非易失性 变量,它解析为 %SystemDrive%Users{username},而 %homepath% 是一个 volatile 变量,它解析为 Users{Username}.这两个命令非常相似(除了systemdrive).那么为什么一个是易失性的,另一个是非易失性的?

  • %userprofile% is an non-volatile variable, which resolves to %SystemDrive%Users{username}, and %homepath% is a volatile variable which resolves to Users{Username}. Both commands are quite similar (except for the systemdrive). Then why is one volatile and the other one non-volatile?

动态变量的标准是什么?是什么让 %appdata%(只是一个例子)成为非易失性变量?

What is the criteria for a variable to be dynamic? what makes %appdata% (just an ex.) an non volatile variable?

每次扩展变量时都会计算动态变量,这对于 %CD% %DATE% %TIME% %RANDOM% 等变量很有意义,因为它们会失去功能如果它们非易失性.但是它会如何影响 %homepath%?

Dynamic Variables are computed each time the variable is expanded, this makes sense for variables like %CD% %DATE% %TIME% %RANDOM% etc. as they would lose their functionality if they would be non-volatile. But how would it effect %homepath%?

一些非易失性变量在其中具有某种动态成分.前任.%userprofile% 在它的路径中有 %SystemDrive%{username} .那么这些变量怎么不是动态的呢?

Some non-volatile variables have sort-of dynamic components in them. Ex. %userprofile% has %SystemDrive% and {username} in it's path. Then how are those variables not dynamic?

推荐答案

使用语法%variable%!variable!!variable! 访问三种类型的变量.code> 在 Windows 命令提示符窗口或批处理文件中使用命令 setlocal 的选项 EnableDelayedExpansion 启用延迟环境变量扩展,即使用 %SystemRoot%System32cmd.exe.

There are three types of variables of which value is accessed using the syntax %variable% or !variable! on having enabled delayed environment variable expansion with using the option EnableDelayedExpansion of the command setlocal from within a Windows command prompt window or a batch file, i.e. using %SystemRoot%System32cmd.exe.

环境变量永久存储在 Windows 注册表中.

There are environment variables stored persistent in Windows registry.

  1. 用户变量存储在 Windows 注册表项下:

  1. User variables stored in Windows registry under the key:

HKEY_CURRENT_USEREnvironment

  • 系统变量存储在 Windows 注册表项下:

  • System variables stored in Windows registry under the key:

    HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSession ManagerEnvironment
    

  • user 变量仅针对存储它们的用户注册表配置单元的帐户定义(文件 %UserProfile% tuser.dat).系统 变量是为 Windows 计算机上使用的所有帐户定义的(文件 %SystemRoot%System32configSYSTEM).

    The user variables are defined for just the account in which user registry hive they are stored (file %UserProfile% tuser.dat). The system variables are defined for all accounts used on a Windows machine (file %SystemRoot%System32configSYSTEM).

    可以通过打开 Windows 控制面板,点击系统,点击上的下一步(左侧)来查看、编辑和删除持久存储的变量高级系统设置,然后点击按钮环境变量.上半部分是当前用户帐户的用户变量,下半部分是自Windows XP以来的系统变量.

    The persistent stored variables can be viewed, edited and deleted by opening the Windows Control Panel, clicking on System, clicking next (on left side) on Advanced system settings and clicking on button Environment Variables. The upper half is for the user variables of the current user account and the lower half is for the system variables since Windows XP.

    从 Windows XP 开始,默认定义为 user 变量的只有 TEMPTMP.

    There are defined by default as user variables only TEMP and TMP since Windows XP.

    预定义的系统变量列表是从 Windows XP 开始的:

    The list of predefined system variables is since Windows XP:

    ComSpec
    NUMBER_OF_PROCESSORS
    OS
    PATH
    PATHEXT
    PROCESSOR_ARCHITECTURE
    PROCESSOR_IDENTIFIER
    PROCESSOR_LEVEL
    PROCESSOR_REVISION
    TEMP
    TMP
    windir
    

    在 Windows Vista 和更新的 Windows 版本上,默认还定义了 system 变量 PSModulePath.

    There is on Windows Vista and newer Windows versions defined by default also the system variable PSModulePath.

    除了PATHPATHEXT 之外,任何预定义的系统 变量都不应删除或修改,因为这可能会导致很多麻烦甚至可能导致 Windows 不再启动.我强烈建议使用虚拟机来试验预定义的系统变量,在开始试验之前,该变量存在整个虚拟机映像的备份.

    None of the predefined system variables with exception of PATH and PATHEXT should be deleted or modified ever as this could cause lots of troubles which can even result in Windows not starting anymore. I would strongly recommend using a virtual machine on experimenting with the predefined system variables for which a backup of the entire virtual machine image exists before starting the experiments.

    建议先备份用户系统变量,然后通过打开命令提示符窗口并运行例如:

    It is advisable to make a backup of the user and system variables before playing around with them by opening a command prompt window and running for example:

    md C:VariablesBackup 2>nul
    %SystemRoot%System32
    eg.exe EXPORT HKCUEnvironment "C:VariablesBackupUserVariables.reg"
    %SystemRoot%System32
    eg.exe EXPORT "HKLMSYSTEMCurrentControlSetControlSession ManagerEnvironment" "C:VariablesBackupSystemVariables.reg"
    

    1.2 持久化存储变量的恢复

    可以在命令提示符窗口中恢复用户变量之前已经进行了备份:

    %SystemRoot%System32
    eg.exe DELETE "HKLMSYSTEMCurrentControlSetControlSession ManagerEnvironment" /f
    %SystemRoot%System32
    eg.exe IMPORT "C:VariablesBackupUserVariables.reg"
    

    恢复系统变量可以在以管理员身份打开的命令提示符窗口内完成,之前已经进行了备份:

    %SystemRoot%System32
    eg.exe DELETE HKCUEnvironment /f
    %SystemRoot%System32
    eg.exe IMPORT "C:VariablesBackupSystemVariables.reg"
    

    建议在从备份中恢复用户系统变量后重新启动 Windows,以确保所有进程都使用恢复的变量.

    It is advisable to restart Windows on having restored user and system variables from a backup to make sure that really all processes use the restored variables.

    考虑使用批处理文件修改用户系统 PATH的批处理文件程序员应该先阅读:

    Batch file programmers thinking about modification of user or system PATH with a batch file should read first:

    注意:绝对NO GO - NEVER EVER将命令SETX%PATH%一起使用在批处理文件中修改用户系统 PATH变量.

    ATTENTION: It is an absolute NO GO - NEVER EVER to use command SETX with %PATH% in a batch file to modify user or system PATH variable.

    在安装程序(可执行文件或脚本)时使用批处理文件修改用户系统PATH的唯一原因是程序主要供用户从 Windows 命令行使用.如果一个程序需要它的目录或其子目录之一在 PATH 中才能工作,那么它就是糟糕的设计.如果程序在 Windows 默认定义的文件夹路径中添加了 system PATH 的文件夹路径,那么它的设计非常糟糕.

    The only reason to modify user or system PATH with a batch file on installation of a program (executable or script) is that this program is designed for being mainly used by users from the Windows command line. A program is bad designed if it requires that its directory or one of its subdirectories is in PATH to work at all. A program is very bad designed if it adds a folder path to system PATH left to the folder paths defined by default by Windows.

    系统 PATH 变量应始终以:

    %SystemRoot%System32;%SystemRoot%;%SystemRoot%System32Wbem
    

    Windows 系统目录是包含大多数可执行文件和动态链接库的目录.因此,它应该始终是当前目录之后搜索可执行文件和库的第一个目录.

    The Windows system directory is the directory containing most executables and dynamic linked libraries. For that reason it should be always the first directory searched for executables and libraries after the current directory.

    预定义了更多 Windows 环境 变量,可以在以下位置看到:

    There are a lot more Windows environment variables predefined as it can be seen on:

    这些变量由 Windows shell 定义,默认情况下 explorer.exe 在 Windows 上启动,根据注册表项下的注册表值 Shell 作为 Windows shell 启动:

    These variables are defined by Windows shell which is by default explorer.exe being started on Windows start as Windows shell according to registry value Shell under registry key:

    HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionWinlogon
    

    Window shell 元素最受关注用户是 Windows 桌面、Windows 开始菜单和带有系统托盘的 Windows 任务栏.

    The Window shell elements noticed most by users are the Windows desktop, the Windows Start menu and the Windows taskbar with the system tray.

    Windows 外壳在其内存中定义了许多环境变量,具体取决于 Windows 注册表中针对当前用户帐户的各种值,而不是如上所述永久存储在 Windows 注册表中.每当创建新进程(例如从 Windows shell 启动可执行文件)时,都会复制当前的环境变量列表.

    The Windows shell defines in its memory lots of environment variables depending on various values in Windows registry for the current user account not stored persistent in Windows registry as described above. The current list of environment variables is copied whenever a new process is created like starting an executable from Windows shell.

    Windows shell 定义的环境变量列表,包括持久存储的用户系统变量以及当前用户帐户的shell变量可以通过打开命令提示符窗口并在没有任何附加参数的情况下运行命令 SET 来查看.

    The list of environment variables defined by Windows shell consisting of the persistent stored user and system variables and the shell variables for current user account can be seen by opening a command prompt window and running the command SET without any additional argument.

    大多数 shell 变量是从注册表字符串中定义的

    Most of the shell variables are defined from the registry strings under

    • HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorerShell 文件夹
    • HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorerUser Shell 文件夹
    • HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerShell 文件夹
    • HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionExplorerUser Shell 文件夹

    大多数注册表字符串值存在于 REG_EXPAND_SZ 类型的 User Shell FoldersREG_SZ 类型的 Shell Folders 中代码>.但是有一些注册表字符串值仅存在于两个注册表项之一下.

    Most of the registry string values exist in User Shell Folders of type REG_EXPAND_SZ and in Shell Folders of type REG_SZ. But there are some registry string values existing only under one of the two registry keys.

    另见:如何在用户的桌面目录中创建目录?
    在这个答案中详细解释了 Windows 资源管理器如何评估这些注册表字符串值并在用户使用 regedit.exereg.exe 手动修改时处理它们的示例shell 文件夹 Desktop.

    See also: How to create a directory in the user's desktop directory?
    In this answer is explained in detail how Windows Explorer evaluates these registry string values and handles them on manual modification by a user using regedit.exe or reg.exe on the example of the shell folder Desktop.

    函数CreateEnvironmentBlockexplorer.exeGetUserNameExWGetComputerNameExW 使用 Windows 内核库函数 CreateProcess.

    The function CreateEnvironmentBlock and the private shell32 function RegenerateUserEnvironment are used by explorer.exe with GetUserNameExW and GetComputerNameExW to create the environment variables list copied by Windows Explorer on starting an executable from Windows shell using the Windows kernel library function CreateProcess.

    另请参阅 Eryk Sun 就问题 cmd.exe的环境变量存放在哪里?

    在 64 位 Windows 上有一些环境变量取决于启动 64 位或 32 位可执行文件.微软在 WOW64 实施细节上记录了它们如下:

    There are some environment variables on 64-bit Windows which depend on starting a 64-bit or a 32-bit executable. Microsoft documented them on WOW64 Implementation Details as follows:

    64 位进程:

    PROCESSOR_ARCHITECTURE=AMD64 PROCESSOR_ARCHITECTURE=IA64 PROCESSOR_ARCHITECTURE=ARM64
    ProgramFiles=%ProgramFiles%
    ProgramW6432=%ProgramFiles%
    CommonProgramFiles=%CommonProgramFiles%
    CommonProgramW6432=%CommonProgramFiles%

    PROCESSOR_ARCHITECTURE=AMD64 or PROCESSOR_ARCHITECTURE=IA64 or PROCESSOR_ARCHITECTURE=ARM64
    ProgramFiles=%ProgramFiles%
    ProgramW6432=%ProgramFiles%
    CommonProgramFiles=%CommonProgramFiles%
    CommonProgramW6432=%CommonProgramFiles%

    Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP:从 Windows 7 和 Windows Server 2008 R2 开始添加了 ProgramW6432 和 CommonProgramW6432 环境变量.

    Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: The ProgramW6432 and CommonProgramW6432 environment variables were added starting with Windows 7 and Windows Server 2008 R2.

    32 位进程:

    PROCESSOR_ARCHITECTURE=x86
    PROCESSOR_ARCHITEW6432=%PROCESSOR_ARCHITECTURE%
    ProgramFiles=%ProgramFiles(x86)%
    ProgramW6432=%ProgramFiles%
    CommonProgramFiles=%CommonProgramFiles(x86)%
    CommonProgramW6432=%CommonProgramFiles%

    PROCESSOR_ARCHITECTURE=x86
    PROCESSOR_ARCHITEW6432=%PROCESSOR_ARCHITECTURE%
    ProgramFiles=%ProgramFiles(x86)%
    ProgramW6432=%ProgramFiles%
    CommonProgramFiles=%CommonProgramFiles(x86)%
    CommonProgramW6432=%CommonProgramFiles%

    环境 变量 PROCESSOR_ARCHITECTURE 的值不能用于从批处理文件中找出安装的 Windows 是 32 位 (x86) 还是 64-位(AMD64)Windows.该值取决于 64 位 %SystemRoot%Sysem32cmd.exe 或 32 位 %SystemRoot%SysWOW64cmd.exe 对批处理文件的处理> 在 64 位 Windows 上.

    The value of the environment variable PROCESSOR_ARCHITECTURE cannot be used to find out from within a batch file if the installed Windows is a 32-bit (x86) or a 64-bit (AMD64) Windows. The value depends on processing of the batch file by either 64-bit %SystemRoot%Sysem32cmd.exe or by 32-bit %SystemRoot%SysWOW64cmd.exe on 64-bit Windows.

    另请参阅 Microsoft 文档:

    See also the Microsoft documentations:

    在编写批处理文件时必须明智地使用由 Windows shell 定义的 环境 变量,该文件应设计为由同一或不同 Windows 机器上的其他帐户执行.由于环境的差异,许多在批处理文件作者的环境中运行良好的批处理文件在使用系统帐户或在不同机器上运行与计划任务相同的批处理文件设置的环境中不起作用变量列表.

    The usage of environment variables defined by the Windows shell must be done wisely on writing a batch file which should be designed for execution by other accounts on same or a different Windows machine. Many batch files working fine in environment of author of the batch file do not work in environment set up on running the same batch file as scheduled task with system account or on a different machine because of the differences in environment variables list.

    进程在使用 Windows 内核库函数 CreateProcess 启动可执行文件时定义的环境变量决定了启动的可执行文件可以使用的环境变量.

    The environment variables defined by a process on starting an executable with the Windows kernel library function CreateProcess determine the environment variables which the started executable can use.

    大多数应用程序使用值为 nullCreateProcess 作为参数 lpEnvironment.因此 CreateProcess 会复制当前进程的当前环境变量.出于这个原因,每个从 Windows 桌面、开始菜单或任务栏启动的可执行文件都会获得由 explorer.exe 实例定义的环境变量,作为 Windows shell 运行.

    Most applications use CreateProcess with value null for the parameter lpEnvironment. Therefore CreateProcess makes a copy of the current environment variables of the current process. For that reason every executable started from Windows desktop, start menu or taskbar gets the environment variables as defined by the explorer.exe instance running as Windows shell.

    使用 Windows 上默认定义的环境变量的非常好的编码可执行文件或脚本明确验证每个使用的环境变量是否确实已定义,否则使用合适的默认值,如 C:Windows在环境变量 SystemRoot 上未定义检查是否确实存在目录 C:Windows 并退出并在未定义的重要环境变量上显示适当的错误消息,然后可能导致伤害.

    A really very good coded executable or script using environment variables which are defined by default on Windows verify explicitly that every used environment variable is really defined and use otherwise a suitable default value like C:Windows on environment variable SystemRoot is not defined with checking if there is really a directory C:Windows and exit with an appropriate error message on an important environment variable not defined before causing perhaps damage.

    SystemRoot 是由 explorer.exe 定义为环境变量的 Windows shell 变量示例,该变量不是由 shell 文件夹的注册表字符串值决定的.某些环境变量值不应由用户在任何时候独立于其真实来源进行修改,脚本作者不需要知道这些是 Windows 实现细节.

    SystemRoot is an example for a Windows shell variable defined by explorer.exe as environment variable which is not determined by the registry string values of the shell folders. Some environment variable values should not be modified by a user at any time independent on its real source which no script author ever needs to know as being a Windows implementation detail.

    在命令提示符窗口中运行时,SET 命令输出的帮助中列出了一些变量 set/? 在运行时的环境变量列表中找不到只需set.

    There are some variables listed in help of command SET output on running in a command prompt window set /? which cannot be found in the list of environment variables on running just set.

    这些变量是:

    CD
    DATE
    TIME
    RANDOM
    ERRORLEVEL
    CMDEXTVERSION
    CMDCMDLINE
    HIGHESTNUMANODENUMBER
    

    动态变量是cmd.exe内部变量.因此,这些变量仅在 Windows 命令提示符窗口中可用,该窗口是正在运行的 cmd.exe 进程或由 cmd.exe 处理的批处理文件.动态变量在其他可执行文件或脚本中不可用,因为这些变量不是环境变量.

    The dynamic variables are internal variables of cmd.exe. So these variables are available only in a Windows command prompt window which is a running cmd.exe process or a batch file processed by cmd.exe. The dynamic variables are not available in other executables or scripts as these variables are not environment variables.

    最常用的动态变量是:

    1. 光盘
      当前目录路径不以反斜杠结尾,除非当前目录是驱动器的根目录.
    2. 日期
      当前本地日期的格式与 Windows 区域和语言设置中为帐户定义的格式相同.
    3. 时间
      当前本地时间的格式与 Windows 区域和语言设置中为帐户定义的格式相同.
    4. 错误级别
      先前执行的命令或程序的退出值.
    5. 随机
      0 到 32767 之间的随机十进制数.

    还有一些动态变量,但它们很少在批处理文件中使用.

    There are some more dynamic variables, but they are rarely used in batch files.

    另外还有一个变量 __AppDir__ 包含当前运行的路径 cmd.exe 总是以反斜杠结尾,微软没有记录.我建议不要使用这个 未记录 变量,因为不能保证 cmd.exe 的未来版本仍然有这个变量.__AppDir__ 在 64 位 Windows 上,例如 %SystemRoot%System32 在 64 位 %SystemRoot%System32cmd.exe> 当前正在运行,或 %SystemRoot%SysWOW64 在当前运行的 32 位 %SystemRoot%SysWOW64cmd.exe 上,或复制 的任何其他路径cmd.exe 到任何其他文件夹并启动 cmd.exe 的此副本.在 SS64 页面 How-to 上列出了更多未记录的动态变量:Windows 环境变量,出于同样的原因,应特别小心使用.

    There is additionally the variable __AppDir__ containing the path of currently running cmd.exe always ending with a backslash which is not documented by Microsoft. I recommend not using this undocumented variable as there is no guarantee that a future version of cmd.exe still has this variable. __AppDir__ is on 64-bit Windows, for example, %SystemRoot%System32 on 64-bit %SystemRoot%System32cmd.exe currently running, or %SystemRoot%SysWOW64 on 32-bit %SystemRoot%SysWOW64cmd.exe currently running, or any other path on copying cmd.exe to any other folder and starting this copy of cmd.exe. There are some more undocumented dynamic variables listed on SS64 page How-to: Windows Environment Variables which should be used only with special care for the same reason.

    最常用的动态变量的值由Windows命令处理器本身动态改变,而环境变量的值只有在执行过程中使用命令SET时才会改变重新定义环境变量的批处理文件.这是环境动态变量之间的重要区别.

    The values of the most used dynamic variables are changed dynamically by the Windows command processor itself while the values of the environment variables change only if command SET is used during execution of a batch file to redefine an environment variable. This is an important difference between environment and dynamic variables.

    每个环境变量都可以在已处理批处理文件的本地环境中删除或重新定义.没有只读环境变量.

    Every environment variable can be deleted or redefined in the local environment of a processed batch file. There is no environment variable read-only.

    cmd.exe 在其代码内部包含文件扩展名列表 .COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSCenvironment 变量 PATHEXTlocal 环境变量列表中不存在,则用作 PATHEXT 的值尽管如此,仍然能够找到在命令行或没有文件扩展名的批处理文件中指定的脚本和可执行文件.但是如果 environment 变量 PATHlocal<中不存在,cmd.exe 不包含文件夹路径列表作为后备列表/strong> 环境.因此,无论出于何种原因,批处理文件编写者都应该小心修改本地环境变量PATH.

    cmd.exe contains internally in its code the file extension list .COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC which is used as value for PATHEXT if the environment variable PATHEXT does not exist in local environment variables list to be able to find nevertheless scripts and executables specified on command line or in a batch file without file extension. But cmd.exe does not contain a list of folder paths as fallback list if the environment variable PATH does not exist in local environment. So a batch file writer should be careful on modification of local environment variable PATH for whatever reason.

    动态 变量的值与环境 变量的值一样,使用%variable%!variable! 启用延迟扩展.但是,如果存在具有指定名称的变量,Windows 命令处理器总是首先在当前的 环境 变量列表中搜索.仅当没有具有该名称的 环境 变量时,cmd 才会在其内部动态变量列表中搜索下一个,如果存在具有指定名称的变量.

    The values of the dynamic variables are referenced like the values of the environment variables with %variable% or !variable! on enabled delayed expansion. But the Windows command processor always searches first in the current list of environment variables if there is a variable with specified name. Only if there is no environment variable with that name, cmd searches next in its internal list of dynamic variables if there is one with the specified name.

    在定义与动态变量同名的环境变量后,无法再访问动态变量的当前值.出于这个原因,批处理文件编写者永远不应使用动态变量名称之一作为环境变量的名称.

    The current value of a dynamic variable cannot be accessed anymore on definition of an environment variable with same name as a dynamic variable. For that reason a batch file writer should never use one of the dynamic variable names as name for an environment variable.

    这里的代码演示了如果批处理文件编写者真的不知道定义一个名为 ERRORLEVELenvironment 变量会发生什么.

    Here is a code which demonstrates what happens if a batch file writer has the really not good idea to define an environment variable with name ERRORLEVEL.

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    echo/
    echo Define environment variable ERRORLEVEL with string value "014".
    echo/
    set ERRORLEVEL=014
    if %ERRORLEVEL% EQU 12 (echo EQU: ERRORLEVEL is 12.) else echo EQU: ERRORLEVEL is not 12.
    if %ERRORLEVEL% == 014 (echo  ==: ERRORLEVEL is 14.) else echo  ==: ERRORLEVEL is not 14.
    if errorlevel 0 (
        if not errorlevel 1 (echo  IF: ERRORLEVEL is 0.) else echo  IF: ERRORLEVEL is greater than 0.
    ) else echo  IF: ERRORLEVEL is less than 0.
    echo/
    echo Delete the environment variable ERRORLEVEL.
    echo/
    set ERRORLEVEL=
    if %ERRORLEVEL% EQU 12 (echo EQU: ERRORLEVEL is 12.) else echo EQU: ERRORLEVEL is not 12.
    if %ERRORLEVEL% == 014 (echo  ==: ERRORLEVEL is 14.) else echo  ==: ERRORLEVEL is not 14.
    if errorlevel 0 (
        if not errorlevel 1 (echo  IF: ERRORLEVEL is 0.) else echo  IF: ERRORLEVEL is greater than 0.
    ) else echo  IF: ERRORLEVEL is less than 0.
    echo/
    echo In all test cases the value of dynamic variable ERRORLEVEL was 0.
    echo/
    for %%I in (%CMDCMDLINE%) do if /I "%%~I" == "/c" pause & goto EndBatch
    :EndBatch
    endlocal
    

    这个批处理文件的输出是:

    The output of this batch file is:

    Define environment variable ERRORLEVEL with string value "014".
    
    EQU: ERRORLEVEL is 12.
     ==: ERRORLEVEL is 14.
     IF: ERRORLEVEL is 0.
    
    Delete the environment variable ERRORLEVEL.
    
    EQU: ERRORLEVEL is not 12.
     ==: ERRORLEVEL is not 14.
     IF: ERRORLEVEL is 0.
    
    In all test cases the value of dynamic variable ERRORLEVEL was 0.
    

    调试批处理文件上可以看出,第一个IF条件if %ERRORLEVEL% EQU 12 导致将 %ERRORLEVEL% 替换为字符串 014 因为存在 environment 变量 ERRORLEVEL 用这个字符串值定义.函数 wcstol 被命令IF 使用,因为运算符EQU 将字符串014 转换为八进制数,因为前导0 和字符串 12 到 32 位有符号整数值,并比较它们是否相等.因此第一个条件为真.

    It can be seen on debugging the batch file that the first IF condition if %ERRORLEVEL% EQU 12 results in replacing %ERRORLEVEL% by the string 014 because of there is the environment variable ERRORLEVEL defined with this string value. The function wcstol is used by command IF because of operator EQU to convert the string 014 being interpreted as octal number because of the leading 0 and the string 12 to 32-bit signed integer values and compare them on equality. Therefore the first condition is true.

    第二个 IF 条件 if %ERRORLEVEL% == 014 也会导致将 %ERRORLEVEL% 替换为字符串 014 因为有使用此字符串值定义的 environment 变量 ERRORLEVEL.但现在函数 lstrcmpW 是由命令 IF 使用,因为运算符 ==.因此第二个条件也成立.

    The second IF condition if %ERRORLEVEL% == 014 results also in replacing %ERRORLEVEL% by the string 014 because of there is the environment variable ERRORLEVEL defined with this string value. But now the function lstrcmpW is used by command IF because of operator ==. Therefore the second condition is also true.

    第三个 IF 条件使用在命令提示符窗口中运行 if/? 时命令 IF 输出的帮助解释的推荐语法.可以看出,使用推荐的语法会导致对 Windows 命令处理器内部动态变量ERRORLEVEL的值进行评估,即使环境变量定义为名称 ERRORLEVEL.如此处所示,用于评估先前执行的命令或程序的退出代码的推荐语法始终适用于批处理文件中的任何位置.

    The third IF condition uses the recommended syntax explained by help of command IF output on running if /? in a command prompt window. It can be seen that using the recommended syntax results in evaluation of the value of the internal dynamic variable ERRORLEVEL of Windows command processor even if an environment variable is defined with name ERRORLEVEL. The recommended syntax to evaluate the exit code of a previously executed command or program works always and anywhere within a batch file as demonstrated here.

    另见:

    此外还必须考虑到,访问 动态 变量的当前值总是基于 Windows 命令处理器扩展的变量引用,而不是命令或可执行文件的实际执行.

    Further it must be taken into account that accessing current value of a dynamic variable is always on variable reference being expanded by the Windows command processor and not real execution of the command or executable.

    证明这种差异的代码:

    @echo off
    setlocal EnableExtensions EnableDelayedExpansion
    for /L %%I in (1,1,3) do (
        echo %%DATE%% %%TIME%% is:  %DATE% %TIME%
        echo ^^!DATA^^! ^^!TIME^^! is:  !DATE! !TIME!
        echo %%RANDOM%%/^^!RANDOM^^!: %RANDOM%/!RANDOM!
        if exist %SystemRoot%System32	imeout.exe (
            %SystemRoot%System32	imeout.exe /T 3 /NOBREAK >nul
        ) else (
            %SystemRoot%System32ping.exe 127.0.0.1 -n 4 >nul
        )
    )
    for %%I in (%CMDCMDLINE%) do if /I "%%~I" == "/c" pause & goto EndBatch
    :EndBatch
    endlocal
    

    输出例如:

    %DATE% %TIME% is:  31.01.2021 13:54:30,67
    !DATA! !TIME! is:  31.01.2021 13:54:30,68
    %RANDOM%/!RANDOM!: 18841/27537
    %DATE% %TIME% is:  31.01.2021 13:54:30,67
    !DATA! !TIME! is:  31.01.2021 13:54:33,12
    %RANDOM%/!RANDOM!: 18841/16705
    %DATE% %TIME% is:  31.01.2021 13:54:30,67
    !DATA! !TIME! is:  31.01.2021 13:54:36,16
    %RANDOM%/!RANDOM!: 18841/32668
    

    %DATE% %TIME% 导致打印到控制台窗口的日期/时间是相同日期/时间的三倍,因为 Windows 命令处理器在解析整个命令块之前已经扩展了这两个变量引用命令 FOR 完全执行.%RANDOM% 出于同样的原因导致打印三倍相同的数字,而 !RANDOM! 通常打印三个不同的数字.

    %DATE% %TIME% results in printing to console window three times the same date/time because of these two variable references are expanded already by the Windows command processor on parsing the entire command block before command FOR is executed at all. %RANDOM% results in printing three times the same number for the same reason while !RANDOM! prints usually three different numbers.

    另见:

    if errorlevel numberif not errorlevel number 也可以在命令方块中使用!

    if errorlevel number and if not errorlevel number work also within a command block!

    动态 环境变量只能在默认启用命令扩展的情况下访问.否则 Windows 命令处理器会模拟 MS-DOS 和 Windows 95/98/ME 的 COMMAND.COM 行为(或多或少)不支持 动态 变量,如此代码所示:

    The dynamic environment variables can be accessed only with command extensions enabled as by default. Otherwise Windows command processor emulates COMMAND.COM behavior (more or less) of MS-DOS and Windows 95/98/ME not supporting dynamic variables at all as demonstrated by this code:

    @echo off
    setlocal DisableExtensions DisableDelayedExpansion
    echo/
    echo With command extensions disabled:
    echo/
    echo Date/time is: %DATE% %TIME%
    echo Current dir: "%CD%"
    endlocal
    setlocal EnableExtensions DisableDelayedExpansion
    echo/
    echo With command extensions enabled:
    echo/
    echo Date/time is: %DATE% %TIME%
    echo Current dir: "%CD%"
    echo/
    for %%I in (%CMDCMDLINE%) do if /I "%%~I" == "/c" pause & goto EndBatch
    :EndBatch
    endlocal
    

    输出例如:

    With command extensions disabled:
    
    Date/time is:
    Current dir: ""
    
    With command extensions enabled:
    
    Date/time is: 31.01.2021 14:17:42,92
    Current dir: "C:TempDevelopment & Test!"
    

    动态变量的值只能读取.无法使用命令 SET 修改 动态 变量的值,因为它会导致定义名为 environment 的变量动态 变量优先于动态 变量.

    The values of dynamic variables can be only read. It is not possible to modify the value of a dynamic variable with command SET as it results in the definition of an environment variable with the name of a dynamic variable which takes precedence over the dynamic variable.

    这篇关于CMD中动态环境变量和普通环境变量的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆