Batch file 理解开始,2>;批处理文件中的nul、cmd和其他符号
从这个话题开始,我试图从一个建议的答案中理解“幕后”发生了什么。我不明白2>nul或1>nul应该做什么。我试图破译start/b行中的符号在做什么,但我在这里真的一窍不通。如果你不介意的话,我需要一个循序渐进的方法 这部分代码中发生了什么Batch file 理解开始,2>;批处理文件中的nul、cmd和其他符号,batch-file,Batch File,从这个话题开始,我试图从一个建议的答案中理解“幕后”发生了什么。我不明白2>nul或1>nul应该做什么。我试图破译start/b行中的符号在做什么,但我在这里真的一窍不通。如果你不介意的话,我需要一个循序渐进的方法 这部分代码中发生了什么 2>nul del %lock%!nextProc! %= Redirect the lock handle to the lock file. The CMD process will =% %= maintain a
2>nul del %lock%!nextProc!
%= Redirect the lock handle to the lock file. The CMD process will =%
%= maintain an exclusive lock on the lock file until the process ends. =%
start /b "" cmd /c %lockHandle%^>"%lock%!nextProc!" 2^>^&1 !cpu%%N! !cmd!
)
set "launch="
这是:
) 9>>"%lock%%%N"
) 2>nul
if %endCount% lss %startCount% (
1>nul 2>nul ping /n 2 ::1
goto :wait
)
2>nul del %lock%*
建议代码的完整副本:
@echo off
setlocal enableDelayedExpansion
:: Display the output of each process if the /O option is used
:: else ignore the output of each process
if /i "%~1" equ "/O" (
set "lockHandle=1"
set "showOutput=1"
) else (
set "lockHandle=1^>nul 9"
set "showOutput="
)
:: Define the maximum number of parallel processes to run.
:: Each process number can optionally be assigned to a particular server
:: and/or cpu via psexec specs (untested).
set "maxProc=8"
:: Optional - Define CPU targets in terms of PSEXEC specs
:: (everything but the command)
::
:: If a cpu is not defined for a proc, then it will be run on the local machine.
:: I haven't tested this feature, but it seems like it should work.
::
:: set cpu1=psexec \\server1 ...
:: set cpu2=psexec \\server1 ...
:: set cpu3=psexec \\server2 ...
:: etc.
:: For this demo force all cpu specs to undefined (local machine)
for /l %%N in (1 1 %maxProc%) do set "cpu%%N="
:: Get a unique base lock name for this particular instantiation.
:: Incorporate a timestamp from WMIC if possible, but don't fail if
:: WMIC not available. Also incorporate a random number.
set "lock="
for /f "skip=1 delims=-+ " %%T in ('2^>nul wmic os get localdatetime') do (
set "lock=%%T"
goto :break
)
:break
set "lock=%temp%\lock%lock%_%random%_"
:: Initialize the counters
set /a "startCount=0, endCount=0"
:: Clear any existing end flags
for /l %%N in (1 1 %maxProc%) do set "endProc%%N="
:: Launch the commands in a loop
set launch=1
echo mem=1m 2m 3m 4m 6m 8m 12m 16m 24m 32m 48m 64m 96m 128m 192m 256m 384m 512m 768m 1024m
echo o=2 3 4 5 6 7 8 10 12 14 16 20 24 28 32
echo s=off 1m 2m 4m 8m 16m 32m 64m 128m 256m 512m 1g 2g 4g 8g 16g 32g 64g on
echo x=1 3 5 7 9
for %%x IN (9) DO for %%d IN (1024m 768m 512m 384m 256m 192m 128m 96m 64m 48m 32m 24m 16m 12m 8m 6m 4m 3m 2m 1m) DO (
set "cmd=7z.exe a teste.resultado\%%xx.ppmd.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -m0=PPMd:mem=%%d:o=%%w -ms=%%s"
if !startCount! lss %maxProc% (
set /a "startCount+=1, nextProc=startCount"
) else (
call :wait
)
set cmd!nextProc!=!cmd!
if defined showOutput echo -------------------------------------------------------------------------------
echo !time! - proc!nextProc!: starting !cmd!
2>nul del %lock%!nextProc!
%= Redirect the lock handle to the lock file. The CMD process will =%
%= maintain an exclusive lock on the lock file until the process ends. =%
start /b "" cmd /c %lockHandle%^>"%lock%!nextProc!" 2^>^&1 !cpu%%N! !cmd!
)
set "launch="
:wait
:: Wait for procs to finish in a loop
:: If still launching then return as soon as a proc ends
:: else wait for all procs to finish
:: redirect stderr to null to suppress any error message if redirection
:: within the loop fails.
for /l %%N in (1 1 %startCount%) do (
%= Redirect an unused file handle to the lock file. If the process is =%
%= still running then redirection will fail and the IF body will not run =%
if not defined endProc%%N if exist "%lock%%%N" (
%= Made it inside the IF body so the process must have finished =%
if defined showOutput echo ===============================================================================
echo !time! - proc%%N: finished !cmd%%N!
if defined showOutput type "%lock%%%N"
if defined launch (
set nextProc=%%N
exit /b
)
set /a "endCount+=1, endProc%%N=1"
) 9>>"%lock%%%N"
) 2>nul
if %endCount% lss %startCount% (
1>nul 2>nul ping /n 2 ::1
goto :wait
)
2>nul del %lock%*
if defined showOutput echo ===============================================================================
echo Thats all folks!
重定向符号前的数字是要重定向的流编号。
当不存在数字时,默认流为1,因此
1>…
和>…
是等效的
流1是标准输入/输出流,2是标准错误流
一个命令可以输出到多个流,并且允许将每个流重定向到不同的目标
所以
2>nul
和1>nul
简单地说,错误输出和正常输出将重定向到nul。因此不会输出任何内容。1>nul和2>nul使其生效,因此不会显示任何输出。start中的^>,因此将>传递给start命令,而不是解释。cmd/c启动一个新的shell,在/c之后执行代码,然后退出。我的解释:
1. 2>nul del %lock%!nextProc!
2. %= Redirect the lock handle to the lock file. The CMD process will =%
3. %= maintain an exclusive lock on the lock file until the process ends. =%
4. start /b "" cmd /c %lockHandle%^>"%lock%!nextProc!" 2^>^&1 !cpu%%N! !cmd!
5. )
6. set "launch="
第1行:删除文件,不显示错误。与“del/Q”相同。感叹号
符号需要启用delayedexpansion才能计算为任何值。我会的
将其写成:del/Q“%lock%”!nextProc
第二行:一种非常奇怪的评论风格。每行开头都应该改为“:”
第3行:与第2行相同
第4行:看不到脚本的其余部分就很难说。%%N告诉我该部分
在循环块的内部。^字符是必需的,以便启动命令
将特殊字符识别为cmd命令字符串的一部分。我不认为启动命令是必要的
给你,伊姆霍。我打赌“start/B/wait”等同于“start/B”和“cmd/c”。
我会亲自重写这个脚本,让它更容易理解
另外,请参见dostips.com
另外:1>NUL2>NULPING/N2::1与“ping-N2-W1000 127.1>nul”相当,但更难理解
另外:%~1表示获取第一个参数%1和修剪引号(如果有)
我可以继续讲下去,但你应该自己研究一下。::1在我看来像是一条评论