bashのパイプの使い方

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コマンドは、標準入力を読み込み、標準出力とファイルに書き込むので画面とログファイルに一つ目のコマンドの実行結果、エラーコメントが出力される。
関連記事の目次

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です