失敗した解決策1

失敗した解決策1

Linuxではパイプラインを実行できますか?

cmd1 | cmd2

このように:

  1. cmd2cmd1完全に完了するまで実行を開始しません。

  2. cmd1エラーがある場合はcmd2まったく実行されず、パイプラインの終了ステータスはですcmd1

たとえば、このパイプラインを作成する方法は次のとおりです。

false | echo ok

何も印刷せずにゼロ以外の状態を返しますか?


失敗した解決策1

set -o pipefail

パイプラインの終了状態はゼロではありませんが、cmd2失敗しても引き続き実行されます。cmd1

解決策2失敗

cmd1 && cmd2

これはパイプラインではありません。 I/O リダイレクトがありません。

解決策3失敗

mkfifo /tmp/fifo
cmd1 > /tmp/fifo && cmd2 < /tmp/fifo

ブロックされます。

最適ではないソリューション

touch /tmp/file
cmd1 > /tmp/file && cmd2 < /tmp/file

これはうまくいくようです。しかし、ここにはいくつかの欠点があります。

  1. I/O 速度が遅いディスクにデータを書き込みます。 (もちろん使えます一時ファイルシステムただし、これは追加のシステム要件です。)

  2. 一時ファイル名を慎重に選択する必要があります。それ以外の場合は、誤って既存のファイルを上書きする可能性があります。一時テーブル役に立つかもしれませんが、名前のないパイプは命名作業を完全に減らします。

  3. 一時ファイルを含むファイルシステムは、データ全体を保存するのに十分な大きさではない可能性があります。

  4. 一時ファイルは自動的にクリーンアップされません。

ベストアンサー1

出力サイズはわかりませんが、cmd1パイプは知っています。バッファサイズが制限されています。。特定の量のデータがパイプに書き込まれると、誰かがパイプを読み取るまですべての後続の書き込みがブロックされます(失敗したソリューション3に似ています)。

ブロックしないことが保証されるメカニズムを使用する必要があります。非常に大きなデータの場合は、一時ファイルを使用してください。それ以外の場合、データをメモリに保存する能力がある場合(最終的にはパイプのアイデアです)、次を使用してください。

result=$(cmd1) && cmd2 < <(printf '%s' "$result")
unset result

ここの結果はcmd1変数に保存されますresultcmd1成功したらcmd2、データを実行して提供しますresult。最後に、result設定を解除して関連メモリを解放してください。

注:以前はここで文字列(<<< "$result")を使用してデータを提供していましたが、cmd2Stéphane Chazelasはそれがbash望ましくない一時ファイルを生成することを観察しました。

コメントの質問に答えてください。

  • はい、コマンドをリンクできますランダム:

    result=$(cmd1) \
    && result=$(cmd2 < <(printf '%s' "$result")) \
    && result=$(cmd3 < <(printf '%s' "$result")) \
    ...
    && cmdN < <(printf '%s' "$result")
    unset result
    
  • いいえ、上記のソリューションは、次の理由でバイナリデータには適していません。

    1. コマンド置換は$(...)末尾の改行を食べます。
    2. \0コマンド置換の結果では、NUL文字()の動作は指定されていません(たとえば、Bashはこれを削除します)。
  • はい、バイナリデータに関連するこれらすべての問題を回避するには、次のエンコーダbase64(またはuuencodeNUL文字と末尾の改行のみを処理する自家製エンコーダ)を使用できます。

    result=$(cmd1 > >(base64)) && cmd2 < <(printf '%s' "$result" | base64 -d)
    unset result
    

    ここでは、終了値を変更せずに>(...)維持するためにプロセス置換()を使用する必要があります。cmd1

つまり、データがディスクに書き込まれないようにするのはかなり面倒です。中間の一時ファイルがより良いソリューションです。バラよりスティーブンの答えこれは、これに対するほとんどの懸念を解決します。

おすすめ記事