为什么要把/ dev / null放在任何东西上?
您将执行此操作以截断文件内容,同时保持inode完整。除了将文件大小重置为零以外,所有打开该文件以供读取或写入的程序都不会受到影响。
通常会发现一个伪造的替代方法是删除文件,然后再次创建它:
rm file
touch file
或类似的:
mv file file.old
gzip file.old
touch file
问题是这些方法不会阻止在删除时打开已删除文件的任何进程来保持旧文件的写入。原因是在Unix文件系统下,删除文件时,仅将其名称(路径)与内容(索引节点)断开链接。只要有打开进程以供读取或写入的索引节点,它就可以保持活动状态。
这会导致一些负面影响:文件删除后写入的日志会丢失,因为没有直接/便携式的方法来打开已删除的文件。只要进程正在写入已删除的文件,它的内容仍在使用文件系统上的空间。这意味着,如果由于文件正在填充磁盘而删除/创建文件,则磁盘将保持填充状态。解决后一个问题的一种方法是重新启动记录程序,但是对于关键服务,您可能不希望这样做,并且中间日志肯定会丢失。由于创建的文件可能与原始文件具有不同的权限,所有者和组,因此也会产生副作用。例如,这可能会阻止日志分析器读取新创建的文件,或更糟糕的是,阻止日志记录过程写入其自己的日志。
第一种方法cat /dev/null > file
正确地实现了目标,尽管有一个顽强的城市传奇,但它的cat /dev/null
一部分绝对没有用。它会打开一个伪文件,该伪文件在设计上是空的,无法读取任何内容,最后退出。这样,使用此命令会浪费键击,字节,系统调用和CPU周期,并且可以毫无疑问地通过更快的no-op命令:
甚至在大多数Shell中甚至根本没有任何命令来替换它,而无需任何功能更改。
让我尝试用一个隐喻来解释无用cat /dev/null
。假设您的目标是倒空玻璃杯。
如果您阅读链接文档的末尾,您可能会注意到脚本的增强版本在此行中的注释:
cat / dev / null> wtmp# ':> wtmp'和'> wtmp'具有相同的效果。
他们确实有;太糟糕了cat /dev/null
被保留在代码中。
这意味着以下代码将适用于所有常见的外壳程序(csh
及其sh
系列):
cd /var/log
: > messages
: > wtmp
echo "Log files cleaned up."
这将与使用Bourne语法所有贝壳里,比如ash
,bash
,ksh
,zsh
和喜欢:
cd /var/log
> messages
> wtmp
echo "Log files cleaned up."
但是请注意,在古老的POSIX Bourne之前的shell中,任何这些命令(包括cat /dev/null
之后仍由仍在运行的shell脚本附加到文件中)都不会截断文件。不是零字节文件,而是一个大小不变的稀疏文件。如果该文件是由某个进程在写入之前寻求其认为是当前位置的位置写入的,则也会发生同样的情况。
还请注意,通常建议截断文件的某些替代解决方案确实存在缺陷。
以下两个只是不起作用。结果文件不为空,但包含一个空行。这样会破坏wtmp
存储固定宽度记录的日志文件。
echo > file
echo "" > file
下一个基于BSD sh
选项的选项是不可移植的,POSIX没有指定任何允许的回显选项,因此您可能最终得到一个包含带有“ -n
” 行的文件:
echo -n > file
通过使用System V sh
转义序列不能移植该代码。某些shell将创建一个文件,其中包含带有“ \c
” 的行:
echo "\c" > file
那个人使用了设计用来完成这项工作的命令。使用的问题truncate
不是可移植的,因为Unix / Linux系统中可能缺少POSIX未指定的命令。
truncate -s 0
最后,这里有一些可移植的替代方法,它们可以正常完成工作: