爲什麼不低於批處理文件保持變量時的CMD.exe終止批處理文件不守變量
@echo off
cmd /c "set var=hi"
if defined var (echo var is defined ("var=%var%")) else (echo var isn't defined)
pause
exit
有沒有辦法使用CMD/C,同時保持變量?爲什麼CMD/c不保存變量?
爲什麼不低於批處理文件保持變量時的CMD.exe終止批處理文件不守變量
@echo off
cmd /c "set var=hi"
if defined var (echo var is defined ("var=%var%")) else (echo var isn't defined)
pause
exit
有沒有辦法使用CMD/C,同時保持變量?爲什麼CMD/c不保存變量?
CMD/C開始一個新的子進程,具有這樣的變量存儲在內存中它自己的環境空間。當這個過程終止時,相關的環境空間就會丟失,所以你當然會失去在那裏定義的任何變量的定義。
用於子過程直接訪問或操縱父進程的變量這是不可能的。
如果您要執行一個簡單的命令,並擁有控制權的任何輸出,那麼你可以寫的定義,標準輸出,讓FOR/F捕獲輸出,這樣就可以在你的父進程設置的值。但是你需要延遲擴展。
注 - 這個例子是很空洞,但它應該得到點跨越
for /f "delims=" %%A in ('cmd /v:on /c "set var=hi&echo "var=!var!""') do set %%A
但事情可能會變得遠爲複雜,確定什麼是引用,需要轉義什麼,...如果你創建一個批處理腳本,做的工作,並用FOR/F執行它
生命可以被簡化。
test.bat的
@echo off
set var1=hi
set var2=Ain't this fun
set var3=bye
setlocal enableDelayedExpansion
for %%V in (var1 var2 var3) do echo "%%V=!%%V!"
main.bat
@echo off
for /f "delims=" %%A in ('cmd /c test.bat') do set %%A
其實,FOR/F採用隱式CMD/C,你不再需要啓用延遲擴展命令,這樣你就可以拋棄明確CMD/C
@echo off
for /f "delims=" %%A in ('test.bat') do set %%A
如果您不能控制輸出,那麼您必須將這些值寫入主腳本可以加載的臨時文件中。您可能會試圖編寫一個臨時批處理腳本來定義變量,但隨後您將冒着必須轉義某些字符的風險,具體取決於變量的內容。最安全的選擇是使用延遲擴展寫出來的變量名和值,並讓父進程使用FOR/F向他們加載。
test2.bat
@echo off
set var1=hi
set var2=Ain't this fun
set var3=bye
echo Here is some output that must be preserved, unrelated to variables
setlocal enableDelayedExpansion
(for %%V in (var1 var2 var3) do echo "%%V=!%%V!") >"%temp%\vars.temp"
爲主。蝙蝠
@echo off
setlocal disableDelayedExpansion
cmd /c test2.bat
call "%temp%\vars.bat"
for /f "usebackq delims=" %%V in ("%temp%\vars.temp") do set "%%V"
del "%temp%\vars.temp"
注意,延遲擴展必須在主要的過程,當你加載變量被禁用,否則你將失去任何VALU字符!
es當3210擴展時。
但要健壯,你應該做的事情,以確保每個實例使用唯一的臨時文件名,以便同時運行不揍海誓山盟。
在實際使用中,我會在批處理文件中執行調用'cmd/c「%〜0」',然後當批處理文件退出時,它將返回到主腳本。這是我能想到的'保持'批處理文件終止其自我的唯一方法。另外,如果CMD/c保存了變量,那麼它將允許腳本的其餘部分訪問它設置的變量。你能想到任何其他的解決方案,可以讓批處理文件自己調用它,同時保持它的環境空間嗎? –
@BurnieRiley - 只需在腳本的開頭添加一個'setlocal',腳本終止後,所有設置在腳本內部的變量都將被取消設置。 – SomethingDark
@BurnieRiley - 見我編輯的答案。 – dbenham
爲什麼你使用'cmd/c「set var = hi」'?這將在子進程中創建變量,並且變量將隨着它而死。 – npocmaka
我很欣賞你使用的是MCVE(嚴重的是,這個標籤超級難得),但爲什麼在這個世界上你會設置這樣的變量? – SomethingDark
@SomethingDark,這只是一個例子。在實際使用中,我會在批處理文件中調用cmd/c「%〜0」',然後當批處理文件退出時,它將返回到主腳本。這是我能想到的'保持'批處理文件終止其自我的唯一方法。另外,如果CMD/c保存了變量,那麼它將允許腳本的其餘部分訪問它設置的變量。長時間解釋soz –