리눅스에서 두 개의 명명 된 파이프를 단일 입력 스트림으로 결합하는 방법


64

|Linux 의 파이프 ( ) 기능을 사용하여 표준 입력을 하나 이상의 출력 스트림에 전달할 수 있습니다.

tee하위 프로세스를 분리하기 위해 출력을 분할하는 데 사용할 수 있습니다 .

두 개의 입력 스트림을 결합하는 명령이 있습니까?

나는 이것에 대해 어떻게 갈 것인가? diff는 어떻게 작동합니까?

답변:


105

개인적으로 내가 좋아하는 것 (대부분의 Linux 배포판에서 표준 인 bash 및 기타 사항이 필요함)

세부 사항은 두 가지 출력 결과와 병합 방법에 따라 크게 달라질 수 있습니다 ...

출력에서 command1과 command2의 내용은 다음과 같습니다.

cat <(command1) <(command2) > outputfile

또는 두 명령이 나란히 보려는 동일한 데이터의 대체 버전을 출력하는 경우 (이는 snmpwalk와 함께 사용했습니다. 한 쪽은 숫자이고 다른 쪽은 MIB 이름입니다).

paste <(command1) <(command2) > outputfile

또는 두 개의 유사한 명령의 출력을 비교하려는 경우 (예 : 두 개의 다른 디렉토리에서 찾기)

diff <(command1) <(command2) > outputfile

또는 어떤 종류의 출력을 주문한 경우 병합하십시오.

sort -m <(command1) <(command2) > outputfile

또는 한 번에 두 명령을 모두 실행하십시오 (그러나 약간 스크램블 할 수 있음).

cat <(command1 & command2) > outputfile

<() 연산자는 각 명령에 대해 명명 된 파이프 (또는 / dev / fd)를 설정하여 해당 명령의 출력을 명명 된 파이프 (또는 / dev / fd 파일 핸들 참조)로 파이프하고 이름을 명령 행에 전달합니다. > ()와 동일합니다. 당신은 할 수 : command0 | tee >(command1) >(command2) >(command3) | command4동시에 예를 들어, 4 다른 명령 한 명령의 출력을 보낼 수 있습니다.


대박! 나는 bash의 맨 페이지를 많이 읽었지만 그 중 하나를 선택하지 않았다
Javier

2
리눅스 문서 프로젝트 의 [advanced bash scripting guide] ( tldp.org/LDP/abs/html/process-sub.html )에서 참조를 찾을 수 있습니다
brice

3
여러 개의 로그 파일 grep --line-buffered을 동시에 처리 grep하는 데 편리한 파이프 스루를 통해 인터리브 라인을 방지 할 수있었습니다 tail. stackoverflow.com/questions/10443704/line-buffered-cat
RubyTuesdayDONO

16

cat고릴라가 보여주는 것처럼 을 사용하여 두 개의 스팀을 다른 스팀에 추가 할 수 있습니다 .

또한 FIFO를 생성하고 명령의 출력을 지시 한 다음 다른 프로그램으로 FIFO에서 읽을 수도 있습니다.

mkfifo ~/my_fifo
command1 > ~/my_fifo &
command2 > ~/my_fifo &
command3 < ~/my_fifo

파일을 쓰거나 읽기만하는 프로그램이나 stdout / file 만 출력하는 프로그램과 다른 것을 지원하는 프로그램을 혼합하는 프로그램에 특히 유용합니다.


2
이것은 pfSense (FreeBSD)에서 작동하지만 허용되는 대답은 그렇지 않습니다. 감사합니다!
Nathan

9
(tail -f /tmp/p1 & tail -f /tmp/p2 ) | cat > /tmp/output

/tmp/p1그리고 /tmp/p2당신의 입력 파이프 /tmp/output이며, 출력입니다.


6
참고 : 양쪽 명령이 ()모든 라인에서 출력을 플러시 하지 않으면 (그리고 원자성에 대해 다른 모호한 POSIX 규칙), 고양이에 대한 입력에서 이상한 스크램블링으로 끝날 수 있습니다.
freiheit

앰퍼샌드 문자 대신 세미콜론을 사용하지 않아야합니까?
Samir

이 에픽 물건입니다
Mobigital

5

나는 이것을 위해 특별한 프로그램을 만들었습니다 : fdlinecombine

여러 파이프 (일반적으로 프로그램 출력)를 읽고 stdout에 줄 단위로 씁니다 (구분 기호를 재정의 할 수도 있음)


광고 된대로 작동합니다. 공개해 주셔서 감사합니다.
alexei

3

내가 이것을 위해 사용한 정말 멋진 명령은 tpipe입니다. 공통이 아니기 때문에 컴파일해야 할 수도 있습니다. 그것은 당신이 말하는 것을 정확하게하는 데 정말 좋습니다. 일반적으로 설치합니다. 매뉴얼 페이지는 http://linux.die.net/man/1/tpipe에 있습니다. 현재 나열된 다운로드는이 ​​아카이브 http://www.eurogaran.com/downloads/tpipe/에 있습니다.

이렇게 사용됩니다

## Reinject sub-pipeline stdout into standard output:
$ pipeline1 | tpipe "pipeline2" | pipeline3

3

여기서주의하십시오. 그것들을 catting하면 원하지 않는 방식으로 결과를 혼합하게 될 것입니다. 괜찮다면

꼬리 -f / tmp / p1 / tmp / p2> / tmp / output

작동합니다. 그것이 좋지 않으면 라인 버퍼링을 수행하고 완전한 라인 만 출력하는 것을 찾아야합니다. Syslog가이 작업을 수행하지만 다른 작업이 무엇인지 잘 모르겠습니다.

편집 : 버퍼링되지 않은 읽기 및 명명 된 파이프에 대한 최적화 :

/ mk / p1, / ​​tmp / p2, / tmp / p3을 "mkfifo / tmp / p N "으로 작성된 명명 된 파이프로 간주

tail -q -f / tmp / p1 / tmp / p2 | awk '{print $ 0> "/ tmp / p3"; 닫기 ( "/ tmp / p3"); fflush ();} '&

이제이 방법으로 다음과 같이 버퍼링되지 않은 파이프 "/ tmp / p3"출력을 읽을 수 있습니다 .

꼬리 -f / tmp / p3

작은 종류의 버그가 있습니다. 첫 번째 입력 파이프 / tmp / p1을 다음과 같이 "초기화"해야합니다.

echo -n> / tmp / p1

꼬리맞추기 위해 두 번째 파이프 / tmp / p2의 입력을 먼저 수락하고 / tmp / p1에 무언가가 올 때까지 기다리지 않습니다. 확실하지 않은 경우에는 / tmp / p1이 먼저 입력을받습니다.

또한 -q 옵션을하기 위해 필요한 꼬리 파일 이름에 대해 쓰레기를 인쇄하지 않습니다.


더 유용한이 될 것입니다 : "꼬리 -q -f / tmp를 / P1 / tmp를 / P2 | another_command" 는 선으로하고 -q 옵션을 사용하여 선을 이루어집니다로 다른 쓰레기를 인쇄되지 않습니다
readyblue

버퍼링되지 않은 파일 / 명명 된 파이프 사용의 경우 : tail -q -f /tmp/p1 /tmp/p2 | awk '{print $0 > "/tmp/p3"; close("/tmp/p3"); fflush();}' & 이제 / tmp / p3은 파이프로 명명 될 수 있으며 간단히 읽을 수 있습니다. tail -f /tmp/p3라인마다 UNBUFFERED = 행 단위 이지만 작은 종류의 버그가 있습니다. 테일이 두 번째 출력을 받아들이 기 위해서는 첫 번째 파일 / 명명 된 파이프를 먼저 초기화해야합니다. 따라서 echo -n > /tmp/p1모든 것이 원활하게 작동 해야합니다 .
readyblue

1

이를위한 최고의 프로그램은 lmerge입니다. freihart의 답변과 달리 라인 지향적이므로 두 명령의 출력이 서로를 방해하지 않습니다. 다른 솔루션과 달리 입력을 상당히 병합하므로 어떤 명령도 출력을 지배 할 수 없습니다. 예를 들면 다음과 같습니다.

$ lmerge <(yes foo) <(yes bar) | head -n 4

다음과 같은 출력을 제공합니다.

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