- ベストアンサー
シェルスクリプト エラー処理について
シェルスクリプトについてお聞きしたいことがあるのですが、 作成したスクリプトは上から実行されていくと思いますが、 途中でスクリプトが止まるということはありますでしょうか。 作成しようとしているスクリプト内容ですが、以下のような感じです。 #!/bin/sh . バッチプログラム1 . バッチプログラム2 . バッチプログラム3 if(一番下までこれたら) then 完了したメールを飛ばす else スクリプトが途中で止まった場合、エラーログを書き込む fi というような感じのスクリプトを作成したいのですが、 各バッチプログラム1・2・3については、 プログラムでエラーがあったら、エラーメールを送信するプログラムを組む予定です。 プログラムが正常に実行されなくても、スクリプトは下までくると思うのですが・・・、 途中でスクリプトが止まる場合についてですが、どのようにすれば エラーログを書き込むようにできるのか、スクリプトはどういうように作成すれば良いのか ご教授いただけますでしょうか。 あと、どのような書くのかも教えていただけるとありがたいです・・・。 宜しくお願い致します。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
>バッチプログラム1実行中で、Ctrl+cを押した場合、 >バッチプログラム1で処理が止まったことがわかるように そういうときは、ふつう、 echo `date` バッチプログラム1開始 >> /tmp/log.txt . バッチプログラム1 echo `date` バッチプログラム2開始 >> /tmp/log.txt . バッチプログラム2 echo `date` バッチプログラム3開始 >> /tmp/log.txt . バッチプログラム3 みたいにしますね。
その他の回答 (4)
- trapezium
- ベストアンサー率62% (276/442)
>errcode=$? もう既に気付いておられると思いますが、$?は直前にフォアグラウンドで実行したコマンドの終了コードですので、スクリプトの先頭に書いても意味はありません。 >trap 'echo "testsite" > test2.txt' 1 2 3 15 これだとスクリプト自体は動作継続します。その場で終了したいなら、exitをtrapの最後に入れてください。 それと#3の方もツッコまれているとおりですが、補足するとしたら確か子プロセスが実行中だと、子の終了をまってtrapが発動するはずです。ですから、子プロセスでシグナル無視してたりすれば、その終了までtrapの実行は遅れます。このへんはOSやshellによってはオプションで動作選択できたりします。逆に移植性を考慮するなら方言は使わない方がいいです。
補足
皆様ご教授ありがとうございます。 trap処理についてはいろいろ試してみましたが、 teapが実行されませんでした・・・。 こちらは再度上手くいくように頑張ってみます! trap処理の実行する流れというか意味はだいたいですが、 理解できてきました。 以下実行してみたいと思っている、スクリプトの内容ですが、 #!/bin/sh . バッチプログラム1 . バッチプログラム2 . バッチプログラム3 trap 'echo "エラーです" > test2.txt exit' 1 2 3 15 上記スクリプト実行中、どのバッチを実行中でスクリプトが 止まったのかわかるようにteap処理をしたいと思っているのですが・・・。 上記の場合だと、Ctrl+cで止めても、「エラーです」を書き込まれる だけだと思います。 バッチプログラム1実行中で、Ctrl+cを押した場合、 バッチプログラム1で処理が止まったことがわかるように したいのですが、スクリプトでどのように書けば実行できるか お教えいただけますでしょうか。 宜しくお願い致します。
- notnot
- ベストアンサー率47% (4900/10358)
#2です。訂正。補足にお書きの内容につられて間違ったことを書いてしまいました。 ctrl-Cはsleepとshの両方に渡ります。 従って、補足のスクリプトを実行してsleep実行中にctrl-Cを押すと、 test2.txt には、testsite が書かれます。 書かれないとすると、 ・ctrl-Cのタイミングが遅すぎる ・スクリプトの写し間違い ( /test2.txt というミスもあるし)
- notnot
- ベストアンサー率47% (4900/10358)
>途中でCtrl+cを押して、処理を止めた場合、 >trap処理が実行されて そうはなりません。sleep実行中のCtrl-Cは、sleepが受け取って、異常終了します。shには渡りません。 #!/bin/sh if sleep 10 then echo "テストOK" >> test2.txt else echo "$?" >> test2.txt echo "テストNG" >> test2.txt fi にすると、sleepを途中でCtrl-Cで止めたら、終了コードと"テストNG"が書かれます。
- trapezium
- ベストアンサー率62% (276/442)
色々やりようはありますが、基本的にはコマンドの終了コードや、出力結果で判断します。 exitコードを使うなら、 if !command; then error handling exit 1 fi などとして、エラー処理でログ出力するなり、最後でまとめて処理するなら変数にエラーコードを保存する command errcode=$? コマンドの出力結果を使うなら aaa=`command` case $aaa in foo) foo handling ;; bar) bar handling ;; *) error handling ;; esac それと、シグナルはtrapで掴まえます。良くあるのはメッセージ表示したり、一時ファイルを削除したりします。 trap 'echo "error messages" 1>&2; rm -f $TEMP; exit 1' 2 15
補足
回等ありがとうございます! trapについていろいろ調べてみて、自分で実装行なってみたのですが、上手く処理されません。 作成したシェルスクリプトは以下に記載します。 #!/bin/sh errcode=$? trap 'echo "testsite" > test2.txt' 1 2 3 15 if [ -e test.txt ] then echo "$errcode" >> /test2.txt echo "テストOK" >> test2.txt sleep 10 else echo "テストNG" >> test2.txt fi というようなスクリプトを作成し、実行したのですが、 test2.txtに記載されるのは 0 テストOK になり、ifでの条件はきちんと動作しているのですが、 途中でCtrl+cを押して、処理を止めた場合、 trap処理が実行されて test2.txtに記載されるのは testsite になると思うのですが、「testsite」の文字が記載されず、 0 テストOK の文字列が追加されるだけです。 書き方が間違っているのか、どこが間違っているのかわかりません・・・。 宜しければ再度ご教授いただけますでしょうか。 宜しくお願い致します。
補足
なるほど!! そうですね・・・少し考えればそういう風に書けば出来るって わかりますね・・・(汗) 馬鹿みたいですけど、書き方教えていただいて感動しました(笑) notnotさんに教えていただいたやり方で、スクリプト作成したいと思います! 皆様丁寧にご教授いただきまして、ありがとうございました!