我试图在linux中清空文件,这是一个日志文件,所以它是连续写入。 现在我用了:
echo -n > filename
要么
cat /dev/null > filename
但是所有这些都会产生一个带有换行符的空文件(或者我可以看到的奇怪的字符),在vi
可以看到^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^我必须用vi
和dd
手工删除第一行然后保存。
如果我不使用vi
adn dd
我不能用grep
来操作文件,但是我需要一个自动程序,我可以在shell脚本中写入。
想法?
这应该足以清空一个文件:
> file
然而,你说你尝试的其他方法也应该工作。 如果你看到奇怪的字符,那么他们正在被其他东西写入文件 – 很可能是任何进程记录在那里。
发生什么很简单:你正在清空文件。
为什么它充满了^@
那么,你问? 那么,在一个非常真实的意义上呢,事实并非如此。 它不包含那些怪异的字符。 它有一个“洞”。
正在写入该文件的程序正在编写一个使用O_WRONLY
(或者O_RDWR
)打开的文件,而不是 O_APPEND
。 当你用cp /dev/null filename
或: > filename
或类似的命令清空文件的时候,这个程序已经写入了65536字节的文件。
现在程序去write
另一块数据(比如4096或8192字节)。 数据将写在哪里? 答案是:“在底层文件描述符的当前查找偏移处”。 如果程序使用了O_APPEND
,那么在执行write
之前,会执行一个“查找当前文件结束,即当前文件长度”的lseek
调用。 当截断文件“当前文件结束”将变为零(该文件变空),所以搜索会将write
偏移量移动到位置0,写入将会去那里。 但是程序没有使用O_APPEND
,所以没有预write
“重定位”操作,数据字节被写入当前的偏移量(这又是我们声称的65536以上)。
您现在有一个文件,在字节偏移0到65535(含)之间没有数据 ,后面是一些字节偏移65536到73727(假设写入8192字节)的数据。 这个“缺失”的数据就是文件中的“漏洞”。 当其他程序读取文件时,操作系统会假装有数据:全零字节的数据。
如果执行write
操作的程序没有在块边界上执行,操作系统实际上将分配一些额外的数据(以适应写入整个块)并将其归零。 这些零字节不是“洞”的一部分(它们是文件中真正的零字节),而是在“绿野仙踪”中没有窥视幕后的普通程序,“空洞”零字节和“非” “零”字节是难以区分的。
你需要做的是修改程序来使用O_APPEND
,或者使用像syslog
那样知道如何配合log-rotation操作的库例程,或者两者兼而有之。
[编辑补充:不知道为什么这突然出现在头版,我回答了2011年的一个问题…]
另一种方法如下:
cp /dev/null the_file
这种技术的优点是它是一个单一的命令,所以如果需要sudo访问只需要一个sudo调用。
为什么不只是:>filename
?
( :
是一个bash内建函数,和/bin/true
有相同的效果,而且这两个命令都不会回显任何内容)
证明它的工作原理:
fg@erwin ~ $ du t.txt 4 t.txt fg@erwin ~ $ :>t.txt fg@erwin ~ $ du t.txt 0 t.txt
如果它是一个日志文件,那么正确的方法是使用logrotate。 正如你所说的那样手动不起作用。
我没有在这里尝试红外Linux shell,但你有没有尝试这个?
echo "" > file