試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

リダイレクトとパイプのパターン集(後半)

リダイレクトとパイプのパターン集(前半)」の続き。

標準エラー出力のデータをファイルに書き出す

標準エラー出力はそのファイル記述子値(2)を用いて

$ [コマンド...] 2> [ファイル]

のように書き出す。標準出力と同時に同じファイルに書き出すには

$ [コマンド...] > [ファイル] 2>&1

とする。「2>&1」というのは

ファイル記述子2(標準エラー出力)の出力先をファイル記述子1(標準出力)の出力先と同じにする

という意味で、これが書かれたよりも左でファイル記述子1(標準出力)が書き出すように指定された先へファイル記述子2(標準エラー出力)から書き出すようにするという指定となり、両方を同じ出力先にする意味で用いる場合は「> [ファイル]」よりも右に書かなくてはならない。
なお、標準出力と標準エラー出力を別々のファイルに書き出すには

$ [コマンド] > stdout.txt 2> stderr.txt

のようにそれぞれ記述すればよいが、同じファイルに両方書き出そうとして同一のファイルを2回別々に指定してもダメ。

(正常に書き込まれない例)
$ [コマンド] > [ファイル] 2> [同一のファイル]

標準入力のファイル指定と標準出力のファイル指定を両方行う

標準入力のファイル指定を行った処理の結果(出力)をファイルに書き出す場合は

$ [コマンド] < [入力ファイル] > [出力ファイル]

と記述する。これは

$ ( [コマンド] < [入力ファイル] ) > [出力ファイル]

と考えると分かりやすいが、このように丸括弧を記述して実行することもできる。

出力の抑制

書き込み先を/dev/nullという特殊なデバイスファイルにすると、実際にはどこにも書き込まれずに出力が抑制される。

(標準出力のみ抑制・標準エラー出力のみ端末に表示される)
$ [コマンド] > /dev/null
(標準エラー出力のみ抑制・標準出力のみ端末に表示される)
$ [コマンド] 2> /dev/null
(標準出力と標準エラー出力の両方を抑制)
$ [コマンド] > /dev/null 2>&1

一番下の例では本記事の「標準エラー出力のデータをファイルに書き出す」と同様、「2>&1」の記述は同じ(端末ではなく)/dev/nullへ書き出すために「> /dev/null」より右に書く必要がある。

パイプの使用

コマンド行どうしを「|」記号でつなぐと、それらのプロセスがパイプで接続され、1つ目のプロセスの標準出力が2つ目のプロセスの標準入力となる。
パイプは複数接続でき、連続して出力を加工するのに使える。また、リダイレクトとの併用もできる。
「|」の右に書くコマンドは標準入力を処理するもの*1となり、そうでないものを指定しても最後のコマンドが普通に実行されるのと同じになって意味がない。

(パイプのみ・連続した例)
$ [コマンド1...] | [コマンド2...] | ...
(リダイレクトとの併用)
$ [コマンド1...] < [入力ファイル] | [コマンド2...] | ... | > [出力ファイル]
(意味のない例)
$ [コマンド...] | ls
(普通にlsを実行したときの結果が出るだけ)

そのままでは標準入力を処理しないものでも、「リダイレクトとパイプのパターン集(前半)」で扱ったような、標準入力をオプション指定の値として指定できるコマンドを用いる場合は

$ [コマンド1...] | [コマンド2] -i -

のような形でパイプを使用でき、具体例としては

$ seq -f http://[ホスト名]/[ディレクトリ...]/img/image%03g.jpg 100 | wget -i -

のようになる。

コマンドの出力を別のプロセスに渡しつつ端末にも表示する

(2010/4/29)「X11上の選択やクリップボードの内容を扱えるxselの使い方に関するメモ」で用いているが、下のように「| tee /dev/stderr」を挟むことで、あるコマンドの出力をパイプで別のプロセスに渡しつつ、最初のコマンドの出力も端末で表示するということができる。

$ [コマンド1...] | tee /dev/stderr | [コマンド2...]

関連記事:

*1:例としてはgrep,less,sed,bzip2,base64など