- PR -

awk構文について

投稿者投稿内容
komey
ベテラン
会議室デビュー日: 2003/11/27
投稿数: 76
投稿日時: 2004-11-26 16:40
引用:

ほろりんさんの書き込み (2004-11-26 15:05) より:

pidでpsの結果をgrepするのがいいアイデアだとは思えません。
誤動作しまくりだと思いますよ。



"http"でps -efの結果をgrepして、抽出行からpid列を抜き出して、親httpdのpidと一致するpidがあるかどうかを調べている、が正確なところですよね。プロセスの生死を判断するのが目的であればこれはこれでお手軽だとは思うのですが、ほろりんさんならどういう方法を取られますか?簡単な方法があれば是非教えていただきたいと思います。
※HTTPでアクセスするのが一番良いのでしょうが、タイムアウトのことを考えると結構面倒ですよね。

また、誤動作とありますが、どういう誤動作を懸念されているでしょうか。ps -efの結果をpid自体でgrepしているわけではないので、pidが1桁でも2桁でもさほど問題はないような気もしますけど、いかがでしょうか。pid自体でgrepするとしても、awkを使わずに" $pid "のように抽出条件の前後にスペースを入れるとか、awkを使ってさらにegrepと正規表現を使って行頭と行末を意識するとか、やりようはそれなりにあるかなと。。。

PIDでプロセス生死を判断するシェルスクリプトは結構見るので、これはこれで汎用的な方法かなーと思ってました。

ビギナー
常連さん
会議室デビュー日: 2004/10/14
投稿数: 40
投稿日時: 2004-11-26 17:51
こんばんは。
途中経過報告でございます。

1 #!/usr/bin/sh
2 awk 'BEGIN{
3 pid=`cat /usr/local/apache/logs/httpd.pid`
4 if [ ! -f $pid ]
5 then
6 echo "File is not found"
7 exit1;
8 fi
9 }
10 {
11 ps -ef | grep http | grep -v grep | awk '{print $2}'
12 ps=`$2`
13 if [ $ps -eq $pid ]
14 then
15 echo
16 else
17 logger -p user.error "プロセスエラーが発生しました "
18 fi
19 }
20 END{
21 }


まだこの文ではsh文とawk文が混ざったままですので、きちんとしたawk文にしたいと思います。

そして参考書にもBEGINとENDは省略できると載ってました。その部分も変更したいと思います。

私がBEGINとENDを用いたのは11行目から18行目の部分を繰り返し処理したい為に無理やりに用いてしまいました。
for文を使わずに繰り返し処理を行いたかったからです。

改めまして質問なのですがfor文やwhile文を用いずにawk文だけで繰り返し処理をする事は可能でしょうか?
佐々木
大ベテラン
会議室デビュー日: 2003/03/30
投稿数: 121
投稿日時: 2004-11-26 18:17
引用:

1 #!/usr/bin/sh
2 awk 'BEGIN{
3 pid=`cat /usr/local/apache/logs/httpd.pid`



これはシェルじゃなくてawkのスクリプトとして書いた方が自然だと思いますよ。

1行目を
コード:
#!/usr/bin/awk -f


にして、後はawkのスクリプトをガンガン書く!
komey
ベテラン
会議室デビュー日: 2003/11/27
投稿数: 76
投稿日時: 2004-11-26 18:25
引用:

ビギナーさんの書き込み (2004-11-26 17:51) より:

私がBEGINとENDを用いたのは11行目から18行目の部分を繰り返し処理したい為に無理やりに用いてしまいました。
for文を使わずに繰り返し処理を行いたかったからです。

改めまして質問なのですがfor文やwhile文を用いずにawk文だけで繰り返し処理をする事は可能でしょうか?




for文やwhile文を使わない理由があれば教えていただけないでしょうか。

また、ビギナーさんが意図されているもので、繰り返し処理を行う必要がよくわかりません。#理解力がなくてすみません。

コマンドを羅列すると、、、、
# cat /usr/local/apache/logs/httpd.pid
で出力結果を記憶しますよね。
# ps -ef | grep "httpd" | grep -v "grep"
で出力結果の第2列目のプロセスIDと最初のhttpd.pidとが完全一致するものがあればOK、なければNG。意図されていることはこれとは違いますか?
ほろりん
ベテラン
会議室デビュー日: 2004/11/24
投稿数: 98
お住まい・勤務地: あそこ
投稿日時: 2004-11-26 19:05
>komeyさん
引用:


"http"でps -efの結果をgrepして、抽出行からpid列を抜き出して、親httpdのpidと一致するpidがあるかどうかを調べている、が正確なところですよね。プロセスの生死を判断するのが目的であればこれはこれでお手軽だとは思PIDでプロセス生死を判断するシェルスクリプトは結構見るので、これはこれで汎用的な方法かなーと思ってました。


Komeyさんに同意します。httpでgrepしてるのを見落としました。pidを取り出していたからこれだけでgrepしていたかと勘違い。汗顔の至り。

にしても、ビギナーさんは頑固ですね。。。。。。ふぅ。
awk '{print $2}'以外のところでawkを使う必然性がない。
2,9,10,19〜21の行を削除してshになさい。
これならまだ見れる。
RAHMEN
会議室デビュー日: 2004/11/26
投稿数: 1
投稿日時: 2004-11-26 19:22
ご参考になるかはわかりませんが、
HTTP_PS=`ps -ef |grep httpd |grep -v grep |wc -l`
とすれば、プロセス数をシェル変数として取り出せると思います。

「この変数がしきい値より小さい時に、エラーメッセージを出す」
とするとラクな感じがします。
komey
ベテラン
会議室デビュー日: 2003/11/27
投稿数: 76
投稿日時: 2004-11-26 19:24
引用:

ビギナーさんの書き込み (2004-11-26 17:51) より:

11 ps -ef | grep http | grep -v grep | awk '{print $2}'
12 ps=`$2`
13 if [ $ps -eq $pid ]
14 then
15 echo
16 else
17 logger -p user.error "プロセスエラーが発生しました "
18 fi



よく見ると、このままだと子httpdのPIDと親httpdのPIDは必ず一致することはないので、正常時であっても必ずエラーメッセージが発生しますよ。
15行目のechoの後にexit 0で抜けるようにして、elseはなし、ループが終了したところでエラーを出力してexit 1が妥当なところでしょう。
個人的には最後の最後にエラー終了するのは好きではないなので、処理を反転させますが。。。

[ メッセージ編集済み 編集者: komey 編集日時 2004-11-26 19:25 ]
ビギナー
常連さん
会議室デビュー日: 2004/10/14
投稿数: 40
投稿日時: 2004-11-26 19:48
引用:

komeyさんの書き込み (2004-11-26 18:25) より:
引用:

ビギナーさんの書き込み (2004-11-26 17:51) より:

私がBEGINとENDを用いたのは11行目から18行目の部分を繰り返し処理したい為に無理やりに用いてしまいました。
for文を使わずに繰り返し処理を行いたかったからです。

改めまして質問なのですがfor文やwhile文を用いずにawk文だけで繰り返し処理をする事は可能でしょうか?




for文やwhile文を使わない理由があれば教えていただけないでしょうか。

また、ビギナーさんが意図されているもので、繰り返し処理を行う必要がよくわかりません。#理解力がなくてすみません。

コマンドを羅列すると、、、、
# cat /usr/local/apache/logs/httpd.pid
で出力結果を記憶しますよね。
# ps -ef | grep "httpd" | grep -v "grep"
で出力結果の第2列目のプロセスIDと最初のhttpd.pidとが完全一致するものがあればOK、なければNG。意図されていることはこれとは違いますか?





for文やwhile文を使わない理由は参考書に載ってあったawk構文の繰り返し処理でした。
(実用 UNIXハンドブックp100 ナツメ社)
このページに載っている方法だとシンプルに簡単に繰り返し処理ができます。
for文やwhile文よりも簡単にループができるのだと考えました。

ただこの方法で繰り返し処理できるのは、この参考書のケースで私のケースだと参考書に載って
いる方法で繰り返しできないのかもしれません。そのあたりはもう少し調べたいと思います。

私のケースでこの方法が使えない時はfor文やwhile文を使って完成させたいと思っています。


繰り返しをさせたい理由なのですが、pid=`cat /usr/local/apache/logs/httpd.pid`
を実行させますと1つだけの結果がでます。

ところが ps -ef | grep http | grep -v grep
を実行させますと複数の結果が表示されます。

複数の結果が表示されるという事は2列目が複数あることになります。
正常なプロセスとそうでないプロセスを1つずつ判断するために繰り返し処理が必要だと思いました。

上手な文章でお答え出来ずに申し訳ございません。

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