パイプに関するいくつかの有用な議論を(やや)学んだ後、例えば 終了状態を別のプロセスにパイプにインポートするそしてパイプラインの1つのプロセスが失敗した場合は終了します。最初のコマンドが失敗した場合でも、2番目のコマンドを開始することは避けられません。配管の必要な詳細を見逃していますか?
例えば
$ somecommand | tar -T - -czf /tmp/someProject.tar.gz
tar.gz
正しく機能せず、予想されるファイルのリストの代わりにいくつかのエラーメッセージのみを生成する場合は、ほとんど空のsomecommand
ファイルを生成しないでください。
答え1
はい、そこに配管に関するいくつかの基本的な詳細があります。
パイプラインのポイントは、複数のコマンドを並列に実行することです。これにより、すべてのデータを完全に保存する必要がなく、すべてのプロセスが同時に動作できるため、時間が節約されます。定義によれば、第1の命令が終了する前に第2の命令が開始されるので、第1の命令の終了状態がまだ使用できないことを意味する。
簡単な解決策は一時ファイルを使用することです。データ自体ではなくファイル名のリストだけを渡すため、ここではリポジトリは大きな問題ではありません。たとえば、
tmp=$(mktemp)
if somecommand > "$tmp"; then
tar -T - -czf /tmp/someProject.tar.gz < "$tmp"
fi
rm -f "$tmp"
または、実際にterdonが述べたようにtar
tarファイルを実行し、失敗した場合は削除します。somecommand
ただし、somecommand
失敗する前に部分的で重要なファイルのリストを作成すると、削除するアーカイブを作成するときに不要なI / Oが発生する可能性があります。
また、少なくともGNU tarには-T
コマンドラインオプションのように見える引用符と行をデフォルトで処理する機能があるので、不快なファイル名がある場合はこれを考慮するか検討することをお勧めします--verbatim-files-from
。--null
他のtar実装にも同様の問題がある可能性があります。 。
答え2
パイプ命令の性格を誤解したようです。
コマンドパイプラインからみんな並列で開始するコマンド(参照ここ例えば)。これは、実行中に生成された出力が読み取られるため、設定がtar
正常に完了するまで「待機」できない理由です。somecommand
tar
somecommand
この状況を軽減するために採用できるいくつかの解決策があります。
- 出力を
somecommand
一時ファイルにバッファリングし、終了ステータスtar
信号somecommand
が「成功」の場合にのみ実行してから削除します(保存スペースが十分な場合にのみ可能です)。 - @terdonが述べたように失敗した場合は、この
pipefail
オプションを使用して使用できないファイルを削除してください。tar.gz
somecommand
答え3
最も簡単な方法はを使用することです&&
。出力もキャプチャしたいので、まずリダイレクトしてから使用できます。
somecommand > somefile && tar -T somefile -czf /tmp/someProject.tar.gz
thensomecommand
以外のもので終了すると、実行は発生しません。exit 0
tar
答え4
パイプはこれを行う方法ではありません。この設定は、最初のコマンドが成功した場合にのみ&&
2番目のコマンドを実行します。
たとえば、「goober」というファイルがないディレクトリの場合:
$ ls goober | echo "done"
done
ls: cannot access 'goober': No such file or directory
$ ls goober && echo "done"
ls: cannot access 'goober': No such file or directory
あなたの例では:
$ somecommand && tar -T - -czf /tmp/someProject.tar.gz
somecommand
失敗するとtar
実行されません。