rsyncの終了ステータスによってその後の処理を切り替えています.
<src>
rsync -auz --delete $SDIR $DDIR
if [ $? -eq 0 ]; then
END=`date '+%Y-%m-%d-%H-%M-%S'`
echo "$END $1 end" >> /home/hoge/log
else
echo "ERROR! exit status $?" >> /home/hoge/log
fi
</src>
rsyncが正常終了すればlogファイルに時間を記入して,
正常終了しなかったら,終了ステータスを記入します.
もし,rsyncが正常終了したにも関わらず,ちょうどif [ $? -eq 0 ]; thenに入るまえに
他のコマンドが異常終了したら変数$?の値が変わると思います.
かなり気にしすぎかもしれませんが,rsyncだけの終了ステータスに注目するにはどうしたらいいでしょうか?
よろしくお願いします.
No.7ベストアンサー
- 回答日時:
>crontabでシェルを動かしているときにkillをしてもkillコマンドの終了ステータスは入ることなくrsyncの終了ステータスをちゃんと受け取れるという理解でよろしいでしょうか?
まず他の方が書いているように、$? はそのシェルプロセスのローカル変数なので、別のプロセス(上記だと、killコマンドを投入した対話型シェルのプロセス)の影響を受けることはありません。
rsync が実行途中でkillされた場合、rsyncの終了ステータス $? は、128+(killのシグナル番号) になります。killのシグナル番号はデフォルトだと15なので、143 ですね。kill -9 とかすると、137 になります。
正確には、「rsyncは15番のシグナルでkillされた」ということがrsyncを呼び出したシェルプロセス(bashとかshとか)に返るので、シェルが+128して、$? にセットして通常の終了(プログラムが自分で狩猟ステータスを指定して終了した)場合と区別できるようにしてます。
あと、126と127もシェルによって予約されたステータスです。
つまり、
・ ?$ が 0~125 → プログラムが終了コードを指定して終了した(Cだとexit(cc);とか return cc;とか)
・ ?$ が 126 → コマンドが存在するが実行に失敗した(実行権限なしなど)
・ ?$ が 127 → コマンドが存在しない(command not found)
・ ?$ が 128 → このケースはたぶん無いはず
・ ?$ が 129~ → コマンドが実行中にシグナル番号($?-128)でkillされた
No.8
- 回答日時:
No7さん。
やっと、ちゃんと理解してくれている人が投稿してくれたようですね。
質問者に代わってお礼を。
ちなみに man で確認をと以前かきましたが、man の検索結果の一例です。正確には、対処のマシンでman or ヘルプを見てください(設置していない場合もあるが、デフォルトは設置されている)。
http://linux.die.net/man/1/rsync
(この「Exit Values」項目が戻り値です。
これがあなたが使用しているOSで、そのバージョンで対象のコマンドなら、そのページでいいですが、
正確にOS名やバージョンの記載がないのでわかりません)
http://linux.die.net/man/5/rsyncd.conf
(基本的には、この設定ファイルでコントロールする。理解しておいた方がいいでしょう)
(http://www.infoscience.co.jp/technical/rsync/rsy …
第3者による解説サイトですね
http://www.infoscience.co.jp/technical/rsync/ind …
いろいろあるのです)
それと、以前にも記載しましたが、終了ステータスは、あくまでコマンドの作成者が予期した範囲での数字です。予期していない場合は、
ただしい値が返っているとは言えないのです。なので、私としての見解は
「$?の値の信頼性を問うなら、メッセージやログを保存し、その違いで分岐する」
が、信頼性を向上させる鍵です。上記の「infoscience.co.jp」にも、それに則した似たようなサンプルが掲載されています。
No.6
- 回答日時:
> rsyncが正常終了したにも関わらず,ちょうどif [ $? -eq 0 ]; thenに入るまえに
> 他のコマンドが異常終了したら変数$?の値が変わると思います
これを心配するのだったら
if rsync -auz --delete $SDIR $DDIR ; then
END=`date '+%Y-%m-%d-%H-%M-%S'`
echo "$END $1 end" >> /home/hoge/log
else
echo "ERROR! exit status $?" >> /home/hoge/log
fi
とすれば、rsyncの終了ステータスそのもので判定するので、少なくとも、rsync成功したときにERRORとログが残ることは無い。
No.5
- 回答日時:
もう一つおまけ。
>コマンドの仕様により、0だったり、1だったり
ちょうどいいサンプルがありましたので、
http://shellscript.sunone.me/exit_status.html
input_check.shのスクリプトですね。exprの計算が成功し0となるはずが、計算結果が0になる。exprの仕様により結果が0の場合、終了ステータスは異常を示す1が返る。
実行は成功しているにもかかわらず、結果の内容によりステータスを変える。
これは、良くある事なので、それぞれのコマンドで違うのである。
また ”「 rm -f 」の終了ステータス”
の項目も理解しておいて欲しい。
何がいいたいか理解していただけましたでしょうか?
文献としては古いので、かならずしもその通りになるとは限りませんが、先人の苦悩を拾うことが重要です。
その文献の初めにありますが
「各コマンドにより異なるが、一般的にはコマンド成功時には「0」が、失敗時には「1」が設定される。」
と言うこと。各コマンドにより違うのである。
あなたの疑問は
input_check.shのスクリプトを同じシェル内で、同時実行してみたり、別シェル(ウインドウ)で同時実行してみたり、crontabで同時刻にやってみて、どうなるか試したらいかかですか?
例えば、違う結果になるようにして、別シェルで同時実行したらどうなるか?
No.4
- 回答日時:
>crontabでシェルを動かしているときにkillをしてもkillコマンドの終了ステータスは入ることなくrsyncの終了ステータスをちゃんと受け取れるという理解でよろしいでしょうか
コードに「<src>」があることが気になるが、あなたが言っているのはシェルスクリプトとしての実行でいいのですよね。
何かのサービスの子プロセスから実行されると言う事でしょうか? つまり、シェルのエミュレーション機能があるサービスで、シェルを模倣して実行される?
そうでないのなら、$? などと言う変数は、シェルの実行単位で有効であり、スコープはローカル変数となります。
つまり、シェルスクリプトが2つ実行されれば、それぞの変数に影響を与える事はありません。ただし、B-Shellであれば、Exportコマンドでグローバル変数となり、実行しているシェル(コマンドツールなどのGUIツール内)では、存在すれば上書きされます。
別のシェルで、それぞれ別に実行すれば、いくらExportコマンドでグローバルにしても、それぞれの変数が上書きなど、影響を与える事はありません。
と言うことは、
「crontabでシェルを動かしているときにkillをしてもkillコマンドの終了ステータスは入ることなくrsyncの終了ステータスをちゃんと受け取れるという理解でよろしいでしょうか」
は、別々のシェルで実行されることになるので、CrontabでKillされても、$?の変数が、そのCrontabのデーモンの成功、失敗を拾うことなく、
rsyncの仕様にしたがって、killされた時の終了ステータスを実行しているシェルから$?を通して受け取ります。
このことを、No3で語ったつもりだったのですが・・・
問題は、rsyncの仕様で、他のプロセスからKillを実行されて終了しても、正常終了として0を返すのか、それとも不明として3以上を返すのか、私は把握していません。
コマンドの仕様により、0だったり、1だったり2だったり、時には255なんて場合もあります。
それはマニュアルに記載されているし(MAN)、実際試せば分かる事です。
なので、私は、終了メッセージや、ログを拾って、分岐させることを、特に業務用ではお勧めします。
あなたが理解しなければならないのは、変数のスコープと、シェルスクリプトの実行の仕組みです。
/bin/shのプロセスの実行単位でローカル、グローバル変数がコントロールできます。
聞くよりも、実際に試してみたらいかかでしょうか?
No.3
- 回答日時:
対策を書くのを忘れていました。
UNIX系のコマンドだと、終了ステータスを拾うという手段は、最初に考える事なんですが、私は、いろんな場合を考え、よく2段がまえで処理を切り分けています。
これはスクリプトだけでなく、C++、Java、HTML系のスクリプトにおいても。
と言うのも、対象処理がハング状態やクラッシュした時(ステータス的には正常終了と出る時がある<=なぜか言えば、それを終了させるプロセスがあるので、対象のプロセスを正常に終了させたと言うこと)など、正確なステータスを拾うことが困難です。
そこで、UNIX系のコマンドだと、エラー出力、標準出力など切り分けて、終了メッセージやログなどを出力する仕組みがそなわっているのがほとんどです。
それらを解析して、終了ステータスと組み合わせて、実行させます。
Oracleなどの業務系のDBや、それに合わせたアプリだと、不思議なクラッシュやハング状態があるものです。
そういったものに、ダブルチェックで異常事態を確実に把握するのには、とても役に立ちます。
1回作ってしまえば、後はコピーするだけなので、使い回しができますよ。
No.2
- 回答日時:
質問の趣旨からいえば、No1でも同じだと思うのだが・・・・
>ちょうどif [ $? -eq 0 ]; thenに入るまえに
そもそも、その考えが違っています。
>他のコマンドが異常終了したら変
その他のコマンドは 「if [ $? -eq 0 ];」 の前に記載されていませんよね。そのスクリプトの前述でバックグランド処理をするスクリプトを書いているか、バックグランド処理されるコマンドを実行していない限り、その部分が評価する対象は直前のシェル(実行単位)から渡される、終了ステータスのみです。
他の実行単位でのコマンドの終了ステータスが入る事は、ありえません。できるのでしたら、プロセス間通信で悩む必要はなくなります。(スクリプトレベルでも簡単にできることになる)
ありがとうございます.
このスクリプトでバックグラウンド処理はしていませんが,
たとえば,crontabで定期的に実行しているときに
root権限をもったユーザがkillコマンドでプロセスを切れたとしたら
変数$?はどうかわるのか気になって質問させていただきました.
解答から,私の懸案事項は他の実行単位での終了ステータスは入ることはないから,
crontabでシェルを動かしているときにkillをしてもkillコマンドの終了ステータスは入ることなくrsyncの終了ステータスをちゃんと受け取れるという理解でよろしいでしょうか?
No.1
- 回答日時:
LOG=/home/hoge/log
rsync -auz --delete $SDIR $DDIR
result_rsync=$?
if [ ${result_rsync} -eq 0 ]; then
echo `date '+%Y-%m-%d-%H-%M-%S'` $1 end >>$LOG
else
echo ERROR! exit status ${result_rsync} >>$LOG
fi
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
好きな人を振り向かせるためにしたこと
大好きな人と会話のきっかけを少しでも作りたい、意識してもらいたい…! 振り向かせるためにどんなことをしたことがありますか?
-
スマホに会話を聞かれているな!?と思ったことありますか?
スマートフォンで検索はしてないのに、友達と話していた製品の広告が直後に出てきたりすることってありませんか? こんな感じでスマホに会話を聞かれているかも!?と思ったエピソードってありますか?
-
モテ期を経験した方いらっしゃいますか?
一生に一度はモテ期があるといいますが、みなさんどうですか? いまがそう! という方も、「思い返せばこの頃だったなぁ」という方も、よかったら教えて下さい。
-
コーピングについて教えてください
皆さんはストレスを感じたとき、どのような方法や手段、テクニックで対処していますか?
-
【大喜利】【投稿~1/20】 追い込まれた犯人が咄嗟に言った一言とは?
【お題】追い込まれた犯人が咄嗟に言った一言とは?
-
echo $!の意味を教えてください
UNIX・Linux
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・あなたの人生で一番ピンチに陥った瞬間は?
- ・初めて見た映画を教えてください!
- ・今の日本に期待することはなんですか?
- ・【大喜利】【投稿~1/31】『寿司』がテーマの本のタイトル
- ・集中するためにやっていること
- ・テレビやラジオに出たことがある人、いますか?
- ・【お題】斜め上を行くスキー場にありがちなこと
- ・人生でいちばんスベッた瞬間
- ・コーピングについて教えてください
- ・あなたの「プチ贅沢」はなんですか?
- ・コンビニでおにぎりを買うときのスタメンはどの具?
- ・おすすめの美術館・博物館、教えてください!
- ・【お題】大変な警告
- ・【大喜利】【投稿~1/20】 追い込まれた犯人が咄嗟に言った一言とは?
- ・洋服何着持ってますか?
- ・みんなの【マイ・ベスト積読2024】を教えてください。
- ・「これいらなくない?」という慣習、教えてください
- ・今から楽しみな予定はありますか?
- ・AIツールの活用方法を教えて
- ・最強の防寒、あったか術を教えてください!
- ・【大喜利】【投稿~1/9】 忍者がやってるYouTubeが炎上してしまった理由
- ・歳とったな〜〜と思ったことは?
- ・モテ期を経験した方いらっしゃいますか?
- ・好きな人を振り向かせるためにしたこと
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
コマンド終了ステータス
-
ping -cコマンドで指定した個数...
-
cactiでグラフが表示されない
-
Illustratorのデータをまとめて...
-
scpコマンドでリモートサーバの...
-
/ が何時の間にか「Read-only f...
-
コマンドプロンプトにてコマン...
-
USBハードディスクのnfsでのエ...
-
メールサーバの/var/spool/mail...
-
ログイン後のカレントディレク...
-
Windows10のRegSys32に登録され...
-
別名でリンク先を保存。
-
/optのアクセス権を変更したい...
-
e2fsckの実行結果について教え...
-
BATファイル実行にフォーカ...
-
Viで書き込もうとすると、保...
-
DOSコマンドでのワイルドカ...
-
netshでipv6がインストールでき...
-
CentOSでのCDマウントがうまく...
-
PC-DOSのバージョンの違いによ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
コマンド終了ステータス
-
実行中のシェルスクリプト自体...
-
cshで変数名の入れ子ができない
-
cshの標準出力を制御したい
-
diskpart でパーティションの一...
-
FTPコマンドの戻り値について
-
FedoraCore4 の.ba...
-
複数の処理を順番にログアウト...
-
cronでftp自動転送を行いたい
-
ping -cコマンドで指定した個数...
-
Mac OSXのターミナルでemacsを起動
-
cshが詳しい方は教えてください
-
Bシェルでパイプ→exitがうまく...
-
telnet へのパイプができないです
-
lsコマンドの色設定が反映されない
-
UNIX Cシェルで実数の比較
-
cronでバックアップsh
-
csh(Cシェル)のevalに関して
-
vsftpd FTP転送を行うシェルス...
-
Linuxのシェルスクリプトをお客...
おすすめ情報