Есть ли способ нажать и вытолкнуть все переменные среды в пакетном скрипте?

10

Есть ли способ нажать и вытолкнуть все переменные среды в пакетном скрипте? Например, я хотел бы сделать что-то вроде этого:

pushEnvironmentVariables
call "%VS140COMNTOOLS%\vsvars32.bat"
(do some stuff...)
popEnvironmentVariables
pushEnvironmentVariables
call "%VS90COMNTOOLS%\vsvars32.bat"
(do some other stuff...)
popEnvironmentVariables
שלומי שטיין
источник

Ответы:

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.

LotPings
источник
Вы исключаете PATH- например или по какой-то причине. Я особенно заинтересован в push / pop переменной пути. Есть что-нибудь, что говорит против резервного копирования / восстановления PATH?
Волк
На самом деле, как пример, так и в случае, если важные изменения были применены к пути в то же время меры предосторожности. @wolf
LotPings
Ну, вы не можете быть уверены во всех случаях, но если вам нужно что-то добавить к пути только для конкретного сеанса, вы определенно заинтересованы в восстановлении пути после этого. Вам не нужно было бы делать это, если бы не было внешних инструментов, которые вызывают другие инструменты и ожидают, что они будут на пути.
Волк
1
Код открыт для изменений, если кто-то хочет восстановить всю среду, просто замените findstr на type.
LotPings
Спасибо, я просто хотел быть уверен, что не пропустил ничего важного.
Волк
1

Немного опоздал на сцену, но все равно идет. Ниже приведена реализация структуры данных стека в пакетных сценариях Windows.

Особенности:

  • Вы должны вызвать подпрограмму : InitializeStack перед использованием стека.
  • Поместите элементы в стек, вызвав функцию: Push .
  • Удаление элементов из стека путем вызова функции : Pop .
  • Переменная $ Count всегда будет содержать количество элементов в стеке.
  • Переменная $ Top всегда будет содержать самый последний элемент, добавленный в стек.
  • Переменная $ Bottom всегда будет содержать первый элемент, добавленный в стек.
  • Вы можете выгрузить содержимое стека, вызвав подпрограмму : DumpStack .
  • Типы элементов, которые вы можете поместить в стек, - это все, что можно сохранить в переменной. Например, Call: Push «Строка 1» , Call: Push «% 1» , Call: 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 подпрограммы, которые реализуют это.
Сафван