在linux中使用时清空文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8518219/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 03:40:00  来源:igfitidea点击:

Empty a file while in use in linux

linuxshell

提问by Miro Barsocchi

I'm trying to empty a file in linux while in use, it's a log file so it is continuosly written. Right now I've used:

我试图在使用时清空 linux 中的文件,它是一个日志文件,因此它被连续写入。现在我用过:

echo -n > filename

or

或者

cat /dev/null > filename

but all of this produce an empty file with a newline character (or strange character that I can see as ^@^@^@^@^@^@^@^@^@^@^@^.. on vi) and I have to remove manually with viand ddthe first line and then save.

但所有这些都会产生一个带有换行符的空文件(或我可以看到的奇怪字符 ^@^@^@^@^@^@^@^@^@^@^@^.. on vi)和我必须与手动删除vidd第一行,然后保存。

If I don't use viadn ddI'm not able to manipulate file with grepbut I need an automatic procedure that i can write in a shell script.

如果我不使用vidn,dd我将无法操作文件,grep但我需要一个可以在 shell 脚本中编写的自动程序。

Ideas?

想法?

回答by fge

Why not just :>filename?

为什么不只是:>filename

(:is a bash builtin having the same effect as /bin/true, and both commands don't echo anything)

:是一个与 具有相同效果的 bash 内置/bin/true命令,并且两个命令都不回显任何内容)

Proof that it works:

证明它有效:

fg@erwin ~ $ du t.txt
4       t.txt
fg@erwin ~ $ :>t.txt
fg@erwin ~ $ du t.txt
0       t.txt

回答by Jonathan

I have not a linux shell here to try ir, but have you try this?

我这里没有 linux shell 来尝试 ir,但是您尝试过吗?

echo "" > file

回答by pgl

This should be enough to empty a file:

这应该足以清空文件:

> file

However, the other methods you said you tried should also work. If you're seeing weird characters, then they are being written to the file by something else - most probably whatever process is logging there.

但是,您说您尝试过的其他方法也应该有效。如果您看到奇怪的字符,那么它们是由其他东西写入文件的 - 很可能是在那里记录的任何进程。

回答by holygeek

If it's a log file then the proper way to do this is to use logrotate. As you mentioned doing it manually does not work.

如果它是一个日志文件,那么正确的方法是使用 logrotate。正如您所提到的,手动操作是行不通的。

回答by alexs333

Another way is the following:

另一种方法如下:

cp /dev/null the_file

The advantage of this technique is that it is a single command, so in case it needs sudo access only one sudo call is required.

这种技术的优点是它是一个单一的命令,所以如果它需要 sudo 访问,只需要一个 sudo 调用。

回答by torek

What's going on is fairly simple: you areemptying out the file.

发生的事情相当简单:您正在清空文件。

Why is it full of ^@s, then, you ask? Well, in a very real sense, it is not. It does not contain those weird characters. It has a "hole".

^@那么,你问为什么它充满了s?嗯,在非常真实的意义上,它不是。它不包含那些奇怪的字符。它有一个“洞”。

The program that is writing to the file is writing a file that was opened with O_WRONLY(or perhaps O_RDWR) but notO_APPEND. This program has written, say, 65536 bytes into the file at the point when you empty out the file with cp /dev/null filenameor : > filenameor some similar command.

被写入文件的程序编写与打开的文件O_WRONLY(或者O_RDWR),但没有O_APPEND。当您使用cp /dev/null filename: > filename或某些类似命令清空文件时,该程序已将 65536 字节写入文件。

Now the program goes to writeanother chunk of data (say, 4096 or 8192 bytes). Where will that data be written? The answer is: "at the current seek offset on the underlying file descriptor". If the program used O_APPENDthe writewould be, in effect, preceded by an lseekcall that did a "seek to current end-of-file, i.e., current length of file". When you truncate the file that "current end of file" would become zero (the file becoming empty) so the seek would move the writeoffset to position 0 and the write would go there. But the program did not use O_APPEND, so there is no pre-write"reposition" operation, and the data bytes are written at the current offset (which, again, we've claimed to be 65536 above).

现在程序转到write另一个数据块(例如,4096 或 8192 字节)。这些数据会写在哪里?答案是:“在底层文件描述符上的当前搜索偏移处”。如果程序使用O_APPENDwrite,实际上会在lseek调用之前执行“查找当前文件结尾,即文件的当前长度”。当您截断“当前文件结尾”将变为零(文件变空)的文件时,搜索会将write偏移量移动到位置 0 并且写入将转到那里。但是程序没有使用O_APPEND,所以没有预先write“重新定位”操作,数据字节写入当前偏移量(同样,我们在上面声称是 65536)。

You now have a file that has no datain byte offsets 0 through 65535 inclusive, followed by some data in byte offsets 65536 through 73727 (assuming the writewrites 8192 bytes). That "missing" data is the "hole" in the file. When some other program goes to read the file, the OS pretends there isdata there: all-zero-byte data.

您现在有一个文件,字节偏移量 0 到 65535 中没有数据,随后是字节偏移量 65536 到 73727 中的一些数据(假设write写入 8192 个字节)。“丢失”的数据就是文件中的“漏洞”。当其他程序读取文件时,操作系统会假装那里数据:全零字节数据。

If the program doing the writeoperations does not do them on block boundaries, the OS will in fact allocate some extra data (to fit the write into whole blocks) and zero it out. Those zero bytes are not part of the "hole" (they're real zero bytes in the file) but to ordinary programs that do not peek behind the curtain at the Wizard of Oz, the "hole" zero-bytes and the "non-hole" zero bytes are indistinguishable.

如果执行write操作的程序没有在块边界上执行这些操作,那么操作系统实际上会分配一些额外的数据(以使写入适合整个块)并将其归零。那些零字节不是“洞”的一部分(它们是文件中真正的零字节),但对于不会窥视绿野仙踪幕后的普通程序来说,“洞”零字节和“非-hole" 零字节无法区分。

What you need to do is to modify the program to use O_APPEND, or to use library routines like syslogthat know how to cooperate with log-rotation operations, or perhaps both.

您需要做的是修改程序以使用O_APPEND,或者使用像syslog知道如何与日志旋转操作合作的库例程,或者两者兼而有之。

[Edit to add: not sure why this suddenly showed up on the front page and I answered a question from 2011...]

[编辑补充:不知道为什么这突然出现在首页上,我回答了 2011 年的一个问题......]