나는 다음 명령을 가지고 있습니다 :
cat somefile >file1 >file2
file1
이 명령을 실행한 후에는 왜 아무것도 없는지 이해할 수 없습니다 . 첫 번째 파일( )의 출력이 있어야 somefile
하지만 그 안에는 아무것도 없습니다.
내 출력을 복사하거나 쓰지 않는 이유를 설명해 주시겠습니까 somefile
? ( file2
내 출력은 포함되어 있지만 file1
아무것도 포함되어 있지 않음)
답변1
쉘 리디렉션이 작동한다고 생각하는 방식과 실제로 작동하는 방식에는 차이가 있다고 생각합니다.
zsh
출력이 여러 번 리디렉션될 때 표시되는 것과 유사한 동작을 구현하는 경우 를 제외하고 tee
, 쉘의 출력을 여러 번 리디렉션할 수 없으며 지정한 모든 위치로 리디렉션될 것으로 기대할 수 없습니다. 대신, 마지막 위치로만 리디렉션됩니다 file2
. 귀하의 경우 Chaos의 답변은 I/O 리디렉션이 작동하는 방식에 대한 좋은 설명을 제공합니다.
당신이 정말로 하고 싶은 일은:
$ cat example.txt | tee file1 > file2
tee
표준 입력에서 읽고 여러 파일 설명자에 쓰는 프로그램입니다. 그 중 하나는언제나표준 출력. 따라서 우리는 를 사용하여 tee
출력을 작성한 file1
다음 표준 출력을 file2
.
또한 의견에서 제안한 대로 원하는 것을 달성하는 더 좋은 방법은 다음과 같습니다.
$ tee file1 < example.txt > file2
이 접근 방식의 장점은 stdin
파이프를 통해 읽으려고 시도하는 대신 리디렉션된다는 것입니다. 이는 이제 쉘이 하나의 프로세스를 덜 생성해야 함을 의미합니다. 소위 말하는 '고양이의 쓰레기 이용'도 해소됩니다. 배치하여 출력 리디렉션뒤쪽에입력 리디렉션을 사용하면 입력 파일을 열 수 없는 경우 출력 파일이 손상되는 것을 방지할 수 있습니다.
답변2
당신이 하는 일은I/O 리디렉션. >file
귀하의 경우에는 표준 출력(stdout)을 file
두 번 리디렉션했습니다. 쉘은 동일한 출력의 리디렉션을 여러 번 처리하지 않습니다.
이 경우:
cat somefile >file1 >file2
쉘은 cat somefile
명령( )을 실행하기 전에 리디렉션을 처리합니다. 이는 >
파일 내용을 덮어썼기 때문에 파일 길이가 0으로 잘린다는 의미입니다. 쉘이 이 명령을 실행하려면 파일이 비어 있어야 합니다. 이는 >
두 가지 리디렉션을 통해 수행됩니다.
이제 두 번째( >file2
)가 첫 번째( >file1
)를 재정의합니다. 쉘이 발생 순서대로 리디렉션을 처리하기 때문입니다. 그래서 마지막은 효과적으로 사용하는 것입니다. 따라서 의 출력은 cat somefile
리디렉션되어 file2
길이 file1
가 0으로 잘립니다.
tee
표준 출력을 여러 프로세스/파일로 리디렉션하는 방법은 다음과 같습니다.
cat somefile | tee file1 file2 file3 fileX
그러면 내용이 표준 출력으로 인쇄됩니다.그리고인수로 제공된 모든 파일에 적용됩니다.
답변3
zsh
~와 함께다양한 옵션설정(기본적으로)을 사용할 수 있습니다:
cat somefile >file1 >file2
이 경우 zsh
뒤에서 비슷한 작업을 수행합니다. tee
심지어:
<somefile >file1 >file2
기본적으로 $NULLCMD
명령 리디렉션이 없을 때 실행되는 명령은 바로 그 명령입니다 cat
.
답변4
cat somefile >file1 >file2
리디렉션이 없으면 cat somefile
stdin은 쉘에서 상속됩니다. 일반적으로 쉘의 stdin은 닫혀 있지 않으며 이미 파일을 가리키고 있습니다. 터미널은 또한문서. 표준 출력이 터미널인 대화형 셸에서 실행하면 cat somefile
의 출력이 cat
터미널로 이동합니다. 일반적으로 쉘의 표준 출력은 관련되지 않은 다른 출력일 수 있으며 cat
어쨌든 상속됩니다.
그것이 cat somefile >file1
하는 일은 쉘을 만드는 것입니다:
- 쓰기 위해 열어보고
file1
(파일이 아직 없으면 생성) 0 크기로 잘라냅니다(가능한 경우). 이는cat
시작하기 전에 발생합니다. file1
미래의 표준 출력으로 설정되어 있으므로 사용됩니다cat
.cat
file1
바꾸다cat somefile >file1
리디렉션 없이 무엇을 사용합니까? ( 터미널에도 쓰고 싶지 않습니까 ?)
리디렉션 리디렉션. :) 현재 방향은 "to 터미널"이고 새 방향은 "to file1
"입니다. 새로운 방향을 잡아라바꾸다현재 방향과 새 방향이 현재 방향이 됩니다.
쉘은 왼쪽에서 오른쪽으로 리디렉션을 구문 분석합니다. cat somefile >file1 >file2
케이싱 인 경우 >file1
먼저 위와 같이 진행하세요. 그런 다음 처리합니다>file2
같은 방법으로: 파일을 열고 자르고 file2
미래를 위해 "to"를 설정합니다.cat
바꾸다현재 방향은 이미 'to file1
'입니다. 이렇게 하면 "to file2
"가 "to"를 대체 file1
하고 현재 상태가 됩니다. 마치 file1
지금 "to"가 "to the Terminal"로 대체된 것과 같습니다.
더 많은 리디렉션을 추가할 수 >fileN
있으며 각 리디렉션은 설명된 대로 처리됩니다. 모두가 성공한다고 가정하면 마지막에 서있는 사람이 승리합니다. 귀하의 경우에는 >file2
승리하십시오 .
모든 리디렉션이 처리되면 cat
시작하십시오. 표준 출력 cat
으로 보이지만 어떤 방식으로든 관련되어 있다는 사실 file2
조차 알지 못합니다 . file1
잘림은 쉘에 의해 구문 분석되었으며 그것과 아무 관련이 없기 file1
때문에 "부작용"입니다 .>file1
cat
이 메커니즘을 사용하여 하나 이상의 파일을 생성/자르기할 수 있습니다. : >file1 >file2 …
파일을 자르려는 시도가 이루어집니다. :
작동하지 않으며 표준 출력도 사용하지 않습니다. 셸이 시작하기 전에 리디렉션을 처리할 때 생성 및 잘림이 발생합니다 :
.
이것이 sh
호환되는 쉘에서 출력 리디렉션이 작동하는 방식입니다. MULTIOS 옵션 zsh
(참조이 다른 답변)은 다릅니다. 첫 번째 리디렉션은 이전 방향(예: 터미널)을 대체하지만 연속 리디렉션은다음에 추가방향. 뒤에서 어떻게 일어나는지는 자세히 설명하지 않겠습니다. 나는 단지 당신이 관찰한 동작이 sh
각각이 처리된다는 사실(또는 호환 가능한 쉘에서) 에서 비롯된다는 점을 지적하고 싶었습니다.>fileN
독립적으로, 차례로; 그러나 zsh
단일 장치처럼 여러 출력을 리디렉션하는 모드가 있습니다.