有没有一种方法可以在批处理脚本中推送和弹出所有环境变量?


10

有没有一种方法可以在批处理脚本中推送和弹出所有环境变量?例如,我想做这样的事情:

pushEnvironmentVariables
call "%VS140COMNTOOLS%\vsvars32.bat"
(do some stuff...)
popEnvironmentVariables
pushEnvironmentVariables
call "%VS90COMNTOOLS%\vsvars32.bat"
(do some other stuff...)
popEnvironmentVariables

Answers:


13

使用setlocal,请参见setlocal /?ss64.com/nt/setlocal

Setlocal
call "%VS140COMNTOOLS%\vsvars32.bat"
(do some stuff...)
Endlocal
Setlocal
call "%VS90COMNTOOLS%\vsvars32.bat"
(do some other stuff...)
Endlocal

要保存当前变量状态,您可以执行

set >MyVarStatus.txt

并稍后还原

@Echo off
For /f "tokens=1* delims==" %%A in (
  'findstr /V "^Path" MYVarStatus.txt '
) Do Set %%A=%%B

这将排除Path变量。


您排除PATH-仅出于举例或出于某些原因。我对推送/弹出路径变量特别感兴趣。有什么反对备份/还原PATH吗?

实际上,在此过程中,都同时对路径应用了示例以及万一重要的更改。@wolf
LotPings

好吧,您不能在所有情况下都确定,但是,如果您只需要为特定会话的路径添加一些内容,那么您肯定会对以后恢复路径感兴趣。如果没有外部工具调用其他工具并且期望它们在开发之路,则不必执行此操作。

1
该代码可以更改,如果要恢复整个环境,只需将findstr替换为type。
LotPings

谢谢,我只是想确保不要忽略任何重要的内容。

1

到现场有点晚,但是无论如何这里都进行了。以下是Windows批处理脚本中堆栈数据结构的实现。

特征:

  • 您必须在使用堆栈之前调用:InitializeStack子例程。
  • 通过调用:Push子例程将项目压入堆栈。
  • 通过调用:Pop子例程将项目弹出堆栈。
  • 变量$ Count将始终包含堆栈中的项目数。
  • 变量$ Top将始终包含添加到堆栈中的最新项。
  • 变量$ Bottom将始终包含添加到堆栈中的第一项。
  • 您可以通过调用:DumpStack子例程来转储堆栈的内容。
  • 您可以压入堆栈的项目类型是可以存储在变量中的任何内容。例如,调用:Push“ String 1”调用:Push“%1”调用:Push“%MyVariable%”等。

我在批处理文件中使用堆栈来跟踪子例程调用。我的批处理文件中的每个子例程都以Call:Push%0开头,它将当前子例程的名称压入堆栈,并以Call:Pop结尾。

有些人可能觉得它对于批处理脚本来说是个过大的杀手,但是我很喜欢创建它,我希望有人会觉得它有用,请享受

@Echo Off
Cls
SetLocal
SetLocal EnableExtensions
SetLocal EnableDelayedExpansion

Call :InitializeStack

Call :Push "String 1"
Call :Push "String 2"
Call :Push "String 3"
Call :Pop

Echo Total items in stack = !$Count!
Echo Top of stack         = !$Top!
Echo Bottom of stack      = !$Bottom!
Call :DumpStack

Goto End

:InitializeStack
:------------------------------------------------------------
Set "$Stack[0]=0"
Set "$Count=!$Stack[0]!"
Set "$Top="
Set "$Bottom="
Exit /b

:DumpStack
:------------------------------------------------------------
If !$Stack[0]! EQU 0 (
  Echo Stack is empty.
) Else (
  Echo.
  Echo Stack Dump
  Echo ----------
  For /l %%a In (!$Stack[0]!,-1,1) Do (Echo !$Stack[%%a]!)
)
Exit /b

:Push <String>
:------------------------------------------------------------
Set /a "$Stack[0]+=1"
Set "$Count=!$Stack[0]!"
Set "$Top=%~1"
Set "$Bottom=!$Stack[1]!"
Set "$Stack[!$Stack[0]!]=!$Top!"
Exit /b

:Pop
:------------------------------------------------------------
If !$Stack[0]! EQU 0 (
  Echo "Stack is empty."
) Else (
  Set "$Stack[!$Stack[0]!]="
  Set /a "$Stack[0]-=1"
  Set "$Count=!$Stack[0]!"
  If !$Stack[0]! GTR 0 (
    For %%a In (!$Stack[0]!) Do Set "$Top=!$Stack[%%a]!"
    Set "$Bottom=!$Stack[1]!"
  ) Else (
    Set "$Top="
    Set "$Bottom="
  )
)Exit /b

:PushAllEnvironmentVariables
:------------------------------------------------------------
For /f "Tokens=* Delims=" %%a In ('Set') Do Call :Push "%%a"
Exit /b

:PopAllEnvironmentVariables
:------------------------------------------------------------
For /l %%a In (!$Stack[0]!,-1,1) Do (Set !$Stack[%%a]!)
Exit /b

:End

因此,要推送所有环境变量,您可以调用:PushAllEnvironmentVariables,要还原所有环境变量,则可以调用:PopAllEnvironmentVariables


乍一看,这似乎是一件需要付出一些努力才能发展的事情,并且可能对某人有用。您能解释一下如何这个问题提供答案吗?
斯科特,

我的观点是,推送所有可以使用的环境变量: For /f "Tokens=* Delims=" %%a In ('Set') Do Call :Push "%%a" 恢复所有可以使用的环境变量: For /l %%a In (!$Stack[0]!,-1,1) Do (Set !$Stack[%%a]!) 我已经更新了答案,其中包括2个实现此目的的子例程。
萨夫万
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.