`>`와`>>`는 어떻게 작동합니까?


9

rev파일을 시도한 다음 파이프로 연결 cat > same_file했지만 빈 파일로 바뀌 었습니다.

내가 시도 rev file.txt | cat > file2.txt && mv file.txt file2.txt;하는 동안 효과가있었습니다.

심지어 rev file.txt | cat >> file.txt;일했다.

그러나 내가 시도했을 때 rev file.txt | cat > file.txt실패했습니다.


다음 cat과 같이 남겨 둘 수도 있습니다 rev file.txt > file2.txt && mv file2.txt file.txt.. 이것은 불필요한 사용입니다cat . 그것을 남겨두면 여분의 프로세스를 스폰시킬 수 있습니다.
matega

답변:


19

이 경우 리디렉션 (> 및 >>)의 두 가지 방법 사이에서 알아야 할 기본 사항은 다음과 같습니다.

>

정보가 지시 된 위치를 재지 정하고 덮어 씁니다 . 파이프 "|"를 통해 정보를받는 동안 발생합니다.

>>

지정된 정보를 리디렉션하고 연결 합니다. 파이프 "|"를 통해 정보를받는 동안 발생합니다.

두 경우 모두 파일이 존재하지 않으면 대신 작성됩니다. 동일한 파일에서 정보를 다시 실행하면 ">>"에서만 정보가 연결됩니다. ">"를 사용하면 첫 번째 실행에서 수행 한 모든 작업을 덮어 씁니다.

그러나 출력 파일과 동일한 입력 파일을 사용할 때의 거래입니다. 이 경우 ">"를 사용하면 출력 파일이 "덮어 쓰기"이므로 "입력"부분을 구문 분석해야하는 정보가 제거됩니다. 그래서 :

rev file.txt | cat > file.txt

"슬로우 모션 설명"에서 실제로 일어나는 것은 다음과 같습니다.

  1. rev내용을 뒤집어 file.txt파이프로 보낼 준비
  2. rev파이프로 정보를 보내는 동안 파이프는 정보를로 직접 스트리밍합니다 cat.
  3. 상태 cat정보를 수신하고 자동으로에 적용 file.txt이 설정되었다.
  4. 모든 것이 동시에 일어나고 있기 때문에 여기서 키워드는 "while"입니다. 이 부분에 대해 더 깊이 이해하려면 아래 Emil의 훌륭한 의견을 참조하십시오.
  5. catrev전체 파일을 파이프 하기 를 기다리지 않습니다 . 정보의 첫 번째 부분이 도착하는 순간부터 시작됩니다. 즉, 사용한 기호에 따라에 대한 연결이 열립니다 file.txt.
  6. 이 경우 >> 대신 > 를 사용했기 때문에 셸은 출력 파일을 자르 므로 새 정보가 도착하기를 기다리는 동안 정보를 열고 지 웁니다 . >> 을 사용하면 연결을 열고 마지막 줄에서 새로운 정보를 기다릴 수 있습니다.file.txtfile.txt
  7. 정보가 이미 삭제 된 이후 file.txt> , rev그것의 일을하고 있기 때문에 아무 것도 얻을하려고 할 cat새로운 정보에 대한 준비를 삭제 다.

왜 위의 내용을 읽은 후에 다른 사람들이 일하는가? 이것 때문에:

rev file.txt | cat > file2.txt && mv file.txt file2.txt

여기에 정보를 다른 파일로 보내는 cat에 파이핑 중입니다 . 이 경우 처리 된 입력 파일 file.txt은 출력 파일과 다릅니다 file2.txt. 그 후 문자 그대로 전체 file2.txt를 덮어 쓰므로 file.txt모든 프로세스 cat가 삭제되었습니다. 기본적으로 전체 줄은 끝에서을 풀고 명령으로 덮어 쓰기 cp file.txt file2.txt때문에 동일한 작업을 수행하기 때문에 단순화 될 수 있습니다 .file2.txtrevmv

rev file.txt | cat >> file.txt

이 경우 정보를 동일한 파일에 연결 합니다. 따라서 해당 파일에 대한 연결 만 열지 만 단일 > 로 표시된 정보는 지워지지 않습니다 . 최종 결과는 원래 정보와 반전 된 정보 여야합니다.


5
cat에 의해 파일이 잘리지 않습니다. 파이프 라인의 명령이 시작 되기 전에 셸에서 잘립니다 .
Emil Jeřábek

맞습니다. 설명하기 쉬운 단어를 찾고있었습니다. OP가 쉘과 그 모든 것을 모르는 경우 설명하기가 약간 어렵 기 때문에. 가능한 한 "친절한"것으로 만들려고 노력합니다.
Luis Alvarado

1
글쎄, 그것은 그것이 쉘에 의해 수행되는 것이 중요하지 않지만, 당신이 제시하는 타이밍이 잘못되었다는 것입니다. 6 단계 rev file.txt | cat --bogus-option > file.txt에서는 잘리지 않지만 0 단계 에서는 잘립니다. cat이 파일을 열려고하지 않더라도 파일도 잘립니다.
Emil Jeřábek

@ EmilJeřábek 당신이 맞습니다. 동작 방식을 모르는 사용자는 명령 만 사용하여 단계별로 더 쉽게 작업 할 수 있습니다. 또한 귀하의 예제는 여전히 동일한 파일로 정보를 전송하므로 bash는 전체 줄을 읽고 출력을보고 여전히 열어서 자릅니다. 오류는 단순히 stderr이 stdout으로 출력하는 것입니다.
Luis Alvarado

4
입력 파일을 덮어 쓰는 유스 케이스를 위해 특별히 설계된 도구 를 포함 하는 환상적인 도구 모음 (패키지 저장소에서 사용 가능) 인 moreutils 도 참조하십시오 . 예를 들어, 해결 방법은 이름이 이미있는 경우에도 올바르게 작동합니다 . moreutilsspongerev file.txt >file2.txt && mv file2.txt file.txtrev file.txt | sponge file.txtfile2.txt
Daniel Wagner

9

쉘이 경로 재 지정을 볼 때, 관련된 명령을 실행하기 전에 관련 파일을 먼저 엽니 다. 따라서 할 때 :

foo file.txt | bar > file.txt

에 대한 재 지정 이 실행 되기 전에file.txt 잘려서 읽을 수 있습니다 . 참고로, 이것이 당신이 할 수없는 이유입니다. foofile.txt

sed 'blah' file.txt > file.txt

sed내부 편집 옵션이 왜 필요한 가요?

마지막으로 다음을 수행하십시오.

.. | cat > file.txt

이다 고양이의 쓸모없는 사용 이 읽는 중에 특히 그렇다면, file.txt에 이전은.

파일을 원래 위치로 되돌리려면 바로 가기가 없습니다 . 전체 편집에서 sed또는 awk트릭 을 사용할 수 있습니다 .


3

>출력을 다른 것으로 출력하는 리디렉터 (연산자)
입니다 (다음 명령 인 프린터 입력).

귀하의 경우 출력은 file file.txt로 이동합니다.이 파일이 이미 존재하면 작성되지 않으면 덮어 씁니다.

>>추가 연산자입니다 ( file.txt이미 존재하는 경우 출력이 파일의 끝에 추가됨). 파일이 존재하지 않으면 파일이 만들어지고 >(리디렉터) 와 동일한 결과가 새 파일에 기록됩니다 .


OP는 이것을 이해 한 것으로 보입니다. 혼란은 양쪽에있는 동일한 파일에서만 줄기 보인다 >>>운영.
bzlm

0

Ex 모드에서 Vim을 사용할 수 있습니다 :

ex -sc '%!rev' -cx file.txt
  1. % 모든 줄을 선택하십시오

  2. ! 명령을 실행

  3. x 저장하고 닫습니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.