Windows批处理文件的隐藏功能

232

Windows批处理文件中一些不太为人所知,但重要且有用的特性是什么?

指南:

  • 每个答案只涉及一个特性
  • 提供特性的简短描述示例,而不是只提供文档链接
  • 答案限于本地功能,即不需要其他软件,如Windows资源工具包

澄清:我们这里指的是由cmd.exe处理的脚本,这是WinNT变体的默认值。

(另请参见:Windows批处理文件:.bat与.cmd有何区别?

91个回答

42

等待N秒钟的巧妙技巧(不是cmd.exe的一部分,但它不需要额外的软件,因为它随Windows一起提供),请参见ping命令。由于第一个ping没有延迟,所以您需要N+1个ping。

    echo %time%
    call :waitfor 5
    echo %time%
    goto :eof
:waitfor
    setlocal
    set /a "t = %1 + 1"
    >nul ping 127.0.0.1 -n %t%
    endlocal
    goto :eof

2
更好的方法是将其放入一个文件中,例如sleep.bat,以免重复编写。 - erjiang
1
...并将sleep.bat放置在PATH环境变量中的某个目录中。 - Scoregraphic
我反对把这个放在外面,这会使它不够便携,在Windows系统上也是如此。 - sorin

37

避免“管道”问题:

echo ^| ^< ^> ^& ^\ ^^

3
我打赌DOS转义字符并不是众所周知的。不错的选择。 - Joshua
12
啊,这就解释了为什么它也是行继续运算符——它可以转义换行符,就像bash中的\一样。 - leander
@leander:是的,但它只能转义LF(而不能转义CR),因为所有CR都会在之前被移除。 - jeb
所以这就是为什么在Windows上使用git来与先前的提交(HEAD^)进行差异比较是有问题的原因。 - Daniel Trebbien

31

能够运行命令并处理输出(如bash中的反引号'$()' )。

for /f %i in ('dir /on /b *.jpg') do echo --^> %i
如果文件名中有空格,请使用以下命令:

</p>

for /f "tokens=*" %i in ('dir /on /b *.jpg') do echo --^> %i

2
不适用于文件名中带有空格的文件... 这个可以工作:for /f "tokens=*" %i in ('dir /on /b *.jpg') do echo --^> %i - doekman
不错的发现。就我个人而言,我认为文件名中的空格是来自地狱第九层深处的邪恶丑陋之物。但我们应该考虑到它们的存在,我想。 - paxdiablo
这是我见过的最疯狂的语法。如果你制作了这个backtick.bat并传入字符串,它能工作吗? - idbrii

30

创建一个空文件:

> copy nul filename.ext

6
@devio: echo命令会输出一个空行,所以文件不会是空的! - Paulius
4
我使用type nul > 文件名.扩展名来实现这个目的。 - Benoit
很好,我一直在想是否有一个触摸屏的等效物。 - jdelator
我一直使用 ren > blah.txt - Synetech

28

为隐藏命令的所有输出,请重定向到>nul 2>&1。

例如,有些命令行程序即使你将输出重定向到>nul,也会显示输出。但是,如果你像下面这行代码一样重定向输出,所有输出都将被抑制。

PSKILL NOTEPAD >nul 2>&1

编辑:请参见忽略命令的输出以了解其工作原理。


1
你知道这是如何工作的吗?2>&1 代表什么意思? - Scott Langham
12
">nul"将标准输出重定向到nul(空设备)。"2>&1"将标准错误重定向到标准输出所指向的位置。 - aphoria
具体来说,我认为2>&1是一个“文件句柄克隆”,将STDERR设置为STDOUT的克隆。在>NUL之后放置它很重要,因为您希望在重定向之后而不是之前克隆STDOUT。(如果我理解有误,请纠正我。) - leander
1
如果你想知道PSKILL是从哪里来的,可以查看http://www.sysinternals.com/。如果你使用的是专业版,你应该有一个本地的TSKILL命令,它与PSKILL基本相同。 - Coding With Style
1
如果您没有pskill或tskill,大多数我使用过的Windows系统都带有taskkill - idbrii
如果你只想隐藏错误输出,你可以使用 PSKILL NOTEPAD 2>nul。所以,2>&1 的意思是将 2>(重定向错误)&1(到标准输入作为输入--这就是 & 的作用)。我经常忘记字符的顺序,所以这个解释应该有助于记住它们为什么按照那个顺序。 - idbrii

25

bash(及其他shell)的等价命令

echo -n Hello # or
echo Hello\\c

以下是可实现此功能的cmd命令行代码,它将输出不带换行符的"Hello":

<nul set /p any-variable-name=Hello

set /p 是一种提示用户输入的方式。它输出给定的字符串,然后等待用户响应(在同一行上,即没有CRLF)。

<nul 只需将空响应传输到 set /p 命令,因此净结果是发出的提示字符串。(由于空响应,使用的变量保持不变。)

问题是:无法输出前导等号;在Vista上会删除前导空格字符,但在XP上不会。


25
PAUSE

停止执行并显示以下提示:

按任意键继续. . .

如果您想通过在Windows资源管理器中双击批处理文件来运行它,并且希望实际上看到输出而不仅仅是命令窗口的闪烁,则此方法很有用。


15
“暂停”命令的一个好处是,如果没有终端接收“任意键”(例如,如果您的批处理文件是从系统服务运行的),它会检测到并继续执行。请注意,这里的“任意键”指的是用户按下计算机键盘上除了Ctrl、Alt或Shift以外的任何键。 - leander
4
给查理·萨默维尔加一分,这是每个游戏程序员在90年代初都会使用的众所周知的东西“go.bat”。 - LiraNuna
6
不要污染所有批处理文件(使它们对CLI专家来说很烦人),你可以使用“开始/运行”,然后输入“cmd /k”和批处理文件名来代替。或者将HKCR \ batfile \ shell \ open \ command默认字符串更改为“cmd /k”%1“%* ”。或者制作另一个批处理文件,只需运行'@cmd / k $ *',将其放在桌面上,并将其他批处理文件拖到该文件上。有许多替代PAUSE的方法。请考虑使用它们。 - system PAUSE
1
@gnud:你仍然可以将输出管道传递到脚本中:“echo.|batch-with-pause.bat” 将产生与按下“任意键”的相同效果... - Kurt Pfeifle
@Lance: 我不知道有这样的事。 - raven
显示剩余3条评论

18

设置环境变量时进行搜索和替换:

> @set fname=%date:/=%

该功能用于将日期中的“/”移除,以便在时间戳文件名中使用。

还可用于子字符串...

> @set dayofweek=%fname:~0,3%

17

整数算术:

> SET /A result=10/3 + 1
4

SET 有能力进行计算有多久了?Windows XP? - chakrit
1
如果您想知道值的大小,我认为这是32位。因此,正负20亿。 - Chris Noe
1
我认为问题是,SET能够计算多长时间了?自从Windows XP以来吗? - Michael Myers
3
我认为CMD.EXE的SET命令从NT 3.1版本开始就能够进行计算。只是花了很长时间才有人注意到CMD.EXE与COMMAND.COM并不完全相同... - RBerteig

16

命令分隔符:

cls & dir
copy a b && echo Success
copy a b || echo Failure

第二行中,&& 后面的命令只有在第一个命令成功运行后才会执行。

第三行中,|| 后面的命令只有在第一个命令运行失败后才会执行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接