2011-09-28 9 views
6

私は、次のターンしたい:私はstdoutに出力をミラーリングし、何かに結果に長さゼロのチェックを行うための望ましい結果を得るバッシュプロセス置換と終了コード

git status --short && (git status --short | xargs -Istr test -z str)

残念ながらティーの終了コードを返す

git status --short | tee >(xargs -Istr test -z str)

(常にゼロ)に近づきます。

置換されたプロセスの終了コードをエレガントに取得する方法はありますか?

は、[EDIT]

私は今のところ、以下で行くよ、それは二度同じコマンドを実行することができないが、より良い何かを請うようだ:

OUT=$(git status --short) && echo "${OUT}" && test -z "${OUT}"

+0

申し訳ありませんが、正確に何を達成したいですか?そのディレクトリにgitのステータスがあるかどうかを確認するだけですか? –

+0

はい、デプロイスクリプトの一部であり、ディレクトリが汚れている場合は0以外を終了する必要があります。 – jodell

答えて

5

はここを見て:

 
    $ echo xxx | tee >(xargs test -n); echo $? 
xxx 
0 
    $ echo xxx | tee >(xargs test -z); echo $? 
xxx 
0 

とここを見て:

 
    $echo xxx | tee >(xargs test -z; echo "${PIPESTATUS[*]}") 
xxx 
123 
    $echo xxx | tee >(xargs test -n; echo "${PIPESTATUS[*]}") 
xxx 
0 

それは?

は、私はしばらくの間、これに取り組んできましたPipe status after command substitution

+0

私はPIPESTATUSについて知らなかった、それは助けになった、感謝していた。 – jodell

+4

誰かが来て、ピペスタットがこれを解決すると思っている人は、そうではありません。エコー$? >(...)構造体の内部で移動されると、期待どおりに動作します。 PIPESTATUSバージョンを外部に移動すると、どちらの場合も0が返されます。 –

0
#!/bin/bash 
if read q < <(git status -s) 
then 
    echo $q 
    exit 
fi 
2

も参照してください、そして、シグナリングインライン化頼る以外、プロセス置換を有することを実行する方法がないと思われ、それができます本当に入力パイプのためだけに使用されるので、私はそれを拡張するつもりはありません。

しかし、bash-4.0では、このコンテキストでプロセス置換を置き換え、きれいな刈り取りを提供するために使用できるコプロセッサを提供しています。

あなたが提供する次のコード:いくつかの説明のために、今すぐ

coproc GIT_XARGS { xargs -Istr test -z str; } 
{ git status --short | tee; } >&${GIT_XARGS[1]} 
exec {GIT_XARGS[1]}>&- 
wait ${GIT_XARGS_PID} 

git status --short | tee >(xargs -Istr test -z str) 

を問わず、何かに置き換えることができ

coproc呼び出しが新しいコプロセスを作成し、 GIT_XARGS(任意の名前を使用できます)という名前を付け、中括弧でコマンドを実行します。コプロセッサー用に2つのパイプが作成され、stdinとstdoutがリダイレクトされます。コプロセスを含む適宜、STDINおよびSTDOUTを([0]が標準入力に書き込むSTDOUT、[1]から読み取る)、

  • ${GIT_XARGS_PID}処理するパイプを含む

    1. ${GIT_XARGS[@]}

      coprocコールは、2つの変数を設定しますPID。

    その後、コマンドが実行され、その出力が2番目のパイプ(つまりコプロセッサ 'stdin)に転送されます。暗号的に見える>&${GIT_XARGS[1]}部分は、通常の出力からfdへのリダイレクトである>&60のようなものに拡張されています。

    コマンドを中括弧で囲む必要があることに注意してください。これは、パイプラインによってサブプロセスが生成され、親プロセスからファイル記述子を継承しないためです。言い換えれば、以下:関連fdが生み出しteeプロセスを親プロセスに存在していないので、

    git status --short | tee >&${GIT_XARGS[1]} 
    

    は、無効なファイルディスクリプタのエラーで失敗します。それを中括弧に入れておくと、bashはパイプライン全体にリダイレクションを適用します。

    execコールは、コプロセッサにパイプを閉じるために使用されます。プロセス置換を使用すると、プロセスは出力リダイレクションの一部として生成され、リダイレクションがもはや効力を失った直後にプロセスへのパイプが閉じられました。コプロセッサのパイプの寿命は単一のリダイレクトを超えているため、明示的に閉じる必要があります。

    出力パイプを閉じると、プロセスはstdinでEOF状態になり、正常終了します。私たちはwaitを使って終了を待ってそれを刈り取る。 waitは、コプロセッサの終了ステータスを返します。

    この場合、killを使用してコプロセッサを終了することはできません。コプロセッサが終了ステータスを変更するためです。

  • +0

    teeは実際にはここでは使用されません。stdout netはstdoutにリダイレクトされます。 – weynhamz

    +0

    'exec {GIT_XARGS [1]}>& - '返信 '-bash:exec:{GIT_XARGS [1]}:私のために見つかりません。 –

    +0

    bash-4.0以降はありますか? –

    関連する問題