
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で質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) ファイル全てを .xlsm に変更したところ、プログラムが途中で落ちてしまっています 17 2022/12/07 12:03
- Visual Basic(VBA) VBAで最新のデータを別シートに転記する方法をお教えください。 3 2022/04/07 19:20
- Visual Basic(VBA) エクセルのマクロについて教えてください。 2 2023/07/06 17:46
- Visual Basic(VBA) VBA 参照先で選んだファイルをコピーし、出力先に別名で保存したい 8 2022/05/13 20:37
- Excel(エクセル) 日付で矢印マクロ 4 2023/07/25 16:47
- Visual Basic(VBA) パーソナルXLSBのfuctionを呼び出すと「Functionが定義されていません」のエラーになる 2 2022/08/22 22:51
- Visual Basic(VBA) 数式が消える 1 2023/03/19 16:55
- Visual Basic(VBA) [Excel VBA] このコードでは行の挿入や行の消去をすると13のエラーが出てしまう。 3 2022/12/09 00:29
- Visual Basic(VBA) こんにちは。ExcelVBA初心者につき困っています。Functionで始まっている処理の中で、処理 1 2022/06/18 21:40
- Visual Basic(VBA) 別シートから年齢別の件数をカウントしたいの続き 5 2023/01/24 00:16
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・「それ、メッセージ花火でわざわざ伝えること?」
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・【お題】甲子園での思い出の残し方
- ・【お題】動物のキャッチフレーズ
- ・人生で一番思い出に残ってる靴
- ・これ何て呼びますか Part2
- ・スタッフと宿泊客が全員斜め上を行くホテルのレビュー
- ・あなたが好きな本屋さんを教えてください
- ・かっこよく答えてください!!
- ・一回も披露したことのない豆知識
- ・ショボ短歌会
- ・いちばん失敗した人決定戦
- ・性格悪い人が優勝
- ・最速怪談選手権
- ・限定しりとり
- ・性格いい人が優勝
- ・これ何て呼びますか
- ・チョコミントアイス
- ・単二電池
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・ゴリラ向け動画サイト「ウホウホ動画」にありがちなこと
- ・泣きながら食べたご飯の思い出
- ・一番好きなみそ汁の具材は?
- ・人生で一番お金がなかったとき
- ・カラオケの鉄板ソング
- ・自分用のお土産
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
シェルスクリプトで困っていま...
-
diskpart でパーティションの一...
-
シェルの実行について
-
Bシェルでパイプ→exitがうまく...
-
コマンド終了ステータス
-
csh(Cシェル)のevalに関して
-
DOSのAUTOEXEC.BATの書き方、等
-
redhat9のwebサーバでのCGI設定
-
scpコマンドでリモートサーバの...
-
IBM漢字コードのSJIS変...
-
UNIXでのファイル、ディレクト...
-
残り日数のカウント方法について
-
PC-DOSのバージョンの違いによ...
-
e2fsckの実行結果について教え...
-
Viで書き込もうとすると、保...
-
wgetの正規表現について
-
Illustratorのデータをまとめて...
-
CentOS6.4で/commonを作成する...
-
Red Hat Linux 9でcd-romをマウ...
-
/ が何時の間にか「Read-only f...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
コマンド終了ステータス
-
実行中のシェルスクリプト自体...
-
diskpart でパーティションの一...
-
FTPコマンドの戻り値について
-
cshの標準出力を制御したい
-
cshで変数名の入れ子ができない
-
csh(Cシェル)のevalに関して
-
Linuxのシェルスクリプトをお客...
-
telnet へのパイプができないです
-
cronでftp自動転送を行いたい
-
ping -cコマンドで指定した個数...
-
UNIX Cシェルで実数の比較
-
cshが詳しい方は教えてください
-
kshでのcase文条件範囲について
-
cshの削除
-
Shellのパターンマッチについて
-
cygwinシェルスクリプト内での...
-
lsコマンドの色設定が反映されない
-
Mac OSXのターミナルでemacsを起動
-
shellから起動したkterm上でコ...
おすすめ情報