- PR -

awk構文について

投稿者投稿内容
ビギナー
常連さん
会議室デビュー日: 2004/10/14
投稿数: 40
投稿日時: 2004-11-25 17:51
こんにちは。
awk構文を使ってプロセスのエラーチェックするシェルの作成にとりくんでいます。
             ↓
1 #!/usr/bin/sh
2 awk 'BEGIN{
3 a=`cat /usr/local/apache/logs/httpd.pid`
4 if [ $a -eq 0 ]
5 then
6 echo "エラーが発生しました。"
7 exit;
8 fi
9 }
10 {
11 ps -ef | grep http | awk '{print $2}'
12
13 if [ $2 -eq $a ]
14 then
15 echo
16 else
17 logger -p user.error "プロセスエラーが発生しました "
18 fi
19 }
20 END{
21 }

11行目から18行目までの処理をプロセスがあるぶんだけループを行いたくて、最初はfor構文を考えてましたがawk構文の参考書をみるとBEGIN、ENDを用いるとawkの一部分を繰り返し処理
出来ることが分かりました。それを参考にしまして上のように作ってみましたが、うまく実行
できません。私ではどの個所がおかしいのかわかりませんので、どなたかご理解いただける方のご指摘をよろしくお願い致します。
ほろりん
ベテラン
会議室デビュー日: 2004/11/24
投稿数: 98
お住まい・勤務地: あそこ
投稿日時: 2004-11-25 18:14
awkとshが混乱してますねぇ。

2行目 awk 'BEGIN{ はどこで閉じてますか?
3行目以降はsh? awk?
11行目にもawkがありますね?awkの中でawkを呼んでる?

2行目がなければ、ほとんどshのプログラム。
そうであれば、1行目にset -xを入れてみたり、要所要所でechoを使って変数の内容をだして見たりしてみなされ。
でも、最後にENDがあるし。

shの文法ををBEGIN{}やEND{}でくくったりしてますねぇ。
根本的に勘違いしてるというか駄目というか、これはまったくawkではないです。
直す以前の問題です。
awkが何かもう一度勉強なされたほうがいいです。


あと、psでみても毎回全部のプロセスが表示されたかなぁ?
とおい昔、同じようなことをしようとして、ときどきあるべきプロセスが表示されなかったような記憶が。(間違ってたらすいません)

[ メッセージ編集済み 編集者: ほろりん 編集日時 2004-11-25 18:23 ]

[ メッセージ編集済み 編集者: ほろりん 編集日時 2004-11-25 18:29 ]
komeyさんのメッセージをみながら一言。
pidが1桁や2桁だったらどういうことがおきるでしょうか?

[ メッセージ編集済み 編集者: ほろりん 編集日時 2004-11-25 19:07 ]
komey
ベテラン
会議室デビュー日: 2003/11/27
投稿数: 76
投稿日時: 2004-11-25 18:50
やりたいのは「プロセスのエラーチェックする」とありますが、このチェックは、httpd.pidファイルに記載された親httpdのプロセスIDがps -ef の出力結果として存在すれば良い、ということでしょうか。であればここまで難しくないと思いますよ。
※設定によってはhttpd.pidに子httpdのプロセスIDって書かれるのでしょうか。私の手元のApacheでは書かれていないので。。。

また、厳密に言うと、ゾンビプロセスなんかが発生することもあるので、ps -efで出力されたからと言って、正常に動作しているとは言い切れません。厳密にやるならシグナルを送ってみるのが良いでしょうね。(上位シェルでタイムアウトを検知する必要もありますが。)

あと、ps -ef | grep xxxを使うときの注意ですが、ps -ef | grep xxx | grep -v grepを忘れないように書くと良いです。でないと、grepコマンドがpsの結果として出力されてしまいます。
※もちろん、抽出したいプロセス名にgrepが付く場合もあるので、-vのあとの引数は場合に応じてかえる必要もあります。

また、httpd.pidがなくても、またhttpd.pidが空でもif [ $a -eq 0 ] は真になりません。これが真になるのはhttpd.pidに0が入っている場合です。そう考えるとあまり意味がないような気がします。


まずはやりたいことをひとつづつコマンドを打ってみてください。自動化はその後です。
ビギナー
常連さん
会議室デビュー日: 2004/10/14
投稿数: 40
投稿日時: 2004-11-26 12:05
こんにちは。

komeyさん、ほろりんさん。返信ありがとうございます。

awk文の参考書をもう一度チェックしたいと思います。
お二方の質問に今の私のレベルでは答えられないので参考書をチェックし
わかりしだいお二方の質問に書き込みをしたいと思います。
お二方のご指摘大変感謝いたします。もう一度最初からやり直します。


ビギナー
常連さん
会議室デビュー日: 2004/10/14
投稿数: 40
投稿日時: 2004-11-26 14:35
4行目の処理は例外処理を行おうとしたのですが、この書き方では例外処理にならない事に気ずきました。まずは例外処理から考え直したいと思います。
komey
ベテラン
会議室デビュー日: 2003/11/27
投稿数: 76
投稿日時: 2004-11-26 14:58
引用:

ビギナーさんの書き込み (2004-11-26 14:35) より:
4行目の処理は例外処理を行おうとしたのですが、この書き方では例外処理にならない事に気ずきました。まずは例外処理から考え直したいと思います。



いえ、例外処理はあくまで例外処理なので、例外処理より正常処理を先に書きましょう。よく言われるのは、プログラムでは正常処理2割、異常処理8割です。正常処理を書くほうがよっぽど楽ですよ。
正常処理がわかれば、どういう例外処理が必要かコメントもできますし。
※例えば if [ ! -f $PIDFILE ];then echo "File is not found.";exit 1;fiを入れた方がいい、とか。

まずは最も典型的なパターンを正常に終了させることが重要です。
ほろりん
ベテラン
会議室デビュー日: 2004/11/24
投稿数: 98
お住まい・勤務地: あそこ
投稿日時: 2004-11-26 15:05
まず、awkはshの構文の一部ではありません。
awkという独立した言語です。BEGIN{}やEND{}でshをくくったからといって
awkになるわけではありません。

awkの基本は、
$awk `{なんとかかんとか}' file
とするとfile内の1行を読み込んで{}内の「なんとかかんとか」を実行するということ。
fileの代わりに|で標準入力からよみこんでもいいです。
で「なんとかかんとか」はshとはまったく別のawk独自の文法があります。
shとはまったく違います。

file内の1行を読み込んで処理をする前にあらかじめ処理をしたい時はBEGIN{}
の中に処理をかきます。後処理をしたいときはEND{}で処理をいれます。
ENDとSTARTは必須ではありません。また、STARTだけということもできます。
http://www.kt.rim.or.jp/~kbk/
をあげておきます。リンク先のgawkとかの例を見てください。全然違うでしょ?
#自分が例を書こうと思ったが就業中でもあるし、(^^;;;めげたんでやめます。
------
pidでpsの結果をgrepするのがいいアイデアだとは思えません。
誤動作しまくりだと思いますよ。

[ メッセージ編集済み 編集者: ほろりん 編集日時 2004-11-26 15:17 ]
ビギナー
常連さん
会議室デビュー日: 2004/10/14
投稿数: 40
投稿日時: 2004-11-26 15:28
お二方の丁寧な解説ありがとうございます。

awk文や例外処理の基本的な書き方に対しての知識に欠けてました。

また11行目の処理から13行目の処理に移る時にこの書き方では$2の内容が
移動しないことが分かりかなりの基礎ミスに気づきました。

そこで↓のように改めます。

b=`$2`
if [ $b -eq $a ]


お二方の丁寧な解説と参考書の力でこの壁を乗り切りたいと思います。

スキルアップ/キャリアアップ(JOB@IT)