bash에서 두 명령의 출력을 결합하십시오.


81

이 두 명령의 출력을 결합 할 수 있습니까?

node ~/projects/trunk/index.js 
python ~/projects/trunk/run.py run

두 명령 모두 종료되지 않으므로 어떻게 해야할지 모르겠습니다.


3
프로그램이 완료되지 않으면 아마도 계속 출력을 씁니까? 그들의 출력으로 무엇을하고 싶습니까? 인터리브 라인, ...? 왜 이러고 싶니?
vonbrand

2
node 명령은 많이 출력하지 않지만 여전히 실행해야합니다. 파이썬 하나는 모든 요청을 출력합니다. 모두를 캡처하고 동일한 쉘 창에서 둘 다보고 싶습니다.
chovy

답변:


108

다음과 { }같이 그룹화하여 두 명령을 결합 할 수 있습니다 .

{ command1 & command2; }

지금까지, 당신이 파일로 그룹을 재 지정할 수 있습니다 (마지막 ;}필수) :

{ command1 & command2; } > new_file

당신은 분리하려는 경우 STDOUTSTDERR두 개의 파일에서 :

{ command1 & command2; } > STDOUT_file 2> STDERR_file

3
그들이 프로그램을 끝내지 않는다는 것은 중요하지 않습니다. 'tail -f'는 "완료"되지 않지만 여전히 작동하며 두 프로그램의 출력을 결합합니다. 둘 이상의 명령에서도 작동합니다. ^ c 종료하면 그룹화 된 명령 중 하나만 종료합니다. 그래도 상대방을 수동으로 죽여야합니다.
SuperMagic

5
마지막 부족한 것 같다 ;전에 }, 그것은 필수입니다!
Gilles Quenot

2
경고 : 이것은 전체 라인을 보존하지 않습니다! 라인이 부분적으로 분할되고 서로 섞여서 신뢰할 수없는 출력을 얻을 수 있습니다. 당신이 시도 할 수 있습니다 { yes {1..20} & yes {1..20}; } | grep -v '^1 2 3'라인이 끊어하지 않으면 아무것도 인쇄되지 않습니다 이상적으로 어떤을.
antak

8
차라리 사용하는 것 &&대신에 &! command1 & command2-백그라운드에서 command1을 실행하고 command2를 즉시 시작하여 두 명령을 병렬로 실행하고 출력을 엉망으로 만듭니다. command1 && command2-이것은 command1 (포 그라운드)을 실행 한 다음 command1이 성공하면 command2를 실행합니다.
DUzun April

1
@DUzun OP는 두 명령 모두 종료되지 않는다고 말 했으므로 솔루션을 사용하면 두 번째 명령이 실행되지 않습니다.
Zoey Hewll

50

보다 일반적으로 서브 쉘 또는 명령 그룹화를 사용하고 전체 그룹의 출력을 한 번에 리디렉션 할 수 있습니다.

암호:

( command1 ; command2 ; command3 ) | cat

{ command1 ; command2 ; command3 ; } > outfile.txt

이 둘의 주요 차이점은 첫 번째 프로세스는 하위 프로세스를 분할하고 두 번째 프로세스는 기본 쉘의 컨텍스트에서 작동한다는 것입니다. 변수 및 기타 환경 설정 및 성능 설정 및 사용과 관련하여 결과가 발생할 수 있습니다.

명령 그룹 (및 함수)에서 닫는 대괄호는 세미콜론이나 개행 문자로 내용과 분리해야합니다. 이 때문입니다 "}"자체의 명령 (키워드) 실제로, 하나처럼 취급해야합니다.


2
에서 리디렉션 ( )도 잘 작동합니다.
muru

2
}전혀 명령이 아닙니다. 예약어입니다. 동일합니다 {. 나는 보통 다음과 같은 목록을 작성합니다 { command1;command2;} > outfile.txt. 세미콜론 뒤에 공백을 추가 할 수 있지만 반드시 필요한 것은 아닙니다. 그래도 이후 공간 { 필요합니다.
와일드 카드

1
경고 : 이것은 전체 라인을 보존하지 않습니다! 라인이 부분적으로 분할되고 서로 섞여서 신뢰할 수없는 출력을 얻을 수 있습니다. 당신이 시도 할 수 있습니다 ( yes {1..20} & yes {1..20}; ) | grep -v '^1 2 3'라인이 끊어하지 않으면 아무것도 인쇄되지 않습니다 이상적으로 어떤을. (H / t에서 @antak로).
Ole Tange

3
때때로 command1이 ( command1 && command2 && command3 ) | cat
성공한

배경 진행으로 실행되는 ()중괄호와 마찬가지로 둥근 괄호를 선호 {}하고 그 결과를 처리해야합니다. 고양이에게 파이프`| cat`는 더 좋은 대안입니다.`> / dev / stdout`
DarkMukke

2

두 번째 명령이 종료되거나 실행되지 않았기 때문에 다른 제안은 효과가 없었습니다.

alias app () {
    nohup python ~/projects/trunk/run.py run 1>/tmp/log 2>&1 &
    echo $! > /tmp/api.pid
    nohup node ~/projects/trunk/index.js 1>/tmp/log 2>&1 &
    echo $! > /tmp/client.pid
    tail -f /tmp/log
}

1
참고 : 두 프로세스가 "동시에"파일에 쓰려고하면 I / O 오류가 발생할 수 있습니다.
Djizeus

2
2 개의 다른 로그 파일을 지정할 수 있으며이를 tail -f *.log동일한 로그 파일에 쓰는 2 개의 다른 프로세스의 문제로 본 적이 없지만.
chovy

@ chovy : 여기에 질문으로 문제를 쓸 수 있습니까 ... 유용합니다
Abdennour TOUMI

1
경고 : 이것은 전체 라인을 보존하지 않습니다! 라인이 부분적으로 분할되고 서로 섞여서 신뢰할 수없는 출력을 얻을 수 있습니다. command1 = yes {1..20}command2 =로 이것을 시도 yes {1..20}하고 | grep -v '^1 2 3'행이 끊어지지 않으면 이상적으로 인쇄하지 않는 결합 된 출력을 파이프 할 수 있습니다 . (H / t에서 @antak로).
Ole Tange

또한 데이터 양이 많으면 디스크가 가득 찰 수 있습니다.
Ole Tange

2

이 시도:

paste $(node ~/projects/trunk/index.js) $(python ~/projects/trunk/run.py run) > outputfile

1
'붙여 넣기'는 무엇을합니까?
chovy

@chovy, 여기 참조 : techrepublic.com/article/… 이 문맥에서 작동하는지 확실하지 않습니다.
FixMaker

나는 서로 옆에 기둥을 놓으려고하기 때문에 여기에 붙여 넣기가 적절하지 않다고 생각합니다
Bernhard

@ 베른하르트. 그러나이 REQ의 지정되지 않았
frogstarr78

@ frogstarr78 이것이 그가 원하는 것이 아닐 가능성이 높다고 생각하지만, 맞습니다. 지정되지 않았습니다.
Bernhard

1

지금까지 대부분의 솔루션은 부분 라인 문제를 잘못 처리합니다. 프로그램이 다음과 같다고 가정하십시오.

cmd1() {
    perl -e 'while(1) { print "a"x3000_000,"\n"}'
}
export -f cmd1
cmd2() {
    perl -e 'while(1) { print "b"x3000_000,"\n"}'
}
export -f cmd2

그것들을 병렬로 실행할 때 출력에 as의 전체 라인과 s의 전체 라인을 갖기를 원합니다 b. 당신이 할 수 없습니다 원하는 것은 as와 b같은 줄에 혼합의 ( tr -s ab반복 대체 a들 하나와 함께 a, 그래서 어떻게되는지하기 쉽습니다)

# This is bad - half lines are mixed
$ (cmd1 & cmd2 ) | tr -s ab
bababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababa
ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab

GNU Parallel을 대신 사용하면 as 또는 bs로 깔끔하고 완전한 라인을 얻을 수 있지만 결코 혼합되지 않습니다.

$ parallel --line-buffer ::: cmd1 cmd2 | tr -s ab
a
a
b
b
b
b
a

최신 버전의 GNU Parallel에서도 디스크를 가득 채우지 않아도됩니다. 위의 내용은 영원히 실행될 수 있습니다.


0

이미를 사용하고 있으므로 동시에node 시도해 볼 수 있습니다

여러 명령을 동시에 실행하십시오. 좋아 npm run watch-js & npm run watch-less하지만 좋아


0

여러 BASH 명령 출력을 한 줄로 결합하는 특별한 경우를 위해 각 명령을 차례로 실행하여 출력 사이의 줄 바꿈을 제거하는 방법이 있습니다.

(echo 'ab' && echo 'cd' && echo 'ef') | tr -d '\n'
>>> abcdef

실제 예를 들어, 아래 코드는 고정 된 두 바이트 문자열 사이에 ASCII 메시지를 포함합니다 (이 경우 인쇄 명령 작성).

#   hex prefix           encode a message as hex    hex suffix    | strip newline | hex to binary | (then, for example, send the binary over a TCP connection)
(echo '1b40' && echo "Test print #1" | xxd -p && echo '1d564103') | tr -d '\n'    | xxd -r -p     | nc -N 192.168.192.168 9100

(참고 :이 방법은 명령이 종료 된 경우에만 작동합니다. 종료되지 않은 명령의 표준 출력을 결합하려면 다른 답변을 참조하십시오.)


(1) 두 번째 명령의 (예상) 출력을 보여주십시오. (2) OP가이 기술을 사용하여 문제를 해결하는 방법을 보여주십시오.
스콧

1) 두 번째 명령의 출력은 ASCII가 아닌 바이너리이므로 표시하는 것이 유용하지 않습니다. 2) OP는 2013 년부터 현재까지 특정 문제를 해결했을 가능성이 높습니다. 이 질문은 이제 여러 Bash 명령의 stdout을 결합하는 것에 대한 효과적인 참조이므로 한 줄로 결합하는 기술은 여기에서 언급 할 수있는 유용한 "레시피"라고 생각합니다 (여기서 그것을 찾아서 찾을 수 없었기 때문에) 그것).
누가 복음
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.