cat과 '>'의 차이점으로 파일을 제로화


23

이 두 명령은 파일을 제로 아웃하는 방법에 대해 다른가요? 후자가 전자보다 짧은 방법입니까? 무대 뒤에서 무슨 일이 일어나고 있습니까?

양자 모두

$ cat /dev/null > file.txt

$ > file.txt 

수율

-rw-r--r--  1 user  wheel  0 May 18 10:33 file.txt

답변:


28

cat /dev/null > file.txt고양이쓸모없는 사용이다 .

기본적으로 cat /dev/null단순히 결과 cat아무것도 출력하지 않습니다. 예, 작동하지만 필요하지 않은 외부 프로세스를 호출하기 때문에 많은 사람들이 눈살을 찌푸립니다.
그것은 일반적이기 때문에 공통적 인 것들 중 하나입니다.

사용하면 > file.txt대부분의 쉘에서 작동하지만 완전히 이식 가능하지는 않습니다. 완전히 이식성을 원한다면 다음과 같은 좋은 대안이 있습니다.

true > file.txt
: > file.txt

모두 :true출력 데이터 없음, 그리고 (반면 쉘 내장 명령이다 cat, 따라서 그들은 더욱 가볍고 '적절한'하고, 외부 유틸리티이다).

 

최신 정보:

타일러가 자신의 의견에서 언급했듯이 >| file.txt구문도 있습니다.

대부분의 쉘에는을 통해 기존 파일을 자르지 못하게하는 설정이 있습니다 >. >|대신 사용해야 합니다. 이것은 실제로 첨부 할 때 사람의 실수를 방지하기위한 것입니다 >>. 로 동작을 켤 수 있습니다 set -C.

따라서 이것으로 파일을 자르는 가장 간단하고 적절하며 이식 가능한 방법은 다음과 같습니다.

:>| file.txt

2
콜론 명령 은 POSIX에 정의되어 있습니다. 명령 행 인수를 확장하기 위해 존재하는 널 조작입니다.
kojiro

3
LOL, "고양이 학대"
KM.

2
@kojiro :는 또한 POSIX에 의해 빌트인되도록 규정되어 있으며 실제로는 "스페셜"빌트인으로true 간주 된다는 점과 다릅니다 .
jw013

2
noclobber를 잊지 마십시오 . >| file보다 명백한 잘라 내기입니다.
tylerl

1
없음은 true내장 할 필요가 없습니다 그것은 전통적 아니었다된다. :본 가족의 모든 껍질에 내장되어 있습니다. :POSIX에 내장 된 특수 ( POSIX 셸에서 쓰기 위해 열 수없는 : > file경우 예를 들어 셸을 종료 함 file) true입니다. POSIX는 일부 시스템 보다 :효율적일 수 있다고 언급 true합니다.
Stéphane Chazelas

23

휴대 성 측면에서 :

                      Bourne POSIX  zsh    csh/tcsh  rc/es  fish
> file                Y      Y      N(1)   N(1)      N      N
: > file              N/Y(2) Y(3)   Y      Y(4)      N(5)   N(5)
true > file           Y(5)   Y      Y      Y(5)      Y(5)   Y(5)
cat /dev/null > file  Y(5)   Y      Y(5)   Y(5)      Y(5)   Y(5)
eval > file           Y(3,8) Y(3)   Y      Y(6)      Y      Y
cp /dev/null file (7) Y(5)   Y      Y(5)   Y(5)      Y(5)   Y(5)
printf '' > file      Y(5)   Y      Y      Y(5)      Y(5)   Y

노트:

  1. 명령이없는 재 지정의 경우 sh또는 ksh에뮬레이션을 제외하고 zsh에서는 catNULLCMD 및 READNULLCMD 변수를 사용하여 조정할 수 있는 기본 명령 (stdin 재 지정에 대한 호출기)이 가정됩니다 . 그것은 비슷한 기능에서 영감을 얻었습니다.(t)csh
  2. 주석 리더와 널 (null) 명령 사이의 중간으로 해석 :되는 것처럼 UnixV7에서는 처음에 리디렉션이 수행되지 않았습니다 :. 나중에 모든 내장에서 그렇습니다. 리디렉션이 실패하면 쉘을 빠져 나갑니다.
  3. :하고 eval있는 특수 내장 기능, 리디렉션이 실패 할 경우, 그 종료 쉘 ( bash단 않습니다 POSIX 모드에서).
  4. 흥미롭게도에서는 (t)cshnull 레이블 (for goto)을 정의 하므로 goto ''분기가 있습니다. 리디렉션이 실패하면 셸이 종료됩니다.
  5. 하지 않는 한 / 해당 명령에서 사용할 수있는 경우 $PATH( :일반적으로 아니다 true, cat, cp그리고 printf일반적으로 (POSIX)는 그들을 필요).
  6. 리디렉션이 실패하면 셸이 종료됩니다.
  7. file그러나 존재하지 않는 파일에 대한 심볼릭 링크 인 경우 cpGNU와 같은 일부 구현 에서는 파일 생성을 거부합니다.
  8. Bourne 셸의 초기 버전은 기본 제공 리디렉션을 지원하지 않았습니다.

가독성 측면에서 :

(이 섹션은 매우 주관적입니다)

  • > file. 그것은 >프롬프트 나 주석과 너무 비슷해 보인다. 또한 읽을 때 물어볼 질문은 (그리고 대부분의 쉘은 같은 것에 대해 불평 할 것입니다) 정확히 어떤 출력을 리디렉션합니까? .
  • : > file. :no-op 명령이라고합니다. 그래서 그것은 빈 파일을 생성하면서 바로 읽습니다. 그러나 여기서도 :쉽게 누락되거나 프롬프트로 볼 수 있습니다.
  • true > file: 리디렉션 또는 파일 내용과 관련된 부울은 무엇입니까? 여기서 무엇을 의미합니까? 내가 읽을 때 가장 먼저 떠오르는 것은
  • cat /dev/null > file. CONCATENATE /dev/nullfile? cat종종 파일의 내용을 덤프하는 명령으로 간주되고, 그것은 여전히 의미가 있습니다 : 의 내용을 덤프 에 빈 파일file 뒤얽힌 방식으로 같은 비트 대답, cp /dev/null file하지만 여전히 이해할 수 있습니다.
  • cp /dev/null file. 사본의 내용을 빈 파일file. 일리, 누군가가 방법을 아는 것은 아니지만 cp당신이 만들려고 생각 기본적으로 수행하기위한 것입니다 아니라 장치.filenull
  • eval > file또는 eval '' > file. 아무것도 실행하지 않고 출력을로 리디렉션합니다 file. 이해가 되네요 일반적인 관용구가 아닌 것이 이상합니다.
  • printf '' > file: 파일에 아무것도 명시 적으로 인쇄 하지 않습니다. 나에게 가장 의미있는 것.

성능면에서

차이점은 우리가 쉘 내장을 사용하는지 여부입니다. 그렇지 않은 경우 프로세스를 분기하고 명령을로드하고 실행해야합니다.

eval모든 쉘에 내장되어 있습니다. :사용 가능한 모든 위치에 내장되어 있습니다 (Bourne / csh 좋아함). trueBourne과 같은 쉘에만 내장되어 있습니다.

printf가장 현대적인 Bourne 같은 쉘이 내장되어 fish있습니다.

cp그리고 cat일반적으로 내장되어 있지 않습니다.

이제 cp /dev/null file쉘 리디렉션을 호출하지 않으므로 다음과 같은 것들이 있습니다.

find . -exec cp /dev/null {} \;

다음보다 더 효율적일 것입니다.

find . -exec sh -c '> "$1"' sh {} \;

(반드시 다음과 같을 필요는 없습니다.)

find . -exec sh -c 'for f do : > "$f"; done' sh {} +

).

몸소

개인적으로, 나는 : > fileBourne과 같은 껍질을 사용 하며 요즘 Bourne과 같은 껍질을 사용하지 않습니다.


무엇에 대해 dd of=file count=0?
kojiro

2
@kojiro, dd(Solaris 10 이상과 같은) 일부 구현에서는 count=0무시됩니다. dd if=/dev/null of=file더 휴대하기 쉬울 것입니다. 어쨌든 그것은 쉘과 독립적입니다.
Stéphane Chazelas

알았어. 그러나 그것은 포함보다 가치가 적지 cp /dev/null file않습니까?
kojiro

2
@kojiro cp /dev/null file는 일반적인 관용구입니다. 나는 그로 제한하고 있으며, 요점은 가능한 모든 방법을 나열하지는 않습니다.
Stéphane Chazelas

5

을보고 싶을 수도 있습니다 truncate. 파일을 자릅니다.

예를 들면 다음과 같습니다.

truncate --size 0 file.txt

아마을 사용하는 것보다 느릴 것 true > file.txt입니다.

그러나 내 주요 요점은 truncate파일을 자르기위한 것이며,>를 사용하면 파일을 자르는 부작용이 있습니다.


2
당신이 말한 0 이외로 파일을 절단 할 때 자르기는 좋은 쉘도없이 당신이 컨텍스트 어디 설명 할 수 있습니다 이상한 성명 truncate하지만 둘 다 사용할 것 >아니다 unistdC 라이브러리를 사용할 수 있을까?
kojiro

실제로는 아닙니다. 사용 가능한 모든 스크립트 또는 프로그래밍 언어에 대해 더 우아한 솔루션이있을 수 있습니다.
Fabian

3
truncateGNU coreutils에 추가 된 비교적 최근 (2008 년) FreeBSD 유틸리티이며 ( --sizeGNU 긴 옵션 스타일은 GNU에만 해당) GNU 이외의 시스템에서는 사용할 수 없으며 이전 GNU 시스템에서는 사용할 수 없습니다. 나는 그것이 휴대용이라고 말하지 않을 것입니다. cp /dev/null file쉘 리디렉션없이 작동하고 더 이식성이 뛰어납니다.
Stéphane Chazelas

좋아요, 그 이식성 주석을 제거하겠습니다. 최근에 대한 귀하의 정의가 다른 것 같습니다.
Fabian

2

대답은 무엇 file.txt이고 프로세스가 어떻게 작성되는지 에 달려 있습니다!

일반적인 사용 사례를 인용하겠습니다.라는 로그 파일이 커지고 file.txt회전하고 싶습니다.

따라서 당신은, 예를 들어, 복사 file.txtfile.txt.save다음 잘라 file.txt.

이 시나리오에서는 경우 파일을 열되지 않은 another_process: (예 another_process, 다음이 개 제안, 동일 잘 모두 작업이 파일에 대한 프로그램 출력, 예를 들어 프로그램 로깅 뭔가를 할 수 있습니다) (단, 2는로 선호한다 먼저 "cat / dev / null> file.txt"는 쓸모없는 고양이 사용이며 / dev / null을 열고 읽습니다).

그러나 실제 문제 other_process는 여전히 활성화되어 있고 여전히 file.txt로 이동하는 열린 핸들이있는 경우입니다.

그런 다음 other process파일을 여는 방법에 따라 두 가지 주요 사례가 발생 합니다.

  • 경우 other_process정상적인 방법으로 그것을 열고, 다음 핸들은 여전히 오프셋 1200 바이트에서 예를 들어, 파일의 이전 위치를 가리키는 것입니다. 따라서 다음 쓰기는 오프셋 1200에서 시작하므로 1200 선행 널 문자와 함께 1200bytes 파일 (+ other_process가 쓴 것)을 다시 갖게됩니다! 당신이 원하는 것이 아니라고 생각합니다 .

  • 경우 other_processfile.txt"추가 모드"에서, 다음의 글마다 포인터가 적극적으로 파일의 끝에 찾을 것이다. 따라서 자르면 바이트 0까지 "찾아"서 나쁜 부작용이 없습니다! 이것은 당신이 원하는 것입니다 (... 보통!)

즉, 파일을자를 때 other_process해당 위치에 계속 쓰는 모든 파일 이 "추가"모드로 열렸 는지 확인해야 합니다. 그렇지 않으면을 중지 other_process하고 다시 시작해야하므로 이전 위치 대신 파일의 시작 부분을 가리 키기 시작합니다.

참조 : /programming//a/16720582/1841533 더 명확하게 설명하고 /programming//a/984761/1841533 에서 정상 및 추가 모드 로깅의 차이점에 대한 간단한 짧은 예


2
이 답변 중 실제로는 거의 관련이 없거나 질문에 대답합니다. 의 차이 cat /dev/null > file와는 > fileA는 cat /dev/null해당 파일에 차이가 없습니다.
jw013

@ jw013 : 맞아요! 그러나 나는 잘 알려지지 않았기 때문에 "원하는 것 / 원하는 것"정보를 다시 언급 할 수있는 기회를 얻고 싶었고 로그를 회전하려고하는 누군가를 강타 할 수 있습니다 (일반적인 경우) 파일 자르기).
Olivier Dulac

1
모든 것을위한 시간과 장소가 있습니다. 귀하의 정보는 다른 상황에서는 유용 할 수 있지만 여기에 속하지는 않습니다. 로그를 회전하려고 시도하는 사람이 전혀 관련이없는이 리디렉션 질문을 보지 않기 때문에 더 적절한 위치를 찾아야합니다. 옥수수 밭 한가운데에 유용한 호박 식물이 잡초로 간주되는 것처럼 귀하의 대답은 디지털 잡초와 같습니다.
jw013

1

나는 이것이 깨끗해 보이고 누군가 실수로 리턴 키를 누르는 것처럼 보이지 않기 때문에 이것을 좋아하고 자주 사용합니다.

echo -n "" > file.txt

내장도되어야합니까?


3
파일을 0으로 지우는 방법에는 여러 가지가 있습니다. 나는 KM을 생각합니다. 질문에 표시된 두 가지 방법의 차이점을 이해하는 데에만 관심이있었습니다.
drs

6
많은 echo구현은 지원하지 않으며 -n( -n<SPC><NL>여기서 출력 printf '' > file.txt될 것입니다.) 더 이식성이 좋을 것입니다 (적어도 현대 / POSIX 시스템에서)
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.