명령 출력을 둘 이상의 명령으로 재 지정할 수 있습니까?


21

내가 아는 한, tee 명령을 사용하여 표준 출력을 화면과 추가 파일로 분할 할 수 있습니다.

command -option1 -option2 argument | tee file1 file2 file3 

이론적으로 일련의 명령을 만들 수 있도록 tee를 사용하여 파일 대신 명령으로 출력을 리디렉션 할 수 있습니까?


3
"출력 신호"가 의미하는 바를 설명하고 "명령 네트워크"를 생성하여 의미하는 바를 설명하십시오.
Janis

리눅스에서 각 명령에는 하나의 입력과 두 개의 출력이 있습니다. 그것들은 0 (입력), 1 (출력) 및 2 (오류 출력)로 표시됩니다. 티 명령이 1로 레이블 된 출력 만 분리한다는 것을 읽었 기 때문에 "출력 신호"라고 말했을 때 1을 생각하고있었습니다. 수학적 관점에서 보았지만, 나는 단순히 명령 적으로 나무를 생각해서 생각하기 때문에 일부 명령은 둘 이상의 자식 명령의 부모가 될 수 있습니다.
Abdul Al Hazred

설명해 주셔서 감사합니다. 유닉스에서는 특정한 의미를 지니고 있으므로이 단어를 사용하지 마십시오. 다시 감사합니다.
Janis

명령 행에서 man -k signal을 입력하여 UNIX 및 Linux에서이 핵심 개념의 특수한 의미를 학습하십시오. man kill은 시작하기에 좋은 페이지입니다.
Rob

또한 많은 사람들이 stdin stdout 및 stderr을 입력 또는 출력 '스트림'이라고합니다. 따라서 작은 데이터 강과 같은 스트림이 있습니다. 단어를 집합 적으로 설명하기 위해 단어를 잡는 것이 옳았지만 신호는 잘못된 단어 일뿐입니다.
Rob

답변:


25

명령 행에서 명명 된 파이프 ( http://linux.die.net/man/1/mkfifo )를 사용하고 명명 된 파이프 tee에서 명령을 읽을 수 있습니다.

mkfifo /tmp/data0 /tmp/data1 /tmp/data2
cmd0 < /tmp/data0 & cmd1 < /tmp/data1 & cmd2 < /tmp/data2 &
command -option1 -option2 argument | tee /tmp/data0 /tmp/data1 /tmp/data2

command완료 되면 tee명명 된 파이프가 닫히고, /tmp/dataN일반적으로 cmdN프로세스를 종료 할 각각의 EOF (읽기 0 바이트) 신호를 보냅니다 . 실제 예 :

$ mkfifo /tmp/data0 /tmp/data1 /tmp/data2
$ wc -l < /tmp/data0 & wc -w < /tmp/data1 & wc -c < /tmp/data2 &
$ tee /tmp/data0 /tmp/data1 /tmp/data2 < /etc/passwd >/dev/null
$ 61
1974
37

백그라운드 프로세스 때문에 쉘은 프로그램 출력 전에 프롬프트를 리턴했습니다. 세 인스턴스가 모두 wc정상적으로 종료되었습니다.


1
에서 bash는 , 당신은 할 수 입력의 안전한 주차장을 통해 /tmp/data/{0,1,2}. 그런 다음 bash에서 프로세스 대체를 사용 하고 mkfifo완전히 건너 뛸 수 있습니다.
Tobias Kienzler

2
/ dev / data0을 / tmp / data0로 변경하려고 할 수 있습니다. 또한 쉘 불가지론 적으로 질문에 답변 해 주셔서 감사합니다. 모두가 bash를 사용한다고 가정하는 것보다 도움이됩니다.
abonet

15

내가 제대로 이해한다면, 당신은 동등한 찾는 tee file1 file2 file3것이 아니라 쓰기 세 개의 파일에 동일한 데이터를보다 file1, file2그리고 file3, 당신이 파이프에 세 가지 명령에 동일한 데이터를 원하는 cmd1, cmd2그리고 cmd3즉,

… | ??? cmd1 cmd2 cmd3

다음과 같아야합니다

… | cmd1 &
… | cmd2 &
… | cmd3 &

한 번만 실행됩니다.

두 가지 방법이 있습니다.

Ksh93, bash 및 zsh는 프로세스 대체를 지원 합니다 . 이것은 파이프의 일반화로, 명령의 인수가 쓰여질 때 데이터를 명령의 입력으로 전달하는 파일이 될 수 있도록합니다 (읽을 때 명령에 의해 데이터 출력을 얻는 입력 변형도 있습니다) . 그건,

echo hello | tee >(cmd1)

인쇄 hello를 표준 출력과 부가가 실행 cmd1하여 hello입력으로.

당신의 입력을 복제 할 경우에 따라서 예를 들어, somecommand모두에 전달 cmd1하고 cmd2, 당신은 사용할 수 있습니다

somecommand | tee >(cmd1) | cmd2

쉘이 프로세스 대체를 지원하지 않으면 대신 명명 된 파이프를 사용할 수 있습니다. 작동 방식에 대해서는 Arcege의 답변 을 참조하십시오 . 명명 된 파이프는 파이프를 생성 및 삭제하고 수동으로 프로세스를 시작 및 동기화해야하기 때문에 프로세스 대체보다 편리하지 않습니다. 모든 쉘이 프로세스 대체를 지원하지는 않지만 완전히 이식 가능하다는 장점이 있습니다. 또한 프로세스 대체가 아닌 다른 시나리오에서도 사용할 수 있습니다.

일부 시스템에서 프로세스 대체는 내부적으로 명명 된 파이프를 사용합니다. 그러나 대부분의 시스템에서 파일 디스크립터를 나타내는 명명 된 파일에 의존 합니다 .


5
참조 pee에서 moreutils.
Stéphane Chazelas

프로세스 대체는 ksh88에 의해 도입되었습니다.
Stéphane Chazelas

6

적어도 에서는 mkfifo프로세스 대체를 사용하여 건너 뛸 수 있습니다 .

command -option1 -option2 argument | tee >(cmd1) >(cmd2) >(cmd3)

또는 Arcege의 예 를 채택

tee >(wc -l) >(wc -w) >(wc -c) < /etc/passwd >/dev/null

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