我已经开始使用本指南学习 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
仍然包含所有文件。
答案1
假设命令成功执行,/var/log/messages
并且/var/log/wtmp
仍然存在,但现在空白的。
Shell 重定向
>
是重定向操作符,由 shell 实现。其语法为:
command > file
此重定向command
的标准输出到file
。
file
也可能是设备节点。- 如果
file
不存在,它被创建为常规文件。 - 如果
file
已作为常规文件存在且非空,则将被覆盖。这通常是您运行的命令中的情况,您将 的输出重定向到cat /dev/null
和messages
。wtmp
- 如果
file
已经存在符号链接,将使用链接的目标。 - 如果
file
已经作为目录存在,您将收到类似这样的错误。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
输出的“内容” /dev/null
,也就是说它的输出是空白的。> messages
(或> wtmp
)导致这个空白输出重定向到运算符右侧的文件>
。
由于messages
和wtmp
是常规文件(而不是例如设备节点),因此它们会变成空白文件(即清空)。
您可以在 的左侧使用任何不执行任何操作并且不产生任何输出的命令>
。
清除这些文件的另一种方法是运行:
echo -n > messages
echo -n > wtmp
该-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
相比之下,仅打开echo -n > file
file
(echo
是 shell 的内置命令)。
虽然这应该可以提高性能,但这并不是好处——至少在手动运行几个命令时不会。相反,好处是更容易理解发生了什么。
重定向和简单(空白/空)命令。
作为jlliagre 指出(也可以看看jlliagre 的回答),可以通过简单地省略左侧的命令来进一步缩短。虽然您不能省略或表达式>
的右侧,但空白命令是有效的(它是您在空提示符上按下时运行的命令),而省略左侧只是重定向该命令的输出。>
>>
Enter
- 请注意,此输出不是包含换行符。当您Enter在命令提示符上按下 时(无论您是否输入了任何内容),shell(以交互方式运行)会在运行发出的命令之前打印一个换行符。此换行符不是命令输出的一部分。
从空白命令(而不是 fromcat /dev/null
或echo -n
)重定向如下:
> messages
> wtmp
答案2
cat
将列出文件的内容,然后将其发送到cat
标准输出,其中> 表示首先删除文件的所有内容,>> 表示添加到当前文件。在本例中,您使用的是 >,因此文件最终将为空。>
messages
wtmp
现在关键的是:/dev/null
是一个向 > 后面的 2 个文件发送“无”内容的设备。
这样做是有原因的:文件不会从系统中删除。如果您rm
这样做然后执行touch messages
权限可能是错误的,并且如果在之后有rm
东西想要写入文件,它将消失并出错。根据软件的创建方式,它可能会崩溃。
答案3
/var/log/messages
正如已经回答的那样,这两行正在清除和文件的内容/var/log/wtmp
,或者在它们不存在的不太可能的情况下创建它们。
然而,它们是基于一个广为人知的赋予/dev/null
“超自然”力量的都市传说。
它实际上没有,所以cat /dev/null
它浪费了按键、时间和 CPU 周期,因为它什么都没有输出。Eliah Kagan 的回复建议使用更好的方法,即echo -n
改为使用。这种方法更好,但无法移植到某些 shell/OS 中,因为在这些 shell/OS 中,它可能会将“ -n
”字符串放入这些文件中。
您可以进一步用可移植的、更简单的命令替换这些命令:
cd /var/log
: > messages
: > wtmp
echo "Log files cleaned up."
对于大多数 shell (但不是csh
基于 shell 的),你甚至可以更进一步删除无操作命令 ' :
' :
cd /var/log
> messages
> wtmp
echo "Log files cleaned up."
答案4
/dev/null 就像一个黑洞。对 /dev/null 的写入将被丢弃。在此脚本中,他们使用 /dev/null 清空消息日志文件。
否则他们只需使用即可。
> /var/log/messages.
还有其他方法可以清空文件的内容。
喜欢。
truncate -s 0 /var/log/messages
cp /dev/null /var/log/messages
但使用“>”或“/dev/null”是有效的方法。