왜`cat / dev / null> / var / log / messages`입니까?


77

bash 스크립팅 예제 페이지 에서 저자는 다음 스크립트를 제시합니다.

# Cleanup
# Run as root, of course.

cd /var/log
cat /dev/null > messages
cat /dev/null > wtmp
echo "Log files cleaned up."

왜 당신은 cat /dev/null무엇을하겠습니까? 여기 의도를 이해 할 수없는 (그것을 사용처럼 while TRUE; sleep 1; elihw을 위해 {some busy program}?). 그러나 저자는 이것을“이상한 것은 없다”고 부릅니다.

답변:


41

일반적으로 cat /dev/null > [something]실제 파일 상태를 방해 할 위험이 전혀없는 상태에서 파일 내용을 지우려고 할 때 사용합니다. 파일의 내용은 cat /dev/null파일 자체가 존재하고 파일 시스템에 알려진 파일 자체에 의해 명확하게 지워지지 만 여전히 동일한 inode 번호, 소유권 및 권한으로 존재합니다.

로그 파일의 경우 다른 프로세스에 의해 로그 파일 자체가 "사용 중"으로 표시 될 수 있습니다. 예를 들어, rm /var/log/messages && touch /var/log/messages다른 프로세스를 방해 할 수 있으며 실행중인 프로세스가 질식 할 수 있습니다. 파일에 연결된 특정 inode 번호에 고정되어있는 프로세스 /var/log/messages는 갑자기 패닉 상태가되어“이봐! 무슨 일이 일어난 /var/log/messages! "파일이 아직 거기 경우에도 마찬가지입니다. 소유권 및 권한이 잘못 재생성 될 수있는 잠재적 인 문제는 말할 것도 없습니다.

파일의 사용 / 상태에 대한 이러한 불확실성으로 인해 cat /dev/null > [something]로그를 지우고 싶지만 기존 프로세스의 작동 을 잠재적으로 방해 하지 않으려는 시스템 관리자는이를 사용하는 것이 좋습니다 .

또한 페이지와 관련 하여 작성자 에게 링크 하면 다음과 같이 표시됩니다.

콘솔이나 터미널 창의 명령 줄에서 하나씩 쉽게 호출 할 수있는 일련의 명령 만 여기에 있습니다. 명령을 스크립트에 넣는 것의 장점은 몇 번이고 다시 입력 할 필요가 없습니다.

따라서 저자가 언급 한“비정상적인 것은 없다”는 특정 배쉬 스크립트가 무엇인지에 대한 전체 개념과 관련이 있습니다. 명령 행에서 쉽게 실행할 수 있지만 텍스트 파일에 배치되는 간단한 명령 세트 일뿐입니다. 반복해서 다시 입력하지 않아도됩니다.


10
@jlliagre "살아있는"유일한 이유는 원저자가 그렇게하는 이유에 초점을 맞춘 질문의 맥락입니다. "신화"를 철회하는 것에 열정이 있다면, 원저자의 코딩 방법에 대한 맥락과 그것이 다른 방법으로 대체 될 수 있다고 생각하는 이유에 대한 관점을 제공하는 답변을 게시하십시오.
JakeGould

7
@jlliagre Cyrus의 답변은 원저자가 왜 그 방법을 사용했는지 또는 그 이유를 설명하는 핵심 질문을 다루지 않습니다. 언급 된 튜토리얼은 상당히 오래되었고 합리적으로 받아 들여졌습니다. "도시의 전설"이라고 생각되는 것은 잘못된 일이 아닙니다. 오히려 한 사람이 코딩하는 방식과 다른 사람이 코딩하는 방식입니다. 저것과 같이 쉬운. 안정성이나 성능에 부정적인 영향을 미치지 않는 스타일 문제입니다.
JakeGould

3
truncate -s 0같은 일을하고 관용적이지 않습니다. 그러나 셸 프로그래머는 보수적 인 사람들이며 해당 명령이 없을 정도로 오래되었거나 엉뚱한 시스템을 만날 수 있습니다.
Schwern

5
@skift cat /dev/null > /foo/bar는 파일을 자릅니다. echo "" > /foo/bar잘린 다음 줄 바꿈 문자 하나를 씁니다.
David

2
rm & touch에 비해이 방법의 또 다른 장점은 소유권과 권한이 유지된다는 것입니다.
jjmontes

121

왜 고양이를 / dev / null로 하시겠습니까?

inode를 그대로 유지하면서 파일 내용을 자르기 위해 그렇게 할 것입니다. 파일을 읽거나 쓰기 위해 열어 둔 모든 프로그램은 파일 크기가 0으로 재설정된다는 사실 외에는 영향을받지 않습니다.

대체로 발견 된 가짜 대안은 파일을 제거한 다음 다시 작성하는 것입니다.

rm file
touch file

또는 유사한 :

mv file file.old
gzip file.old
touch file

문제는 이러한 방법으로 삭제 된 파일을 삭제했을 때 열려있는 프로세스가 이전 파일을 쓰지 못하게하지는 않습니다. 파일이 삭제 될 때 Unix 파일 시스템 아래에있는 이유는 파일 이름 (경로)과 내용 (inode)의 연결 만 해제하는 것입니다. 아이 노드는 읽기 나 쓰기를 위해 열린 프로세스가있는 한 살아있다.

삭제 된 파일을 열 수있는 간단하고 이식 가능한 방법이 없기 때문에 파일 삭제 후 작성된 로그가 손실됩니다. 프로세스가 삭제 된 파일에 쓰는 동안 해당 내용은 여전히 ​​파일 시스템의 공간을 사용합니다. 즉, 디스크를 채우는 중이기 때문에 파일을 제거 / 만들면 디스크는 채워진 상태로 유지됩니다. 후자의 문제를 해결하는 한 가지 방법은 로거 프로세스를 다시 시작하는 것이지만 중요한 서비스 및 중간 로그에 대해서는 그렇게하지 않을 수 있습니다. 생성 한 파일이 원본과 동일한 권한, 소유자 및 그룹을 가질 수 없기 때문에 부작용이 있습니다. 예를 들어, 로그 분석기가 새로 작성된 파일을 읽지 못하게하거나 로깅 프로세스가 자체 로그를 작성하지 못하게 할 수 있습니다.

첫 번째 방법 은 강렬한 도시 전설에도 불구하고cat /dev/null > file 목표를 올바르게 달성 하지만 그 cat /dev/null부분은 전혀 유용하지 않습니다. 그것은 의도적으로 비어있는 의사 파일을 열고, 아무것도 읽지 못하고 결국 종료합니다. 이 명령을 사용하면 키 입력, 바이트, 시스템 호출 및 CPU 사이클이 낭비되며 의심 할 여지없이 더 빠른 no-op 명령으로 명령을 변경 :하거나 명령을 전혀 사용하지 않고 대부분의 셸 을 사용하여 기능을 변경하지 않고도 대체 할 수 있습니다 .

쓸모없는 방법을 설명하기 위해 은유를 시도해 봅시다 cat /dev/null. 유리를 비우는 것이 목표라고 가정 해 봅시다.

  • 먼저 액체를 제거하십시오. 그것은 충분하고 정확하게 > file리디렉션이 항상 먼저 처리된다는 사실을 감안할 때 ( ) 무엇입니까 ?

  • 그런 다음 빈 병 ( /dev/null) 을 골라 빈 유리 ( )에 붓습니다 cat. 이것은 무의미한 단계입니다 ...

링크 된 문서 를 끝까지 읽으면 향상된 스크립트 버전에서이 줄의 주석을 볼 수 있습니다.

    cat / dev / null> wtmp #   ':> wtmp'및 '> wtmp'는 동일한 효과를 갖습니다.

그들은 실제로; cat /dev/null코드에 너무 나쁜 것이 유지되었습니다.

즉, 다음 코드는 모든 공통 쉘 (모두 cshsh패밀리)에서 작동합니다.

cd /var/log
: > messages
: > wtmp
echo "Log files cleaned up."

이처럼, 보른 구문을 사용하여 모든 조개와 함께 작동합니다 ash, bash, ksh, zsh좋아하는 및 :

cd /var/log
> messages
> wtmp
echo "Log files cleaned up."

그러나 이전의 POSIX 이전 Bourne 쉘에서는 cat /dev/null파일을 계속 실행중인 쉘 스크립트에 의해 작성된 파일을 포함하여 이러한 명령 이 잘리지 않습니다. 0 바이트 파일 대신 크기가 변경되지 않는 스파 스 파일입니다. 파일이 쓰기 전의 현재 위치라고 생각하는 프로세스를 통해 파일을 작성하는 경우에도 마찬가지입니다.

또한 파일을 자르도록 제안 된 일부 대체 솔루션에 결함이 있음을주의하십시오.

  • 다음 두 가지 모두 작업을 수행하지 않습니다. 결과 파일은 비어 있지 않지만 빈 줄이 있습니다. 이렇게하면 wtmp해당 고정 너비 레코드 와 같은 로그 파일이 손상 됩니다.

    echo > file
    echo "" > file
    
  • BSD sh옵션을 기반으로 한 다음 옵션은 이식성이 없으며 POSIX는 echo에 허용되는 옵션을 지정하지 않으므로 " -n" 가있는 행이 포함 된 파일로 끝날 수 있습니다 .

    echo -n > file
  • System V sh이스케이프 시퀀스를 사용하여 이식 할 수 없습니다 . 일부 쉘은 " \c" 로 줄을 포함하는 파일을 만듭니다 :

    echo "\c" > file
  • 그 작업을 수행하도록 설계된 명령을 사용합니다. truncatePOSIX에 의해 지정되지 않은이 명령이 Unix / Linux 시스템에서 누락 될 수 있기 때문에 사용 중이 아닙니다.

    truncate -s 0

마지막으로, 이식성이 있고 작업을 올바르게 수행 할 수있는 몇 가지 대안이 있습니다.

  • 파일에 빈 문자열을 명시 적으로 인쇄 :

    printf "" > file
  • 더 읽기 쉽지만 trueno-op 명령과 완전히 동일한 명령을 사용합니다 :.

    true > file

1
@JonathanLeffler csh반드시 문서화되어 있지는 않지만 모든 현재 구현의 일부라고 생각 합니다. Solaris csh 매뉴얼 페이지에서 : Null command. This command is interpreted, but performs no action.. tcsh매뉴얼 페이지 또는 원래 BSD 에서 동일한 내용을 발견하지 csh못했지만이 구문은 항상 작동했을 수 있습니다.
jlliagre

6
글을 쓰는 한 가지 이유 cat /dev/null는 당신의 의도를 분명하게하기 위해서입니다.
Davidmh

1
@Davidmh 그것은 합리적이지만 당신의 진술은 사실 확인에 저항하지 않습니다. 나는 아마도 몇 십 년 동안이 쉘 관용구를 관찰했습니다. 저자에게 그 이유를 물어볼 기회가 있었을 때, 나는 항상/dev/null 0 바이트를 주입하는 효율적인 방법을 사용하는 것에 대한 건전한 이론을 얻었습니다 :. 바로이 페이지에서 간결하지만 요점까지의 사이러스 답변은 0 표를 얻지 못했지만 사실 cat /dev/null에 도전 한 제이크 굴드 (JakeGould)는 논란 이 없었습니다.
jlliagre 2016

2
@jlliagre 쉘에 대한 나의 지식은 꽤 기본적이므로 아마도 최고의 인구 목표가 아닐 것입니다. 그러나 맨손으로 >또는 :명확하지 않습니다. 나는 신화가 그 사용으로 인해 전파되었다는 것이 부끄러운 일임을 동의합니다.
Davidmh

4
@Davidmh 리디렉션 전에 명시 적으로 뭔가를 원한다면 printf "" > file쉘 내장으로 구현되는 것처럼 휴대용 (POSIX)과 경량 인 것이 좋습니다 .
jlliagre

6

파일을 0 크기로 만드는 번거로운 방법입니다.

cd /var/log
> messages
> wtmp
echo "Log files cleaned up."

이 구문은 모든 쉘에서 작동하지는 않습니다.
reinierpost

2
옳은. 질문은 "bash"로만 태그됩니다.
Cyrus

@reinierpost 모든 Bourne 스타일의 쉘에서 작동합니까? 걱정하지 마십시오 csh.
Barmar

: > messages작동합니다. :또는 true아무것도 인쇄하지 않고 true를 반환하는 명령에 대한보다 확실한 선택입니다.
Peter Cordes

-3

열린 파일을 자릅니다. 이것은 동등하며 더 이해하기 쉽습니다.

echo -n > /var/log/messages

(개행을 피하기 위해 -n을 추가했습니다)


3
이것은 실제로 더 이해하기 쉽지만 불행히도 동등한 것은 아닙니다. wtmp경우 와 같이 기능이 손상 될 수도 있습니다. 업데이트 된 답변을 참조하십시오.
jlliagre

echo -n은 개행을 피합니다.
bbaassssiiee

6
당신이 확실하게 사용한다면 bash, -n모든 Bourne 쉘에서 작동한다고 보장되지는 않습니다.
jlliagre
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.