[unix] cat / dev / null> file.log가 Darwin에서 큰 파일을 자르지 않습니다.

과거에는 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소용이 없었습니다.

자르기 기능 ( man 2 truncateDarwin에서) 을 활용할 수 있다고 생각하여 이것을 컴파일하고 두 가지 파일, 하나는 사소한 크기의 파일과 다른 하나는 실제 로그 파일에 대해 실행했습니다. 다시, 그것은 사소한 파일에 대해 작동했으며 훨씬 더 큰 로그에서는 작동하지 않았습니다.

/*
 * 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어떤 파일을 사용하든 관계없이 프로세스가 반환 됩니다.



답변

cat /dev/null출력을 생성하지 않는 명령을 작성하는 방법이 약간 복잡합니다. :또는 true더 명백한 것입니다.

모두에서 cat /dev/null > file, : > file그리고 심지어 > file대부분의 쉘에서, 쉘이 다음 아무것도 출력하지 않는 응용 프로그램을 실행, 표준 출력에 O_TRUNC와 파일을 열고, 파일이 닫히고 절단 왼쪽.

그러나이 경우 또는 truncate시스템 호출을 사용할 때 해당 파일을 채우는 프로세스가 O_APPEND 플래그를 사용하여 파일을 열지 않으면 다음에 파일 디스크립터에 파일을 열 때 파일에서 파일을 열 때 파일 내에있는 오프셋의 데이터

HFS +는 스파 스 파일을 지원하지 않기 때문에 해당 오프셋 이전의 공간을 다시 할당하고 시스템에서 0으로 채워야합니다.

따라서 파일을 자르기 전에 해당 파일에 쓰는 응용 프로그램을 종료해야합니다. 또는 응용 프로그램에서 파일을 여는 지 확인해야합니다 O_APPEND( >>셸 리디렉션을 사용 하는 경우 와 같이 ).

당신이 그것을 실험하고 싶다면 :

$ 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 바이트로 커집니다. 첫 번째 0은 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

오프셋 100000이 아니라 파일의 끝에 1 바이트를 파일에 쓰는 중 O_APPEND입니다. 파일은 1 바이트 크기이며 해당 1 바이트를 보유하는 데 필요한 공간을 차지합니다.


답변