Windows批处理文件有哪些不太为人所知,但很重要和有用的特性?
指南:
每个答案一个特征 给出特性的简短描述和示例,而不仅仅是文档链接 将答案限制在本地功能,即不需要额外的软件,如Windows资源包
澄清:这里我们指的是由cmd.exe处理的脚本,这是WinNT变体的默认值。
(请参见:Windows批处理文件:.bat vs .cmd?)
Windows批处理文件有哪些不太为人所知,但很重要和有用的特性?
指南:
每个答案一个特征 给出特性的简短描述和示例,而不仅仅是文档链接 将答案限制在本地功能,即不需要额外的软件,如Windows资源包
澄清:这里我们指的是由cmd.exe处理的脚本,这是WinNT变体的默认值。
(请参见:Windows批处理文件:.bat vs .cmd?)
当前回答
ENDLOCAL使用的行仍然解析局部变量。这就允许了以下技巧:
ENDLOCAL & SET MYGLOBAL=%SOMELOCAL% & SET MYOTHERGLOBAL=%SOMEOTHERLOCAL%
这是一种将结果传输到调用上下文的有用方法。具体来说,一旦ENDLOCAL完成,% somlocal%就超出了作用域,但那时% somlocal%已经展开,因此MYGLOBAL在调用上下文中使用局部变量赋值。
出于同样的原因,如果你决定这样做:
ENDLOCAL & SET MYLOCAL=%MYLOCAL%
您将发现新的MYLOCAL变量现在实际上是一个常规环境变量,而不是您希望它成为的局部变量。
其他回答
CHOICE命令提示用户在多个选项中选择一个(通过单个按键)
@echo off
echo Please choose one of the following options
echo 1. Apple
echo 2. Orange
echo 3. Pizza
echo a, b, c. Something else
choice /c:123abc /m "Answer?"
set ChoiceLevel=%ErrorLevel%
echo Choice was: %ChoiceLevel%
%ChoiceLevel%将是选中的第n个选项(在上面的例子中,b=5)。
更多详情请访问SS64.com上的CHOICE参考页面。
使用&::的内联注释。
:: This is my batch file which does stuff.
copy thisstuff thatstuff &:: We need to make a backup in case we screw up!
:: ... do lots of other stuff
这是如何工作的呢?这是一个丑陋的黑客。&是命令分隔符,大致近似于;UNIX shell。::是另一个丑陋的黑客,有点像REM语句。最终结果是执行命令,然后执行一个什么都不做的命令,从而近似于注释。
这并不是在所有情况下都有效,但它通常足够有用。
搜索路径上的可执行文件(或其他类似路径的字符串,如果需要):
c:\> for %i in (cmd.exe) do @echo. %~$PATH:i
C:\WINDOWS\system32\cmd.exe
c:\> for %i in (python.exe) do @echo. %~$PATH:i
C:\Python25\python.exe
c:\>
您可以在批处理文件运行时修改它。例如,如果您希望在批处理文件退出之前看到结果,您可以在文件运行时在文件的末尾添加一个被遗忘的暂停。
请参见在批处理文件运行时更改批处理文件
我个人认为这更像是一个陷阱,而不是一个功能。
抽取随机的文本行
@echo off
:: Get time (alas, it's only HH:MM xM
for /f %%a in ('time /t') do set zD1=%%a
:: Get last digit of MM
set zD2=%zD1:~4,1%
:: Seed the randomizer, if needed
if not defined zNUM1 set /a zNUM1=%zD2%
:: Get a kinda random number
set /a zNUM1=zNUM1 * 214013 + 2531011
set /a zNUM2=zNUM1 ^>^> 16 ^& 0x7fff
:: Pull off the first digit
:: (Last digit would be better, but it's late, and I'm tired)
set zIDX=%zNUM2:~0,1%
:: Map it down to 0-3
set /a zIDX=zIDX/3
:: Finally, we can set do some proper initialization
set /a zIIDX=0
set zLO=
set zLL=""
:: Step through each line in the file, looking for line zIDX
for /f "delims=@" %%a in (c:\lines.txt) do call :zoo %zIDX% %%a
:: If line zIDX wasn't found, we'll settle for zee LastLine
if "%zLO%"=="" set zLO=%zLL%
goto awdun
:: See if the current line is line zIDX
:zoo
:: Save string of all parms
set zALL=%*
:: Strip off the first parm (sure hope lines aren't longer than 254 chars)
set zWORDS=%zALL:~2,255%
:: Make this line zee LastLine
set zLL=%zWORDS%
:: If this is the line we're looking for, make it zee LineOut
if {%1}=={%zIIDX%} set zLO=%zWORDS%
:: Keep track of line numbers
set /a zIIDX=%zIIDX% + 1
goto :eof
:awdun
echo ==%zLO%==
:: Be socially responsible
set zALL=
set zD1=
set zD2=
set zIDX=
set zIIDX=
set zLL=
set zLO=
:: But don't mess with seed
::set zNUM1=
set zNUM2=
set zWORDS=