/dev/null 在 shell 脚本中是什么意思?

ris*_*iag 44 filesystem command-line bash scripts

我已经开始使用本指南学习 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."
Run Code Online (Sandbox Code Playgroud)

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

Eli*_*gan 53

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

外壳重定向

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

command > file
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

null设备

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

  • /dev/null 当你阅读它时看起来是空的。
  • 写入/dev/null没有任何作用:写入此设备的数据只是“消失”。

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

command > /dev/null
Run Code Online (Sandbox Code Playgroud)

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

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

您可以使用任何不执行任何操作且不产生任何输出的命令,位于>.

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

echo -n > messages
echo -n > wtmp
Run Code Online (Sandbox Code Playgroud)

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

(这始终工作在bash,而且我相信默认sh每个GNU / Linux发行版和其它类Unix系统普遍使用的今天支持的-n标志在其echo内置的,但jlliagre是正确的是echo -n应该避免为一个真正的便携式shell脚本,因为它是不需要工作。也许这就是为什么你使用的指南会cat /dev/null方式。)

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

  • cat可执行文件(一般/bin/cat),一个普通的文件。
  • /dev/null设备。
  • file

相比之下,opens only (是一个内置的shell)。echo -n > filefileecho

虽然这应该会提高性能,但这并不是好处——无论如何,当只是手动运行几个这些命令时。相反,好处是更容易理解正在发生的事情。

重定向和微不足道的(空白/空)命令。

正如jlliagre 所指出的(另见jlliagre 的回答),可以通过简单地完全省略左侧的命令来进一步缩短>。虽然你不能省略 a>>>表达式的右侧,但空白命令是有效的(当你按下Enter一个空提示时,它就是你正在运行的命令),而省略左侧你只是重定向了它的输出命令。

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

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

> messages
> wtmp
Run Code Online (Sandbox Code Playgroud)

  • 你可以更进一步,用 `:` 或什么都不替换无用的 `echo -n`,因为该命令无论如何都不做任何事情。 (8认同)

Rin*_*ind 43

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

现在是踢球者:/dev/null是一种向 > 后面的 2 个文件发送“无”的设备。

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

  • `cat "echo" &gt; messages` 会给你一个空白文件,还有消息 `cat: echo: No such file or directory`。`cat` 将在 STDIN 上传递任何内容,但它不会像 `echo` 那样打印参数。我个人会推荐 `echo "" &gt; file`,因为它的意图是明确和明确的。 (8认同)
  • @Mr.Llama 我会为此推荐 [`truncate`](http://linux.die.net/man/1/truncate) - 当有明确为此任务设计的命令时,为什么要使用 echo 和管道. (3认同)
  • `echo "" &gt; wtmp` 将创建一个不可用的 `wtmp` 文件(非空),然后阻止使用它的程序工作。 (2认同)

jll*_*gre 13

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

然而,它们基于一个成熟的都市传说,赋予了/dev/null“超自然”的力量。

它实际上没有,因此cat /dev/null浪费了击键、时间和 CPU 周期,因为它绝对没有输出。Eliah Kagan 的回复建议使用更好的方法echo -n。这更好,但不能移植到某些 shell/操作系统,它可能会将 ' -n' 字符串放入这些文件中。

您可以更进一步,用可移植和更简单的命令替换这些命令:

cd /var/log
: > messages
: > wtmp
echo "Log files cleaned up."
Run Code Online (Sandbox Code Playgroud)

对于大多数外壳(但不是csh基于外壳的),您可以更进一步并删除无操作命令 ' :' :

cd /var/log
> messages
> wtmp
echo "Log files cleaned up."
Run Code Online (Sandbox Code Playgroud)


g_p*_*g_p 6

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

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

现在下一件事情是这是什么/dev/null/dev/null是空文件 是一个特殊的文件,它什么都不包含。

所以当你执行命令时

cat /dev/null > messages
cat /dev/null > wtmp
Run Code Online (Sandbox Code Playgroud)

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

所以在这里您不是在清除/var/log目录,而是在清除这两个文件的内容。