bashのパイプの詳しい使用方法についてmanを見て、今まで知らなかった使い方をまとめてみました。
●構文
[time [-p]] [ ! ] command [ [| or |&] command2 … ]
●time
timeを指定するとコマンド実行に要した経過時間がsystemとuserの内訳とともに表示されます。
$ time rpm -qa | tail kernel-firmware-2.6.32-431.17.1.el6.noarch xkeyboard-config-2.6-6.el6.noarch DeviceKit-power-014-3.el6.x86_64 : real 0m0.581s user 0m0.550s sys 0m0.032s
※-pオプションを指定するとPOSIXの出力フォーマットになります。
$ time -p rpm -qa | tail kernel-firmware-2.6.32-431.17.1.el6.noarch xkeyboard-config-2.6-6.el6.noarch DeviceKit-power-014-3.el6.x86_64 : real 0.59 user 0.55 sys 0.03
●exitステータスコード
通常は、パイプで指定した複数のコマンドの最後のコマンドのexitステータスコードが表示されます。
すべてのコマンドが0の場合のみ0が返るように挙動を変更する場合には、pipefailオプションを使用します。
$ rpm -ql aaa | head パッケージ aaa はインストールされていません。 $ echo $? 0 $ set -o pipefail $ rpm -ql aaa | head パッケージ aaa はインストールされていません。 $ echo $? 1
●標準エラーもパイプする
・”|”を指定した場合は、標準出力を後続のコマンド2の標準出力につなげる。
・標準エラーもパイプする場合は、”|&”を指定する。
※標準入出力、標準エラー
・どんなシェルも、基本的には同じ方法で標準入出力を処理する。
・呼び出される各プログラムには、端末用に設定された標準入出力、標準エラーが備えられていて、標準入力はキーボード、標準出力と標準エラーは画面、ウィンドウになっている。
例)
〇pipetest.sh #!/bin/bash source hello.sh source no_such_file.sh 〇通常のパイプを使用 $ source pipetest.sh | tee pipetest.log -bash: no_such_file.sh: そのようなファイルやディレクトリはありません hello! $ more pipetest.log hello! ・一つ目のコマンドの標準出力はパイプで後続のコマンドに渡している。 ・一つ目のコマンドの標準エラー出力はパイプされていないので、画面に出力される。 ・teeコマンドは、標準入力を読み込み、標準出力とファイルに書き込むので画面とログファイルに一つ目のコマンドの実行結果が出力される。 〇標準エラーもパイプで渡す $ source pipetest.sh |& tee pipetest.log hello! -bash: no_such_file.sh: そのようなファイルやディレクトリはありません $ more pipetest.log hello! -bash: no_such_file.sh: そのようなファイルやディレクトリはありません ・一つ目のコマンドは標準出力と標準エラーをパイプで後続のコマンドに渡しているので、画面には何も出力されない。 ・teeコマンドは、標準入力を読み込み、標準出力とファイルに書き込むので画面とログファイルに一つ目のコマンドの実行結果、エラーコメントが出力される。