cat / dev / null> file.log不会在达尔文中截断大文件


15

过去,在linux系统上,我已经能够使用截断大型的打开日志文件(即进程正在主动写入的文件)cat /dev/null > file.log

但是,在10.9(小牛)上,情况似乎并非如此。我有一个11GB的文件正在由应用程序登录,但是当我对上述文件执行相同的命令时,似乎什么也没发生。

当我在一个很小的文件上尝试时,它确实起作用。

这里是ls -l /dev/null

crw-rw-rw- 1 root wheel 3, 2 Dec 16 12:49 /dev/null

我也尝试cp /dev/null file.log无济于事。

考虑到我可以利用truncate函数(man 2 truncate在Darwin中),我对此进行了编译并针对两个文件(一个很小的文件,另一个是实际的日志文件)运行了它。再次,它针对琐碎的文件,不适用于更大的日志。

/*
 * Copyright (c) 2013 Thomas de Grivel <thomas@lowh.net>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 ...
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <unistd.h>

int main (int argc, const char **argv)
{
        int e = 0;
        while (--argc) {
                argv++;
                if (truncate(*argv, 0)) {
                        e = 4;
                        warn("%s", *argv);
                }
        }
        return e;
}

0无论我使用哪个文件,该过程都会返回。


您怎么知道它不起作用?是什么dudu -h说什么?该文件是否可能是稀疏文件?
Mikel 2013年

2
另外,在此帖子中包含许可证的目的是什么?似乎只会增加噪音。
Mikel 2013年

du -h /tmp/file.log结果11G /tmp/file.log
chb 2013年

@Mikel出于礼貌,我将许可证包括在内...您会注意到我已编辑了大部分许可证。
chb 2013年

1
执照
让人

Answers:


12

cat /dev/null有点令人费解地写了一种不产生任何输出的命令。:true更明显的

在所有cat /dev/null > file: > file甚至> file大多数外壳程序中,外壳程序都会在stdout上使用O_TRUNC打开文件,然后运行不输出任何内容的应用程序,然后关闭文件并将其截断。

但是,在那种情况下或使用truncate系统调用时,如果填充该文件的进程没有使用O_APPEND标志打开该文件,则下次写入文件描述符时,它将在文件上打开数据在文件中偏移的位置。

因为HFS +不支持稀疏文件,所以这意味着偏移量之前的空间必须由系统重新分配并用零填充。

因此,您需要在截断该文件之前终止正在写入该文件的应用程序。或者,您需要确保应用程序使用打开文件O_APPEND(就像>>使用shell重定向一样)。

如果您想尝试一下:

$ exec 3> x
$ yes | head -n 50000 >&3
$ ls -ls x
200 -rw-r--r--  1 me me  100000 Dec 16 21:32 x

现在我外壳的fd 3在文件中为100000字节

$ : > x
$ ls -ls x
0 -rw-r--r--  1 me me  0 Dec 16 21:34 x

现在文件被截断了(大小为0,磁盘上没有空间)。

$ echo >&3
$ ls -ls x
200 -rw-r--r--  1 me me  100001 Dec 16 21:34 x

向偏移量为100000的文件写入1个字节,该文件现在为100001字节大,第一个全为零,在HFS +上将使用100k以上,但在大多数其他Unix文件系统中大约只有一个磁盘块

另一方面,使用:

$ exec 3>> x
$ yes | head -n 50000 >&3
$ ls -ls x
200 -rw-r--r--  1 me me  100000 Dec 16 21:35 x
$ : > x
$ echo >&3
$ ls -ls x
8 -rw-r--r--  1 me me  1 Dec 16 21:36 x

将1个字节写入文件的位置不是偏移量100000,而是因为,在文件末尾写入O_APPEND。该文件大1个字节,并占用了保留该1个字节所需的空间。


1
我从这个答案中学到了很多。谢谢。
chb 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.