web-dev-qa-db-ja.com

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

これら2つのコマンドからの出力を組み合わせることが可能ですか?

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

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

98
chovy

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
}
2
chovy

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

{ command1 & command2; }

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

{ command1 & command2; } > new_file

2つのファイルでSTDOUTSTDERRを分離する場合:

{ command1 & command2; } > STDOUT_file 2> STDERR_file
124
Gilles Quenot

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

コード:

( command1 ; command2 ; command3 ) | cat

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

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

コマンドのグループ化(および関数)の閉じ角かっこは、セミコロンまたは改行で内容と区切る必要があることを忘れないでください。それの訳は "}"は実際には独自のコマンド(キーワード)であり、1つのコマンドと同じように扱う必要があります。

56
j9s

これまでのほとんどの解決策は、部分的な線の問題をうまく処理していません。プログラムが次のとおりであると仮定します。

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の完全な行とそれに続くbsの完全な行を含める必要があります。あなたがすることnot欲しいのは、asとbsが同じ行で混合することです(tr -s abは、繰り返しasを1つの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の新しいバージョンは、ディスクがいっぱいになるのを回避します。上記は永久に実行できます。

3
Ole Tange

これを試して:

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

複数の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を組み合わせる方法については、他の回答を参照してください。)

2
Luke

既にnodeを使用しているので、試してみてください 同時に

複数のコマンドを同時に実行します。お気に入り npm run watch-js & npm run watch-lessしかし、より良い。

0
Tamlyn