/ dev / null在shell脚本中的含义是什么?

我已经开始使用本指南学习bash脚本: http : //www.tldp.org/LDP/abs/abs-guide.pdf

但是我遇到了第一个脚本:

cd /var/log cat /dev/null > messages cat /dev/null > wtmp echo "Log files cleaned up." 

第2行和第3行在Ubuntu中做了什么(我理解cat )? 它仅适用于其他Linux发行版吗? 以root身份运行此脚本后,我得到的输出是Log files cleaned up./var/log仍然包含所有文件。

cat将列出cat之后传入标准输出的文件的内容,然后>将其发送到文件messageswtmp ,其中>表示首先删除文件的所有内容,>>表示将ADD添加到当前文件。 在这种情况下,您正在使用>,因此文件最终将为空。

现在对于踢球者来说: /dev/null是一个向’后面的2个文件发送’nothing’的设备。

这样做是有原因的:文件不会从系统中删除。 如果你想要它然后做一个touch messages ,权限可能是错误的,如果只是在某些东西想要写入文件之后,它就会消失并出错。 根据软件的创建方式,它可能会崩溃。

假设命令成功, /var/log/messages/var/log/wtmp仍然存在,但现在是空白的

Shell重定向

>是一个重定向操作符,由shell实现。 它的语法是:

 command > file 

这会将command的标准输出重定向到file

  • file也可以是设备节点 。
  • 如果file不存在,则将其创建为常规文件 。
  • 如果file已作为常规文件存在且非空,则会被覆盖。 这通常是您运行的命令中的情况,您将cat /dev/null的输出重定向到messageswtmp
  • 如果file已作为符号链接存在,则使用链接的目标。
  • 如果file已经作为目录存在,你将收到类似bash: file : Is a directory的错误bash: file : Is a directory

(当然,这些操作可能由于其他原因而失败,例如缺少权限或文件系统错误。)

>>重定向操作符类似,但它附加到非空常规文件的末尾而不是覆盖其内容。 (另一个重定向操作符是< command < file使用file作为command的标准输入 。)

null设备

/dev/null是一个简单的设备(用软件实现,不对应系统上的任何硬件设备)。

  • 从中读取时, /dev/null看起来是空的。
  • 写入/dev/null不会做任何事情:写入此设备的数据只是“消失”。

通常,命令的标准输出通过将其重定向到/dev/null来静音,这可能是null设备在shell脚本中最常用的:

 command > /dev/null 

您使用/dev/null不同。 cat /dev/null输出cat /dev/null的“contents”,也就是说它的输出是空白的。 > messages (或> wtmp )导致此空白输出重定向到>运算符右侧的文件。

由于messageswtmp是常规文件(而不是例如设备节点),因此它们被转换为空白文件(即,清空)。

您可以在>的左侧使用任何不执行任何操作且不产生输出的命令。

清除这些文件的另一种方法是运行:

 echo -n > messages echo -n > wtmp 

-n标志是必需的,或者echo写入换行符 。

(这总是在bash 。我相信每个GNU / Linux发行版和其他类似Unix系统的默认sh支持其内置echo-n标志。但是jlliagre是正确的 , 应该避免echo -n一个真正的可移植shell脚本,因为它不需要工作 。也许这就是你使用的指南教导cat /dev/null方式的原因。)

echo -n方式在效果上是等效的,但可以说是更好的解决方案,因为它更简单。
cat /dev/null > file打开三个“文件”:

  • cat可执行文件(通常是/bin/cat ),一个常规文件。
  • /dev/null设备。
  • file

相比之下, echo -n > file只打开fileecho是内置的shell)。

虽然这应该可以提高性能,但这并不是好处 - 不管是手动运行几个这样的命令,无论如何。 相反,好处是更容易理解发生了什么。

重定向和普通(空白/空)命令。

正如jlliagre所指出的那样 (参见jlliagre的回答 ),只需简单地省略>左边的命令就可以进一步缩短这一点。 虽然你不能省略>>>表达式的右侧,但是空白命令是有效的(这是你在空提示符下按Enter键时运行的命令),而在省略左侧时你只是重定向该命令的输出。

  • 请注意,此输出不包含换行符。 当您在命令提示符下按Enter键时 - 无论您是否键入了任何内容 - shell(以交互方式运行)在运行发出的命令之前打印换行符。 此换行符不是命令输出的一部分。

从空白命令(而不是cat /dev/nullecho -n )重定向看起来像:

 > messages > wtmp 

正如已经回答的那样,这两行正在清除/var/log/messages/var/log/wtmp文件的内容,或者在它们尚不存在的情况下创建它们。

然而,它们基于一个完善的城市传说,赋予/dev/null “超自然”力量。

它实际上没有,所以cat /dev/null是浪费击键,时间和CPU周期,因为它绝对没有输出。 Eliah Kagan的回复表明使用echo -n的更好方法。 这是更好但不可移植到某些shell / OS,它可能会将’ -n ‘字符串放入这些文件中。

您可以通过便携和更简单的方式进一步替换这些命令:

 cd /var/log : > messages : > wtmp echo "Log files cleaned up." 

对于大多数shell(但不是基于csh的shell),你可以更进一步并删除no-op命令’ : ‘:

 cd /var/log > messages > wtmp echo "Log files cleaned up." 

>是输出重定向运算符。 它将命令输出重定向到它后面提到的文件而不是标准输出设备,截断或覆盖文件的内容。

例如ls -l > demo.txt 。 执行此命令后,“demo.txt”将包含输出ls -l命令。

接下来就是这个/dev/null/dev/null是空文件Is是一个不包含任何内容的特殊文件。

所以当你执行命令时

 cat /dev/null > messages cat /dev/null > wtmp 

它通过用EOF(文件结束)字符覆盖来清除“消息”和“wtmp”文件的内容。

所以这里你没有清除/var/log目录,但是你正在清除这两个文件的内容。

/ dev / null就像一个黑洞。 对/ dev / null的写入将被丢弃。 在此脚本中,它们使用/ dev / null清空消息日志文件。

否则他们可以简单地使用。

  > /var/log/messages. 

还有其他方法可以清空文件的内容。

喜欢。

  truncate -s 0 /var/log/messages cp /dev/null /var/log/messages 

但使用“>”或“/ dev / null”是有效的方法。