抑制命令行输出

时间:2009-08-11 20:24:41

标签: batch-file

我有一个像这样的简单批处理文件:

echo off

taskkill /im "test.exe" /f > nul

pause

如果“test.exe”没有运行,我会收到以下消息:

ERROR: The process "test.exe" not found.

为什么显示此错误消息,即使我已将输出重定向到NUL?

如何抑制输出?

4 个答案:

答案 0 :(得分:189)

因为错误消息通常会转到stderr而不是stdout

将调用更改为:

taskkill /im "test.exe" /f >nul 2>&1

一切都会好起来。

这是有效的,因为stdout是文件描述符1,stderr按照惯例是文件描述符2。 (顺便提一下,0是stdin。)2>&1从新值1复制输出文件描述符2,它刚被重定向到空设备。

这个语法(松散地)从许多Unix shell中借用,但是你必须要小心,因为shell语法和CMD.EXE之间存在细微差别。

更新:我知道OP了解我在这里写的名为NUL的“文件”的特殊性,但是评论者没有这样做,所以让我离题了关于这方面的更多细节。

一直回到最早的MSDOS版本,某些文件名被文件系统内核抢占并用于引用设备。最早的名单包括NULPRNCONAUXCOM1COM4NUL是空设备。它总是可以打开读取或写入,任何数量都可以写在上面,读取总是成功但不返回数据。其他包括并行打印机端口,控制台和最多四个串行端口。从MSDOS 5开始,还有几个保留名称,但基本惯例已经很成熟。

创建Windows时,它在MSDOS内核之上作为一个相当薄的应用程序切换层开始生效,因此具有相同的文件名限制。当Windows NT本身被创建为真正的操作系统时,NULCOM1这样的名称被广泛认为可以用来消除它们。然而,新设备总是会获得名称以阻止这些名称的实际文件的未来用户的想法显然是不合理的。

Windows NT以及随后的所有版本(2K,XP,7和现在8)都遵循内核代码中更精细的NT Namespace以及精心构建的高度非便携式用户空间代码。在该名称空间中,通过\Device文件夹可以看到设备驱动程序。为了支持所需的向后兼容性,有一种使用\DosDevices文件夹的特殊机制,该文件夹在任何文件系统文件夹中实现保留文件名列表。用户代码可以使用通常的Win32 API下面的API层来浏览此内部名称空间;一个探索内核命名空间的好工具是来自Microsoft的SysInternals组的WinObj

有关Windows中文件(和设备)合法名称的规则的完整说明,this page at MSDN将提供丰富的信息和令人生畏的内容。规则是 lot 比它们应该更复杂,并且实际上不可能回答一些简单的问题,例如“最长的法律完全合格路径名称有多长?”。

答案 1 :(得分:6)

请改用此脚本:

@taskkill/f /im test.exe >nul 2>&1
@pause

2>&1部分实际上做的是,它将stderr输出重定向到stdout。我将在下面更好地解释:

@taskkill / f / im test.exe> nul 2>& 1

杀死任务“test.exe”。将stderr重定向到stdout。然后,将stdout重定向到nul

@pause

显示暂停消息Press any key to continue . . .,直到有人按下某个键。

注意:@符号隐藏了每个命令的提示。这种方式最多可以保存8个字节。

您脚本的最短版本可能是:
@taskkill/f /im test.exe >nul 2>&1&pause
&字符第一次用于重定向,第二次用于分隔命令 一行中不需要两次@个字符。这个代码只有40个字节,尽管你发布的是49个字节!我实际上节省了9个字节。如需更清晰的代码,请查看上面的内容。

答案 2 :(得分:1)

mysqldump不适用于:> nul 2>& 1
而是使用: 2> NUL
这会抑制stderr消息:“警告:在命令行界面上使用密码可能不安全”

答案 3 :(得分:0)

您也可以这样做:

tasklist | find /I "test.exe" > nul && taskkill /f /im test.exe > nul