bashの2つのコマンドからの出力を結合する


81

これらの2つのコマンドからの出力を結合することは可能ですか?

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

どちらのコマンドも終了しないので、これを行う方法がわかりません。


3
プログラムが終了しない場合、おそらく継続的に出力を書き込みますか?あなたは彼らの出力で何をしたいのですか?インターリーブライン、...?なぜこれをしたいのですか?
フォンブランド

2
nodeコマンドはあまり出力しませんが、実行する必要があります。Python 1はすべてのリクエストを出力します。両方をキャプチャし、同じシェルウィンドウで両方を監視したいと思います。
チョビー

回答:


108

次のようにグループ化することにより、2つのコマンドを組み合わせることができます{ }

{ command1 & command2; }

これまでは、グループをファイルにリダイレクトできます(最後の;}は必須です)。

{ command1 & command2; } > new_file

あなたは、分離したい場合STDOUTSTDERR2つのファイルに:

{ command1 & command2; } > STDOUT_file 2> STDERR_file

3
プログラムが終了しなくても構いません。「tail -f」も「終了」しませんが、これは機能し、両方のプログラムの出力を結合します。3つ以上のコマンドでも機能します。^ cを終了すると、グループ化されたコマンドの1つだけが強制終了されます。ただし、相手を手動で殺す必要があります。
-SuperMagic

5
あなたは;前の最後を欠いているようだ}、それは必須です!
ジルケノ14

2
警告:これは行全体を保存しません!行が途中で分割され、互いに混同されると、信頼性の低い出力が得られます。{ yes {1..20} & yes {1..20}; } | grep -v '^1 2 3'行を分割しない場合、理想的には何も印刷しないこれを試すことができます。
antak

8
私はむしろ&&代わりに使用したいと思います&command1 & command2-これはcommand1をバックグラウンドで実行し、command2をすぐに開始します。したがって、両方のコマンドを並行して実行し、出力を台無しにします。 command1 && command2-これはcommand1(フォアグラウンドで)を実行し、command1が成功した場合、command2を実行します。
-DUzun

1
@DUzun OPはどちらのコマンドも終了しないと言ったので、ソリューションでは、2番目のコマンドは実行されません
ゾーイヒュール

50

より一般的には、サブシェルまたはコマンドのグループ化を使用して、グループ全体の出力を一度にリダイレクトすることができます。

コード:

( command1 ; command2 ; command3 ) | cat

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

2つの主な違いは、最初のプロセスが子プロセスを分割し、2番目のプロセスがメインシェルのコンテキストで動作することです。これは、パフォーマンスと同様に、変数および他の環境設定の設定と使用に関して結果をもたらす可能性があります。

コマンドのグループ化(および関数)の閉じ括弧は、セミコロンまたは改行のいずれかでコンテンツから分離する必要があることを忘れないでください。これは、"}"実際にはそれ自体がコマンド(キーワード)であり、1つのように処理する必要があるためです。


2
からのリダイレクト( )も正常に機能します。
ムル

2
}コマンドではありません。予約語です。同じことが当てはまります{。私は通常、そのようなリストを次のように書きます{ command1;command2;} > outfile.txt。セミコロンの後にスペースを追加できますが、必須ではありません。ただし、その後のスペース{ 必要です。
ワイルドカード

1
警告:これは行全体を保存しません!行が途中で分割され、互いに混同されると、信頼性の低い出力が得られます。( yes {1..20} & yes {1..20}; ) | grep -v '^1 2 3'行を分割しない場合、理想的には何も印刷しないこれを試すことができます。(H / tから@antak)。
オレ丹下

3
command1が成功した場合にのみcommand2を実行したい場合があります( command1 && command2 && command3 ) | cat
。– DUzun

バックグラウンド進行として実行される()中括弧{}と同様に、丸括弧を好むので、そこからの出力を処理する必要があります。猫にパイプする `| cat`は、よりよい代替次いで`>の/ dev / stdout`ある
DarkMukke

2

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
注:2つのプロセスが「同時に」ファイルに書き込もうとすると、I / Oエラーが発生する可能性があります。
Djizeus

2
2つの異なるログファイルを指定できますtail -f *.logが、同じログファイルに書き込む2つの異なるプロセスの問題としてこれを見たことはありませんが。
チョビー

@chovy:uは疑問として、あなたの問題を書くことができ、ここで、それは便利です...
Abdennour TOUMI

1
警告:これは行全体を保存しません!行が途中で分割され、互いに混同されると、信頼性の低い出力が得られます。これをcommand1 = yes {1..20}command2 =で試してみて、理想的には行が壊れていない場合は何も印刷しないyes {1..20}結合出力をパイプで送ることができ| grep -v '^1 2 3'ます。(H / tから@antak)。
オレ丹下

さらに、データ量が多い場合、ディスクがいっぱいになる可能性があります。
オレ丹下

2

これを試して:

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

1
「貼り付け」とは何ですか?
チョビー

@chovy、こちらをご覧ください:techrepublic.com/article/… このコンテキストで機能するかどうかはわかりません。
FixMaker

私はお互いに次の列を置くことを意図しているようペーストは、ここで適切ではないと思います
ベルンハルト

@Bernhard確かに。しかし、それは
要求に

@ frogstarr78これは彼が望んでいることではないだろうと思うが、あなたは正しい、それは明記されていない。
ベルンハルト

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。何をではないしたいことはあるaのとb同じ行に混合秒(tr -s ab繰り返し置き換えasが単一で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コマンド出力を1行に結合する特別な場合について、各コマンドを順番に実行し、出力間の改行を削除するレシピを次に示します。

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

実際の例として、以下のコードは2つの固定バイト文字列の間に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

(注:このメソッドは、コマンドが終了する場合にのみ機能します。終了しないコマンドからstdoutを組み合わせるには、他の回答を参照してください。)


(1)2番目のコマンドの(予想される)出力を表示してください。(2)OPがこの手法を使用して彼の問題を解決する方法を示してください。
スコット

1)2番目のコマンドの出力は非ASCIIバイナリであるため、表示するのは有用ではありません。2)OPは2013年から現在までに彼の特定の問題を解決した可能性が高い。この質問は現在、複数のBashコマンドの標準出力を結合する際の参照になっているので、それらを1行で結合する手法はここで言及するのに役立つ「レシピ」であると思います(私はここを探して見つけられなかったのでそれ)。
ルーク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.