teeコマンドでシェルスクリプトのパイプラインをデバッグする方法
インスタンス
以下は、processid関数が指定されたプロセス名のプロセスIDを問い合わせる簡単なスクリプトで、Linuxサーバーの管理では非常によく使われる関数です。
#! /bin/sh
processid()
{
ipid=$(ps -ef | grep -w $1 | grep -v grep | awk '{print $2}')
echo $ipid
}
case "$1" in
i)
processid $2
;;
*)
echo "parameter error... $1"
;;
esac
スクリプトを実行する
このスクリプトを実行して、zone9_log1 のプロセス ID を問い合わせると、次のような結果が得られます。
[wanng@localhost ~]$ . /a.sh i zone9_log1
130530 144391 144392
実際のzone9_log1プロセスのプロセスIDと比較するために、ps -ef | grep -w zone9_log1 | grep -v grep | awk '{print $2}' コマンドを別途実行すると、以下のような結果になります。
[wanng@localhost ~]$ ps -ef | grep -w zone9_log1 | grep -v grep | awk '{print $2}'
130530
質問事項
パイプラインの中間結果を出力するために、スクリプトにteeコマンドを追加し、調整したスクリプトは次のようになります。
processid()
{
ipid=$(ps -ef | grep -w $1 | tee out1 | grep -v grep | tee out2 | awk '{print $2}') | tee out3
echo $ipid
}
case "$1" in
i)
processid $2
;;
*)
echo "parameter error... $1"
;;
esac
再度スクリプトを実行すると、このパイプラインコマンドの中間結果を記録した out1 out2 out3 という3つのファイルがローカルに生成されます。スクリプトの実行結果と out1 out2 out3 ファイルの内容は次のとおりです。
[wang@localhost ~]$ . /a.sh i zone9_log1
130530 144885 144886
[wang@localhost ~]$ cat out1
wang 130530 1 0 Apr 24 pts/10 00:07:47 . /zone9_log1 . /zone9_log1.lua
wang 144885 109338 0 20:45 pts/8 00:00:00 /bin/sh . /a.sh i zone9_log1
wang 144886 144885 0 20:45 pts/8 00:00:00 /bin/sh . /a.sh i zone9_log1
wang 144888 144886 0 20:45 pts/8 00:00:00 grep -w zone9_log1
[wang@localhost ~]$ cat out2
wang 130530 1 0 Apr 24 pts/10 00:07:47 . /zone9_log1 . /zone9_log1.lua
wang 144885 109338 0 20:45 pts/8 00:00:00 /bin/sh . /a.sh i zone9_log1
wang 144886 144885 0 20:45 pts/8 00:00:00 /bin/sh . /a.sh i zone9_log1
[wang@localhost ~]$ cat out3
130530
144885
144886
[wang@localhost ~]$
理由
スクリプトを実行すると、デフォルトで新しいシェル(=新しいプロセス)が作成され、上記のスクリプトa.shは新しいシェル環境で実行されます。上記のテスト結果からわかるように、ps -ef | grep -w zone9_log1 コマンドの結果には、実行フット自身が起動したプロセスと問い合わせたい対象プロセスが含まれており、正確なプロセスIDを得るためにはスクリプト自身のプロセスをフィルタリングすればよく、調整後のスクリプトは以下のようになります(とりあえずteeコマンドの中間結果を出力しておきます)。
processid()
{
ipid=$(ps -ef | grep -w $1 | grep -v $0 | tee out1 | grep -v grep | tee out2 | awk '{print $2}') | tee out3
echo $ipid
}
case "$1" in
i)
processid $2
;;
*)
echo "parameter error... $1"
;;
esac
上記のprocessid関数 grep -v $0 は、スクリプトの名前 ( a.sh ) をフィルタリングする役割を果たします。
バリデート
再度スクリプトを実行すると、以下のようになります。
[wanng@localhost ~]$ . /a.sh i zone9_log1
130530
[wanng@localhost ~]$ cat out1
wanng 130530 1 0 Apr 24 pts/10 00:07:51 . /zone9_log1 . /zone9_log1.lua
wanng 146170 146168 0 21:11 pts/8 00:00:00 grep -w zone9_log1
[wanng@localhost ~]$ cat out2
wanng 130530 1 0 Apr 24 pts/10 00:07:51 . /zone9_log1 . /zone9_log1.lua
[wanng@localhost ~]$ cat out3
130530
上のテストからわかるように、最終的な出力は正しいです
概要
多層パイプラインはシェルスクリプトでは非常に一般的で、非常に簡単かつ効率的に使用できます。しかし、スクリプトに問題が発生した場合、デバッグが困難になります。
シェルスクリプトのパイプラインをデバッグするteeコマンドの詳細については、スクリプトハウスの他の関連記事に注目してください!上記は、シェルスクリプトのパイプラインをデバッグするteeコマンドの使用方法です。
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン