web-dev-qa-db-ja.com

パイプするtarはSTDERRとは別に-v詳細出力を保持

通常のtarコマンド

tar cvf foo.tar ./foo >foo.out 2>foo.err

3つの出力IOストリーム

  • データをfoo.tarにアーカイブする
  • sTDOUTへのファイル名のリスト(foo.outにリダイレクトされる)
  • sTDERRへのエラーメッセージ(foo.errにリダイレクトされる)

次に、ファイル名のリストを読む必要なく、エラーメッセージについてfoo.errを検査できます。

アーカイブデータで何かをしたい場合(netcatまたは特別な圧縮プログラムを介してそれをパイプします)、tarの-f -オプションを使用できます。

tar cvf - ./foo 2>foo.err | squish > foo.tar.S

ただし、tarの-v出力は明らかにSTDOUT(アーカイブデータが流れる場所)に移動できないため、tarはSTDERRに巧妙にSTDERRに書き込みます。

Kornシェルを使用して、アーカイブストリームを別のコマンドにパイプ処理しながら、-v出力をエラーメッセージとは別にキャプチャするコマンドを作成する方法はありますか。

12
RedGrittyBrick

システムが/dev/fd/nをサポートしている場合:

tar cvf /dev/fd/3 ./foo 3>&1 > foo.out 2>foo.err | squish > foo.tar.S

ksh(またはbashまたはzsh)のAT&T実装では、プロセス置換を使用して記述できます。

tar cvf >(squish > foo.tar.S) ./foo > foo.out 2>foo.err

今回は、シェルが3(通常は9以上)の代わりに使用するファイル記述子を決定することを除いて、まったく同じことを行っています。別の違いは、今回はtarではなくsquishの終了ステータスを取得することです。 /dev/fd/nをサポートしないシステムでは、一部のシェルがその機能のために名前付きパイプを使用する場合があります。

システムが/dev/fd/nをサポートしていない場合、またはシェルがプロセス置換に名前付きパイプを使用できない場合は、ここで 名前付きパイプを手動で処理する にする必要があります。

9

そのためには名前付きパイプを使用する必要があります。

まず、フォルダに1つ作成します。

mkfifo foo.pipe

次に、そのコマンドを使用します。

tar cvf foo.pipe ./foo >foo.out 2>foo.err & cat foo.pipe >foo.tar

通知:cat- partは、パイプから読み取ることができるgzipまたは何でもかまいません。

tar cvf foo.pipe ./foo >foo.out 2>foo.err & gzip -c foo.pipe >foo.tar

説明:

出力は名前パイプ(foo.pipe)、別のプロセス(catgzipnetcat)がそこから読み取ります。したがって、情報を得るためにstdout/stderrチャネルを失うことはありません。

6
chaos

GNU tar --index-fileオプション はうまく機能します:

tar cvf - ./foo 2>foo.err --index-file=foo.out | squish > foo.tar.S
5
Josh Kelley