プロが教えるわが家の防犯対策術!

Linuxのshellで、ftpを使ってデータを転送するシェルを作成しています。
転送部分はうまくいき、エラー制御を考えているのですが上手くいきません。(ログは取得できてます)
やりたいことは、ftp転送で失敗したかどうかの判定をしたい。ということです。

過去ログ等見ていて、ログファイルからエラーNoをgrepして判断する。というやり方があったので
試して見ましたが、構文が正常に書けていないようです。すみませんがアドバイスをお願い致します。

ftp転送終了したとします。 ログは $Log_Path/$date.txt にとってあります。

grep ^425 $Log_Path/$date.txt /dev/null
if $? eq 0
then
error_flag=1
exit 1
fi

(エラーが発生したら、error_flagに1が入るようにしたい)

エラーナンバーは425(データコネクションをオープンできない)というやつで、いいかなと思っていますが、もっと適切なものがあれば教えて下さい。(putで行っている転送の失敗を判断できればいいです)

上記の構文ではエラーが出ます。
また、 /dev/null の部分が意味が解っていません。この部分の説明をお願いできますでしょうか?

宜しくお願い致します。

A 回答 (4件)

grepは、一致した行を画面に出力してしまうので、それを見たくない場合は煩わしい。

そのような時には画面出力を捨てます:

grep ^425 $Log_Path/$date.txt > /dev/null

不等号記号 ">" に注意して下さい。これは「標準出力を /dev/null というファイルに出しなさい」という意味です。不等号記号は「リダイレクション」という機能ですから、詳しくはリダイレクションの使い方を調べてみてください。また、/dev/null がどういうファイルかも、シェルプログラミング関連で調べられると思います。

あるいは、grep に "-q" (quiet) オプションがあれば、

grep -q ^425 $Log_Path/$date.txt

で同じ効果が得られるんじゃないかと思います。

また、"if" は、コマンドを実行しその戻り値を利用するのですから、"if" の直後はコマンドです。従って、

if test $? eq 0

と書きます。"test" というコマンドに "$? eq 0" という式の真偽を計算させるのです。

さらに、それで悪くはないのですが、どうせコマンドの戻り値を使うなら、"if" の後に直接 grep を書いてやればいいじゃないか . . . ということになります。

また、error_flag=1 としたあとに、exit していますが、それではせっかく設定した変数error_flagが無駄になってしまいませんか?

以上のことを考えると

if grep ^425 $Log_Path/$date.txt > /dev/null
then
exit 1
fi

になると思います。あとは、個人の好みですが、僕だったらもっと簡潔に

(grep ^425 $Log_Path/$date.txt > /dev/null) && exit 1

と書くと思います。

最後にですが、ftpなどの、本来は対話的に使うように出来ているコマンドをスクリプトで使うのは結構辛いです。そこで、"expect" という、対話コマンドをスクリプトから使うためのコマンドもあります。ずっと昔使っていただけで、使い方は忘れてしまいました。また、転送が失敗したかどうか知りたいだけだったら、wgetをftpコマンドの代わりに使う方がずっと楽かも知れません。
    • good
    • 2
この回答へのお礼

とても丁寧な回答ありがとうございます。
非常に解りやすく、参考になりました。
意味のわかっていなかった部分も改善できました。

アドバイスいただいた内容で試して見たいと思います。
ありがとうございました。

お礼日時:2012/08/31 14:11

たぶんで申し訳ないんですが、対話的に使用するftpコマンドよりも


wgetコマンドを使用したほうがいいと思います。
ログをgrep することなく、wgetコマンドの直後に $? の比較で
済むと思います。
    • good
    • 0

>(エラーが発生したら、error_flagに1が入るようにしたい)



そのerror_flagは何者です?
シェル内の変数ですか?
環境変数ですか?
# どちらにしろ、exitで抜けているので意味ありませんが…。
# シェル内で環境変数を変更しても、親プロセス(呼び出し側)には影響しなかった…かと。
呼び出し側でエラーによる分岐をしたいのであればexitで返却する終了コードで分岐すべき…かと思います。

>上記の構文ではエラーが出ます。

どういうエラーが出ますか?

>また、 /dev/null の部分が意味が解っていません。この部分の説明をお願いできますでしょうか?

なんか抜けていませんかね?
grep ^425 $Log_Path/$date.txt > /dev/null
なんじゃないですか?

/dev/nullへのリダイレクトなら、grepの出力結果を捨てる。というだけです。
    • good
    • 0
この回答へのお礼

回答ありがとうございました。

また、提示情報が不足しておりもうしわけありませんでした。
他の方かも頂いた回答で解決できそうです。

ありがとうございました。

お礼日時:2012/08/31 14:12

正しくは



grep ^425 $Log_Path/$date.txt > /dev/null
if [ $? -eq 0 ];
then
#error_flag=1
exit 1
fi

だと思います。
grepは正規表現に該当した行を出力するので、それを「 > /dev/null」で表示させないようにします。
ifの比較の文も変更しています。スペースに注意して下さい。
error_flag=1とexit 1ですがどちらか一つにして下さい。
シェルの実行方法は
A) ./aaa.sh
B) source ./aaa.sh
の二通りありますが、Aではサブシェル内で実行され、Bでは現在のシェル内で実行されます。
Aではerror_flag=1が現在のシェルに引き継がれないので、意味を持ちません。
Bではexit 1で現在のシェルを終了させてしまいます(要するにコマンドプロンプトが閉じる)。
    • good
    • 0
この回答へのお礼

迅速な回答ありがとうございました。
不明点も明確になり、理解が増しました。

基本的な部分がわかっておらず申し訳ありません。
徐々に改善していければと思います。

ありがとうございました。

お礼日時:2012/08/31 14:13

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています