[英]How to pass environment variables as parameters by reference to another batch file?
我對 Windows 批次有疑問。 我有兩個批處理文件/腳本,第一個調用第二個,多次使用不同的參數。
我想在第一個中創建幾個環境變量並將它們作為參數傳遞給第二個。 在第二個批處理腳本中,傳遞的變量應分別增加一個在第二個批處理文件中確定的值。 然后在第二個批處理文件的下一次調用中再次傳遞第一個批處理文件中的環境變量,並且它們的值應該由第二個批處理文件相應地再次遞增。
First.bat 腳本:
::Modules find
set anz_Modules=0
::Modules build successful
set SR_Modules=0
set CPP_Modules=0
call ./Pearl_p2cpp.bat EXTRA auto anz_Modules SR_Modules CPP_Modules
rem Here are more calls of Pearl_p2cpp.bat with varying first parameter.
call ./Pearl_p2cpp.bat FKT auto anz_Modules SR_Modules CPP_Modules
Second.bat 腳本Pearl_p2cpp.bat
:
::Globale Variablen aus *_ALLES.bat bearbeiten
if NOT[%3]==[] goto noParams
set /a "%~3=%3%+%numberOfModuls%"
if NOT[%4]==[] goto noParams
set /a "%~4=%4%+%SRecordSuccess%"
if NOT[%5]==[] goto noParams
set /a "%~5=%5%+%CppSuccess%"
:noParams
再次使用 First.bat 腳本:
echo Es wurden insgesammt [%anz_Modules%]*.P (PEARL)-Module gefunden
echo aus diesen wurden [%SR_Modules%]-SREC und [%CPP_Modules%]-C++ Dateien in %TookTime:~0,-2%.%TookTime:~-2% seconds gebuildet!
Output:
Es wurden insgesammt [0]*.P (PEARL)-Module gefunden
aus diesen wurden [0]-SREC und [0]-C++ Dateien in 143.41 seconds gebuildet!
增加或編輯變量似乎不起作用。
問題是什么?
2021 年 4 月 9 日更新:
以下是根據 Mofi 在最終刪除的評論中的建議更改的批處理腳本。 第二個批處理文件現在使用保存臨時值的局部變量。 第二個批處理文件應在endlocal
末尾使用 set "%~3=%interimVAR%"
傳回新值。
但是 output 仍然是錯誤的,因為 output 是第一個批處理文件的初始值。
完整的 first.bat 腳本:
@echo off
:: Store start time
set StartTIME=%TIME%
set H=%StartTIME:~0,2%
if "%H:~0,1%"==" " set H=%H:~1,1%
if "%H:~0,1%"=="0" set H=%H:~1,1%
set M=%StartTIME:~3,2%
if "%M:~0,1%"=="0" set M=%M:~1,1%
set S=%StartTIME:~6,2%
if "%S:~0,1%"=="0" set S=%S:~1,1%
set U=%StartTIME:~9,2%
if "%U:~0,1%"=="0" set U=%U:~1,1%
)
set /a Start100S=%H%*360000+%M%*6000+%S%*100+%U%
::Modules found
set /A "anz_Modules = 0"
::Modules build successful
set /A "SR_Modules = 0"
set /A "CPP_Modules = 0"
call "%~dp0Pearl_p2cpp.bat" EXTRA auto %anz_Modules% %SR_Modules% %CPP_Modules%
call cd ../.batch_scripts
call "%~dp0Pearl_p2cpp.bat" FKT auto %anz_Modules% %SR_Modules% %CPP_Modules%
call cd ../.batch_scripts
call "%~dp0Pearl_p2cpp.bat" FKTREP auto %anz_Modules% %SR_Modules% %CPP_Modules%
call cd ../.batch_scripts
call "%~dp0Pearl_p2cpp.bat" FKTZU auto %anz_Modules% %SR_Modules% %CPP_Modules%
call cd ../.batch_scripts
call "%~dp0Pearl_p2cpp.bat" KALIB auto %anz_Modules% %SR_Modules% %CPP_Modules%
call cd ../.batch_scripts
call "%~dp0Pearl_p2cpp.bat" LASER auto %anz_Modules% %SR_Modules% %CPP_Modules%
call cd ../.batch_scripts
call "%~dp0Pearl_p2cpp.bat" MOAB auto %anz_Modules% %SR_Modules% %CPP_Modules%
call cd ../.batch_scripts
call "%~dp0Pearl_p2cpp.bat" MOENDE auto %anz_Modules% %SR_Modules% %CPP_Modules%
call cd ../.batch_scripts
call "%~dp0Pearl_p2cpp.bat" MOZU auto %anz_Modules% %SR_Modules% %CPP_Modules%
call cd ../.batch_scripts
call "%~dp0Pearl_p2cpp.bat" MTERM auto %anz_Modules% %SR_Modules% %CPP_Modules%
call cd ../.batch_scripts
call "%~dp0Pearl_p2cpp.bat" MTERM\RTOS auto %anz_Modules% %SR_Modules% %CPP_Modules%
call cd ..
call cd ../.batch_scripts
call "%~dp0Pearl_p2cpp.bat" PAKZU auto %anz_Modules% %SR_Modules% %CPP_Modules%
call cd ../.batch_scripts
call "%~dp0Pearl_p2cpp.bat" PE auto %anz_Modules% %SR_Modules% %CPP_Modules%
call cd ../.batch_scripts
call "%~dp0Pearl_p2cpp.bat" SRS auto %anz_Modules% %SR_Modules% %CPP_Modules%
call cd ../.batch_scripts
call "%~dp0Pearl_p2cpp.bat" SRTBEG2 auto %anz_Modules% %SR_Modules% %CPP_Modules%
call cd ../.batch_scripts
call "%~dp0Pearl_p2cpp.bat" STDBY auto %anz_Modules% %SR_Modules% %CPP_Modules%
call cd ../.batch_scripts
call "%~dp0Pearl_p2cpp.bat" VDE auto %anz_Modules% %SR_Modules% %CPP_Modules%
call cd ../.batch_scripts
call "%~dp0Pearl_p2cpp.bat" VGL auto %anz_Modules% %SR_Modules% %CPP_Modules%
call cd ../.batch_scripts
:: Get the end time
set StopTIME=%TIME%
set H=%StopTIME:~0,2%
if "%H:~0,1%"==" " set H=%H:~1,1%
if "%H:~0,1%"=="0" set H=%H:~1,1%
set M=%StopTIME:~3,2%
if "%M:~0,1%"=="0" set M=%M:~1,1%
set S=%StopTIME:~6,2%
if "%S:~0,1%"=="0" set S=%S:~1,1%
set U=%StopTIME:~9,2%
if "%U:~0,1%"=="0" set U=%U:~1,1%
)
set /a Stop100S=%H%*360000+%M%*6000+%S%*100+%U%
:: Test midnight rollover. If so, add 1 day=8640000 1/100ths secs
if %Stop100S% LSS %Start100S% set /a Stop100S+=8640000
set /a TookTime=%Stop100S%-%Start100S%
echo ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
echo ----------------------------------------------------------------------------------------------------
::echo um %StartTime% Uhr gestartet
::echo um %StopTime% Uhr beendet
echo Es wurden insgesammt [%anz_Modules%]*.P (PEARL)-Module gefunden
echo aus diesen wurden [%SR_Modules%]-SREC und [%CPP_Modules%]-C++ Dateien in %TookTime:~0,-2%.%TookTime:~-2% seconds gebuildet!
echo ----------------------------------------------------------------------------------------------------
echo ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
完整的 second.bat 腳本完整:
@echo off
echo compile and port moduls in subfolder "%1"
cd .././%1
pwd
echo *.Px ,*.cpp und *.SR-Dateien werden geloescht.
if /i "%2%"=="auto" GOTO nopause_1
pause
rm *.Px
rm *.SR
echo Konvertierungen starten:
:nopause_1
if /i "%2%"=="auto" GOTO no_time_rec
:: Store start time
set StartTIME=%TIME%
set H=%StartTIME:~0,2%
if "%H:~0,1%"==" " set H=%H:~1,1%
if "%H:~0,1%"=="0" set H=%H:~1,1%
set M=%StartTIME:~3,2%
if "%M:~0,1%"=="0" set M=%M:~1,1%
set S=%StartTIME:~6,2%
if "%S:~0,1%"=="0" set S=%S:~1,1%
set U=%StartTIME:~9,2%
if "%U:~0,1%"=="0" set U=%U:~1,1%
)
set /a Start100S=%H%*360000+%M%*6000+%S%*100+%U%
:no_time_rec
setlocal EnableDelayedExpansion
set cppExtension=".cpp"
set PearlExtension=".P"
set SRecordExtension=".SR"
set /a "SRecordSuccess=0"
set /a "CppSuccess=0"
set /a "numberOfModuls=0"
set doCompilePort=true
for /f %%a IN ('dir /b *.P') do (
echo Modul %%a
set doCompilePort=true
if "%%a" == "INCL.P" set doCompilePort=false
if "%%a" == "INCL_FKR.P" set doCompilePort=false
if "%%a" == "INCL_GLO.P" set doCompilePort=false
if "%%a" == "INCL_PE.P" set doCompilePort=false
if "%%a" == "INCL_STB.P" set doCompilePort=false
if "%%a" == "INCL_VDE.P" set doCompilePort=false
echo doCompilePort:!doCompilePort!
if "!doCompilePort!" == "true" (
echo start compiler
set /a numberOfModuls=!numberOfModuls!+1
echo modul number !numberOfModuls!
echo Convert
set filename=%%a
set fileBasename=!filename:~0,-2!
rm !fileBasename!.cpp
echo returnValue rm !errorlevel!
set filenameSR=!fileBasename!.SR
call C:\programme\compiler\rtos-uh\pe\pe.exe C:\programme\compiler\rtos-uh\ppc\PEARL90\vers16_6\P16Q6H.VBI -si=!filename! -co=!filenameSR! -lo=no -e0
IF !errorlevel! NEQ 0 (
REM do something here to address the error
echo returnValue Pearl-Compiler !errorlevel!
) ELSE (
set /a SRecordSuccess=!SRecordSuccess!+1
)
call pqprep !filename!
echo returnValue pqprep !errorlevel!
call p2cpp !filename!x
IF !errorlevel! NEQ 0 (
REM do something here to address the error
echo returnValue Pearl-Compiler !errorlevel!
) ELSE (
set /a CppSuccess=!CppSuccess!+1
)
)
echo ----------------------------------------------------------------------------------------------------
)
echo ----------------------------------------------------------------------------------------------------
echo number of moduls: %numberOfModuls%
echo successfully created S-Records: %SRecordSuccess%
echo successfully created cpp-files: %CppSuccess%
IF %numberOfModuls% == %SRecordSuccess% (
IF %numberOfModuls% == %CppSuccess% (
echo all moduls successful
)
)
::Globale Variablen aus *_ALLES.bat bearbeiten
if "%~3" == "" goto noParams
set /A "PassedVar3=%~3+numberOfModuls"
if "%~4" == "" goto noParams
set /A "PassedVar4=%~4+SRecordSuccess"
if "%~5" == "" goto noParams
set /A "PassedVar5=%~5+CppSuccess"
:noParams
if /i "%2%"=="auto" GOTO no_time_rec2
:: Get the end time
set StopTIME=%TIME%
set H=%StopTIME:~0,2%
if "%H:~0,1%"==" " set H=%H:~1,1%
if "%H:~0,1%"=="0" set H=%H:~1,1%
set M=%StopTIME:~3,2%
if "%M:~0,1%"=="0" set M=%M:~1,1%
set S=%StopTIME:~6,2%
if "%S:~0,1%"=="0" set S=%S:~1,1%
set U=%StopTIME:~9,2%
if "%U:~0,1%"=="0" set U=%U:~1,1%
)
set /a Stop100S=%H%*360000+%M%*6000+%S%*100+%U%
:: Test midnight rollover. If so, add 1 day=8640000 1/100ths secs
if %Stop100S% LSS %Start100S% set /a Stop100S+=8640000
set /a TookTime=%Stop100S%-%Start100S%
echo wurden in %TookTime:~0,-2%.%TookTime:~-2% seconds uebersetzt und in PEARL-SRs compiliert
echo ----------------------------------------------------------------------------------------------------
:no_time_rec2
echo *.Px -Dateien werden geloescht.
echo ----------------------------------------------------------------------------------------------------
if /i "%2%"=="auto" GOTO nopause_2
Pause
:nopause_2
rm *.Px
rm *.phx
rm *.INCx
rm *.incx
pwd
cd ./..
pwd
if "%~3" == "" goto noParams
endlocal & set "%~3=%PassedVar3%" "%~4=%PassedVar4%" "%~5=%PassedVar5%"
:noParams
echo Vorgang beenden
這是重寫的完整的第一個批處理文件:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Get start time region independent in seconds and hundredths of a second
for /F "tokens=2 delims==" %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "LocalTime=%%I"
set /A Start100S=(1%LocalTime:~8,2%-100)*360000 + (1%LocalTime:~10,2%-100)*6000 + (1%LocalTime:~12,2%-100)*100 + (1%LocalTime:~15,2%-100)
rem Modules found
set "anz_Modules=0"
rem Modules build successful
set "SR_Modules=0"
set "CPP_Modules=0"
call "%~dp0Pearl_p2cpp.bat" EXTRA auto anz_Modules SR_Modules CPP_Modules
call "%~dp0Pearl_p2cpp.bat" FKT auto anz_Modules SR_Modules CPP_Modules
call "%~dp0Pearl_p2cpp.bat" FKTREP auto anz_Modules SR_Modules CPP_Modules
call "%~dp0Pearl_p2cpp.bat" FKTZU auto anz_Modules SR_Modules CPP_Modules
call "%~dp0Pearl_p2cpp.bat" KALIB auto anz_Modules SR_Modules CPP_Modules
call "%~dp0Pearl_p2cpp.bat" LASER auto anz_Modules SR_Modules CPP_Modules
call "%~dp0Pearl_p2cpp.bat" MOAB auto anz_Modules SR_Modules CPP_Modules
call "%~dp0Pearl_p2cpp.bat" MOENDE auto anz_Modules SR_Modules CPP_Modules
call "%~dp0Pearl_p2cpp.bat" MOZU auto anz_Modules SR_Modules CPP_Modules
call "%~dp0Pearl_p2cpp.bat" MTERM auto anz_Modules SR_Modules CPP_Modules
call "%~dp0Pearl_p2cpp.bat" MTERM\RTOS auto anz_Modules SR_Modules CPP_Modules
call "%~dp0Pearl_p2cpp.bat" PAKZU auto anz_Modules SR_Modules CPP_Modules
call "%~dp0Pearl_p2cpp.bat" PE auto anz_Modules SR_Modules CPP_Modules
call "%~dp0Pearl_p2cpp.bat" SRS auto anz_Modules SR_Modules CPP_Modules
call "%~dp0Pearl_p2cpp.bat" SRTBEG2 auto anz_Modules SR_Modules CPP_Modules
call "%~dp0Pearl_p2cpp.bat" STDBY auto anz_Modules SR_Modules CPP_Modules
call "%~dp0Pearl_p2cpp.bat" VDE auto anz_Modules SR_Modules CPP_Modules
call "%~dp0Pearl_p2cpp.bat" VGL auto anz_Modules SR_Modules CPP_Modules
rem Get end time region independent in seconds and hundredths of a second
for /F "tokens=2 delims==" %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "LocalTime=%%I"
set /A Stop100S=(1%LocalTime:~8,2%-100)*360000 + (1%LocalTime:~10,2%-100)*6000 + (1%LocalTime:~12,2%-100)*100 + (1%LocalTime:~15,2%-100)
rem Test midnight rollover. If so, add one day=8640000 1/100ths seconds
if %Stop100S% LSS %Start100S% set /A Stop100S+=8640000
set /A TookTime=Stop100S - Start100S
echo ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
echo ----------------------------------------------------------------------------------------------------
echo Es wurden insgesammt [%anz_Modules%]*.P (PEARL)-Module gefunden.
echo Aus diesen wurden [%SR_Modules%]-SREC und [%CPP_Modules%]-C++ Dateien in %TookTime:~0,-2%.%TookTime:~-2% Sekunden erzeugt!
echo ----------------------------------------------------------------------------------------------------
echo ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
endlocal
這個批處理文件首先用前兩個命令行完全定義了執行環境:
命令SETLOCAL
這總是由命令SETLOCAL完成,獨立於在沒有、一個或兩個參數的情況下運行。
命令ENDLOCAL
這也由 Windows 命令處理器cmd.exe
為在批處理文件中執行的每個SETLOCAL隱式完成,在退出批處理文件的處理之前未明確執行ENDLOCAL 。 因此,許多在頂部某處使用SETLOCAL的批處理文件在最后某處不包含ENDLOCAL 。
也可以看看:
因此批處理文件在其自己的本地執行環境中運行,該環境不依賴於批處理文件之外定義的內容,當前目錄除外,因為從該批處理文件傳遞到被調用批處理文件Pearl_p2cpp.bat
的所有目錄路徑都是相對於在批處理文件之外定義的當前目錄。 這可能不是那么好,但我不能評價。
可以使用第三個命令行pushd "%~dp0"
將當前目錄路徑推送到堆棧上,並使批處理文件的目錄成為當前目錄,並作為最后一行popd
從堆棧中彈出目錄路徑的初始當前目錄,並再次將此目錄設置為當前目錄。
接下來的兩個命令行獲取當前本地時間,獨立於百分之一秒的地區/國家,並計算開始時間的值。 有關解釋,請參閱午夜后的時間設置不正確。
在算術表達式中,時間的每個兩位十進制數前面都有字符1
,導致所有數字現在都是三位數字,最小值為100
。 這是因為SET將算術表達式中以0
開頭的數字解釋為八進制數而不是十進制數。 數字8
和9
在八進制數中無效。 因此, 08
和09
將被解釋為無效的八進制數,而不是十進制數8
和9
。 避免將十進制數解釋為八進制數的簡單解決方案是在算術表達式字符串中的每個兩位十進制數之前插入字符1
,並在計算算術表達式時從每個十進制數中減去100
。
使用時間格式hh:mm::ss.xx
獲取開始/結束時間區域/國家/地區的更好代碼是:
rem Get start time region dependent in seconds and hundredths of a second.
set "LocalTime=%TIME%"
set "Hour=%LocalTime:~0,2%"
if "%Hour:~0,1%" == "0" (set "Hour=%Hour:~1%") else if "%Hour:~0,1%" == " " set "Hour=%Hour:~1%"
set "Minute=%LocalTime:~3,2%
if "%Minute:~0,1%" == "0" set "Minute=%Minute:~1%"
set "Second=%LocalTime:~6,2%"
if "%Second:~0,1%" == "0" set "Second=%Second:~1%"
set "HundredthOfSecond=%LocalTime:~9,2%
if "%HundredthOfSecond:~0,1%" == "0" set "HundredthOfSecond=%HundredthOfSecond:~1%"
set /A Start100S=Hour*360000 + Minute*6000 + Second*100 + HundredthOfSecond
rem Or for the end time the lines above with last line modified to:
set /A Stop100S=Hour*360000 + Minute*6000 + Second*100 + HundredthOfSecond
這里通過額外的IF條件避免了八進制數問題,這些條件重新定義了字符串值的第一個字符為0
(或小時值上的空格)的適當環境變量,只有第二個字符。 所以算術表達式中沒有數字有前導0
。
請永遠不要在算術表達式中引用環境變量,即使用%
或!
set /A
之后的字符串。 . 這是不必要的,而且適得其反。 環境變量可以在算術表達式中僅通過它們的名稱來引用,以便更容易使用它們,尤其是在IF條件塊或FOR循環中。 有一些例外情況,例如環境變量名稱包含空格或字符,在算術表達式中被解釋為數學運算符,或者在算術表達式中應僅使用環境變量的字符串值的一部分。 但一般來說,只有變量名可以在算術表達式中使用,才能使用良好的環境變量名。
接下來的命令行定義了三個值為 0 的環境變量。一般不應使用算術表達式來定義具有數字的環境變量。 環境變量始終是 memory 中的字符串,而不是 integer。 因此,與使用set "anz_Modules=0"
"anz_Modules=0" 的簡單字符串定義相比,使用諸如set /A "anz_Modules = 0"
類的算術表達式定義環境變量需要更多的 CPU 指令,盡管沒有用戶注意到差異,因為 CPU 非常如今快。 另請參閱:在命令行上使用 'set var = text' 后,為什么沒有字符串 output 和 'echo %var%'?
下一個命令行塊是對具有完全限定文件名的批處理文件Pearl_p2cpp.bat
的簡單調用。 此批處理文件始終存儲在與第一個批處理文件相同的目錄中,因此使用%~dp0
擴展為第一個批處理文件的完整路徑始終以反斜杠結尾確保(幾乎總是)第二個批處理文件確實調用獨立於哪個目錄是當前目錄。
帶有命令CD的命令行全部被刪除,因為它們不再需要在批處理文件Pearl_p2cpp.bat
中使用PUSHD和POPD 。
注意:像CD一樣在cmd.exe
的內部命令上使用命令CALL是危險的,至少會增加批處理文件的執行時間。 Windows 命令處理器在CALL之后期望以冒號開頭的參數字符串被解釋為當前批處理文件中的 label 應該像子例程一樣調用,即批處理文件中的批處理文件,或者批處理文件的名稱沒有或帶路徑,不帶或帶文件擴展名。 因此, call cd
結果在cmd.exe
中搜索當前目錄,然后在環境變量PATH
的值中的所有目錄中搜索文件名為cd
(不區分大小寫)且文件擴展名列在環境變量PATHEXT
值中的文件以及何時它確實找到了這樣一個文件,這個文件是通過將內部命令CD的 arguments 傳遞給這個可執行文件或腳本來執行的,而不是運行內部命令來更改當前目錄。
接下來確定停止/結束時間,並在批處理文件執行結束時計算最終信息 output 的時間差。
這是完整的第二個批處理文件Pearl_p2cpp.bat
重寫,但未經過全面測試:
@echo off
echo Kompiliere und portiere Module im Unterverzeichnis: "%~1"
pushd "..\%~1" || exit /B
echo "%CD%"
echo *.Px und *.SR Dateien werden entfernt.
if /I not "%~2" == "auto" pause
if exist *.Px del /Q *.Px
if exist *.SR del /Q *.SR
if /I "%~2" == "auto" GOTO no_time_rec
rem Get start time region independent in seconds and hundredths of a second
for /F "tokens=2 delims==" %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "LocalTime=%%I"
set /A Start100S=(1%LocalTime:~8,2%-100)*360000 + (1%LocalTime:~10,2%-100)*6000 + (1%LocalTime:~12,2%-100)*100 + (1%LocalTime:~15,2%-100)
:no_time_rec
setlocal EnableExtensions EnableDelayedExpansion
echo Konvertierungen starten:
set "SRecordSuccess=0"
set "CppSuccess=0"
set "numberOfModules=0"
for /F "eol=| delims=" %%I in ('dir /A-D /B *.P 2^>nul') do (
echo Modul %%I
set "doCompilePort=true"
if /I "%%I" == "INCL.P" set "doCompilePort="
if /I "%%I" == "INCL_FKR.P" set "doCompilePort="
if /I "%%I" == "INCL_GLO.P" set "doCompilePort="
if /I "%%I" == "INCL_PE.P" set "doCompilePort="
if /I "%%I" == "INCL_STB.P" set "doCompilePort="
if /I "%%I" == "INCL_VDE.P" set "doCompilePort="
if defined doCompilePort (
echo doCompilePort:true
echo start compiler
set /A numberOfModules+=1
echo module number !numberOfModules!
echo Convert
if exist "%%~nI.cpp" del /F "%%~nI.cpp"
echo returnValue del !errorlevel!
"C:\programme\compiler\rtos-uh\pe\pe.exe" "C:\programme\compiler\rtos-uh\ppc\PEARL90\vers16_6\P16Q6H.VBI" -si="%%I" -co="%%~nI.SR" -lo=no -e0
if errorlevel 1 (
rem Do something here to address the error.
echo returnValue Pearl Compiler !errorlevel!
) else set /A SRecordSuccess+=1
call pqprep %%I
echo returnValue pqprep !errorlevel!
call p2cpp %%Ix
if errorlevel 1 (
rem Do something here to address the error.
echo returnValue p2cpp !errorlevel!
) else set /A CppSuccess+=1
) else echo doCompilePort:false
echo ----------------------------------------------------------------------------------------------------
)
echo ----------------------------------------------------------------------------------------------------
echo number of modules: %numberOfModules%
echo successfully created S-Records: %SRecordSuccess%
echo successfully created cpp-files: %CppSuccess%
if %numberOfModules% == %SRecordSuccess% if %numberOfModules% == %CppSuccess% echo all modules successful
rem Globale Variablen aus *_ALLES.bat addieren.
if "%~3" == "" goto noParams
if "%~4" == "" goto noParams
if "%~5" == "" goto noParams
set /A numberOfModules+=%~3
set /A SRecordSuccess+=%~4
set /A CppSuccess+=%~5
:noParams
if /I "%~2" == "auto" goto no_time_rec2
rem Get end time region independent in seconds and hundredths of a second
for /F "tokens=2 delims==" %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "LocalTime=%%I"
set /A Stop100S=(1%LocalTime:~8,2%-100)*360000 + (1%LocalTime:~10,2%-100)*6000 + (1%LocalTime:~12,2%-100)*100 + (1%LocalTime:~15,2%-100)
rem Test midnight rollover. If so, add 1 day=8640000 1/100ths seconds
if %Stop100S% LSS %Start100S% set /A Stop100S+=8640000
set /A TookTime=Stop100S - Start100S
echo Die Dateien wurden in %TookTime:~0,-2%.%TookTime:~-2% Sekunden verarbeitet und in PEARL-SRs kompiliert.
echo ----------------------------------------------------------------------------------------------------
:no_time_rec2
echo *.Px Dateien werden entfernt.
echo ----------------------------------------------------------------------------------------------------
if /I not "%~2" == "auto" pause
if exist *.Px del /Q *.Px
if exist *.phx del /Q *.phx
if exist *.INCx del /Q *.INCx
if exist *.incx del /Q *.incx
if not "%~3" == "" (endlocal & set "%~3=%numberOfModules%" & set "%~4=%SRecordSuccess%" & set "%~5=%CppSuccess%") else endlocal
echo Vorgang beenden
popd
該批處理文件首先將當前目錄的完整路徑推送到堆棧上,並根據傳遞的第一個參數字符串使該目錄與當前目錄的相對路徑成為新的當前目錄。 批處理文件期望第一個傳遞的目錄是當前目錄的父目錄的子目錄。
請閱讀有關命名文件、路徑和命名空間的 Microsoft 文檔,了解將.././
替換為..\
的說明。 Windows 上的目錄分隔符是反斜杠\
而不是 Linux/Mac 上的斜杠/
。 Windows 的大多數文件/文件夾參數字符串也可以與/
一起使用,因為 Windows 文件管理在將文件/文件夾名稱字符串傳遞給文件系統之前將所有/
替換為\
。 但我知道在文件/文件夾名稱字符串中使用/
會導致意外行為的幾個用例。 ..\
(父目錄)之后的.\
(當前目錄)總是無用的。 只要有父目錄,父目錄的當前目錄就是已經用..\
引用的父目錄。
文件/文件夾字符串應始終包含在"
中,以確保使用它們的命令即使在包含空格或這些字符之一&()[]{}^=;,'+,`~
也能正常工作。
命令pwd
(打印工作目錄)是 Linux 命令。 Windows 上的一種替代方法是echo "%CD%"
或 not safe echo %CD%
。 如果當前目錄路徑包含一個或多個&
,則后者的作用與僅輸出當前目錄路徑不同。 所以最好用雙引號將當前目錄路徑括起來,參見上面的段落。 沒有"
的安全替代方法是setlocal EnableDelayedExpansion & echo !CD!& endlocal
。但是在這種情況下,在 output 的當前目錄路徑中做了很多工作,沒有雙引號。
命令rm
(刪除)也是一個 Linux 命令。 Windows 命令對於文件是del
(刪除),對於目錄是rd
(刪除目錄)。
改進后的第二個批處理文件仍然包含命令SETLOCAL以啟用延遲擴展。 但這僅適用於for
循環中的某些echo
命令行。 真正需要的命令行不再需要延遲的環境變量擴展。 除了一些echo
命令行之外,所有其他命令行都使用推薦的語法,這使得延遲擴展的使用變得不必要。
我無法測試FOR循環內的任何內容,因此只能希望第二個批處理文件的這一部分按您的預期工作。
在批處理文件頂部設置的當前目錄中傳遞給pqprep
和p2cpp
的兩個文件名(批處理文件,可執行文件?)沒有包含在"
因為它應該這樣做,因為我不知道這兩個腳本或可執行文件支持用雙引號括起來的文件名。兩個重寫的批處理文件現在這樣做了,除了帶有pqprep
和p2cpp
的兩個命令行與兩個原始批處理文件相比,這兩個原始批處理文件對於具有一個或多個的目錄或文件名會失敗多次空格或&()^=;,'+,
在文件/目錄名稱中。好吧,由於啟用了延遲擴展,由FOR循環處理的 *.P 文件名稱中的感嘆號仍然是一個問題。
必須將要由第二個批處理文件修改的環境變量的名稱傳遞給第二個批處理文件,而不是它們的當前值,否則第二個批處理文件將不知道要在第一個批處理文件的環境變量列表中重新定義哪些環境變量批處理文件。
我不明白為什么要刪除*.INCx
和*.incx
文件,因為 Windows 文件系統不區分大小寫。 但是當前目錄可能是網絡驅動器,網絡資源上的文件系統是 Linux 文件系統,區分大小寫。
最重要的是最后一個IF條件命令行:
if not "%~3" == "" (endlocal & set "%~3=%numberOfModules%" & set "%~4=%SRecordSuccess%" & set "%~5=%CppSuccess%") else endlocal
環境變量numberOfModules
、 SRecordSuccess
和CppSuccess
是第二個批處理文件的本地環境變量。 通過環境變量anz_Modules
、 SR_Modules
和CPP_Modules
的值,它們的值在上面的幾行中增加了,它們的名稱被傳遞到第二個批處理文件。
現在需要顯式運行ENDLOCAL以在退出處理第二個批處理文件之前恢復第一個批處理文件的環境變量列表,並在調用批處理文件的環境變量列表中另外重新定義環境變量anz_Modules
、 SR_Modules
和CPP_Modules
。 這是通過在同一命令塊中的同一行上分別使用以(
和結尾)
三倍的命令SET來完成的,其中環境變量名稱作為 arguments 和三個本地環境變量的當前值傳遞給批處理文件。
Windows 命令處理器CMD首先使用IF條件處理整個命令行,如Windows 命令解釋器 (CMD.EXE) 如何解析腳本中詳細描述的那樣? 在命令行處理期間, %~3
被anz_Modules
和%numberOfModules%"
替換為本地環境變量numberOfModules
的當前值。同樣對%~4
、 %SRecordSuccess%
、 %~5
和%CppSuccess%
. 最終執行的IF命令行不再包含參數或環境變量引用。整個命令行僅包含所有引用的字符串。因此,調用批處理文件的三個環境變量重新定義為三個值在IF條件的真或假分支中執行命令ENDLOCAL后不再存在的局部環境變量。
最后一個IF條件也可以寫成:
if not "%~3" == "" (
endlocal
set "%~3=%numberOfModules%"
set "%~4=%SRecordSuccess%"
set "%~5=%CppSuccess%"
) else endlocal
結果將與 Windows 命令處理器解析整個塊並在執行命令IF之前將所有參數和環境變量引用替換為其字符串值相同。
最后,第二個批處理文件恢復了初始當前目錄,這使得第一個批處理文件中的命令CD的使用變得不必要。
要了解使用的命令及其工作原理,請打開命令提示符window,在其中執行以下命令,並仔細閱讀每個命令顯示的所有幫助頁面。
call /?
cmd /?
del /?
dir /?
echo /?
endlocal /?
for /?
goto /?
if /?
pause /?
popd /?
pushd /?
set /?
setlocal /?
wmic /?
wmic os /?
wmic os get /?
有關運算符&
和||
的說明,另請參見使用 Windows 批處理文件的單行多命令 .
閱讀有關使用命令重定向運算符的 Microsoft 文檔,了解2>nul
的說明。 當 Windows 命令解釋器在執行命令FOR執行嵌入式dir
命令行之前使用在后台啟動的單獨命令進程來執行嵌入式 dir 命令行時,重定向運算符>
必須在FOR命令行上使用脫字符^
進行轉義,以將其解釋為文字字符%ComSpec% /c
和'
中的命令行作為附加的 arguments 附加。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.