대상 파일이 아직 없을 때`>>`와의 리디렉션이`>`와 동일합니까?


80

Bash 또는 sh와 같은 쉘을 고려하십시오. 대상 파일이 존재하는 경우 >>>그 사이의 기본적인 차이점은 다음 과 같습니다.

  • > 파일을 0 크기로 자른 다음 기록합니다.
  • >> 잘리지 않고 파일 끝에 쓰거나 추가합니다.

파일이 없으면 크기가 0으로 작성됩니다. 그런 다음에. 이것은 두 연산자 모두에 해당됩니다. 대상 파일이 아직없는 경우 연산자가 동일하게 보일 수 있습니다.

그들은 정말입니까?

답변:


107

tl; dr

번호 >>는 본질적으로 "항상 파일의 끝을 찾습니다"이며 >마지막으로 쓴 위치에 대한 포인터를 유지합니다.


전체 답변

(참고 : 모든 테스트는 데비안 GNU / 리눅스 9에서 수행되었습니다).

또 다른 차이점

아닙니다. 이 또 다른 차이점은. 대상 파일이 이전에 존재했는지 여부에 관계없이 나타날 수 있습니다.

이를 관찰하려면 데이터를 생성하고 >또는 >>(예 :)를 사용하여 파일로 리디렉션하는 프로세스를 실행하십시오 pv -L 10k /dev/urandom > blob. 파일 크기를 실행하고 변경하십시오 (예 :) truncate. 항상 끝에 추가 >하면서 (증가) 오프셋 을 유지하는 것을 볼 수 >>있습니다.

  • 파일을 더 작은 크기로 자르면 (제로 크기 일 수 있음)
    • >상관 없으며 아무 일도 일어나지 않은 것처럼 원하는 오프셋에 기록합니다. 오프셋 잘림이 파일 끝을 넘어 서면 바로 파일 크기가 다시 커지고 더 커지고 누락 된 데이터는 0으로 채워집니다 (가능한 경우 스파 스 방식으로).
    • >> 새 끝에 추가하면 파일이 잘린 크기에서 커집니다.
  • 파일을 확대하면
    • >상관 없으며 아무 일도 일어나지 않은 것처럼 원하는 오프셋에 기록합니다. 크기를 변경 한 직후 오프셋이 파일 내부 어딘가에 있으면 오프셋이 새 끝에 도달 할 때까지 파일이 잠시 동안 멈추지 않고 파일이 정상적으로 커집니다.
    • >> 새 끝에 추가하면 파일이 확대 된 크기에서 커집니다.

또 다른 예는 >>데이터 생성 프로세스가 실행 중이고 파일에 쓸 때 별도의 추가 항목을 추가하는 것입니다. 파일을 확대하는 것과 비슷합니다.

  • 생성 프로세스 >는 원하는 오프셋에 기록하고 추가 데이터를 결국 덮어 씁니다.
  • with 생성 프로세스 >>는 새 데이터를 건너 뛰고이를 지나서 추가합니다 (레이스 조건이 발생할 수 있으며 두 스트림이 인터리브 될 수 있지만 여전히 데이터를 덮어 쓰지 않아야합니다).

실제로 중요합니까? 이 이 질문은 :

stdout에서 많은 출력을 생성하는 프로세스를 실행 중입니다. 파일로 전부 보내기 [...] 로그 회전 프로그램을 사용할 수 있습니까?

이 답변 은 솔루션에 다음 logrotatecopytruncate같은 옵션 있다고 말합니다 .

사본을 작성한 후 기존 로그 파일을 이동하고 선택적으로 새 로그 파일을 작성하는 대신 원본 로그 파일을 잘라냅니다.

위에서 쓴 내용에 따르면 리디렉션 >하면 잘린 로그가 즉시 커집니다. Sparseness는 하루를 절약 할 수 있으며 디스크 공간을 낭비하지 않아도됩니다. 그럼에도 불구하고, 각각의 연속적인 로그는 완전히 불필요한 0을 가지고 있습니다.

그러나 logrotateSparseness를 유지하지 않고 복사본을 만들면 이러한 선행 0은 복사본을 만들 때마다 점점 더 많은 디스크 공간이 필요합니다. 나는 도구 동작을 조사하지 않았으며, 즉흥적으로 압축 또는 압축 (압축이 활성화 된 경우)으로 충분히 영리 할 수 ​​있습니다. 여전히 0은 문제를 일으키거나 중립적 일 수 있습니다. 그들에게 좋은 것은 없습니다.

이 경우 대상 파일을 아직 만들려고하더라도 >>대신 대신 사용 하는 >것이 훨씬 좋습니다.


공연

보시다시피, 두 연산자는 시작시뿐만 아니라 나중에 다르게 작동합니다. 이로 인해 약간의 성능 차이가 발생할 수 있습니다. 현재로서는 지원하거나 반증 할 의미있는 테스트 결과가 없지만 성능이 일반적으로 동일하다고 가정해서는 안된다고 생각합니다.


9
그래서 >>"항상 파일의 끝을 추구"본질적으로있는 동안은 >마지막으로 기록 된 위치에 대한 포인터를 유지한다. 작동 방식에 미묘한 성능 차이가있을 수 있습니다 ...
Mokubai

10
시스템 호출 레벨에서 to 플래그를>> 사용하십시오 . 그리고 실제로는 사용 하지만 그렇지 않습니다. 의 조합 도 가능할 것이다, 쉘 언어는 해당 기능을 제공하지 않습니다. O_APPENDopen()>O_TRUNC>>O_TRUNC | O_APPEND
ilkkachu

3
@jjmontes, 표준 소스는 POSIX가 될 것입니다 : pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/… 물론 Bash 매뉴얼에는 지원하는 비표준 오퍼레이터를 포함한 리다이렉션 오퍼레이터에 대한 설명도 있습니다 : gnu.org/ software / bash / manual / html_node / Redirections.html
ilkkachu

2
@ilkkachu 나는 이것이 당신의 의견 후에 궁금했던 O_APPEND에 대한 세부 사항을 설명하기 때문에 관심이 있음을 발견했습니다. :) : stackoverflow.com/questions/1154446/…
jjmontes

1
@ Mokubai, 모든 정상적인 OS는 파일을 열 때 파일 길이를 가지고 있으며 플래그를 확인하고 오프셋을 끝으로 이동하면 다른 모든 부기에서 사라집니다. 전에 각각 을 에뮬레이트 O_APPEND하는 것은 다르지만 추가 시스템 호출 오버 헤드가 있습니다. (물론 다른 프로세스가 가능하기 때문에 작동하지 않을 것 입니다.)lseek()write()write()
ilkkachu
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.