現在、Unix スクリプトを呼び出す夜通しのジョブを作成しています。Unix スクリプトは、.NET を使用してファイルを作成および転送しますftp
。考えられるすべての戻りコードを確認したいと思います。のマニュアル ページにftp
はリターン コードが記載されていません。リストの場所を知っている人はいますか?これを経験した人はいますか?ログ内の特定の戻り文字列を grep する他のスクリプトがあり、エラーが発生した場合に電子メールを送信します。ただし、予期しないコードを見逃すことがよくあります。次に、理由をログと電子メールに入れています。
9 に答える
このftp
コマンドは、私が遭遇したほとんどの実装でゼロ以外を返しません。
ログ内の 3 桁のコードを処理する方がはるかに優れています。バイナリ ファイルを送信している場合は、送信されたバイト数が正しいことを確認できます。
3桁のコードは「シリーズコード」と呼ばれ、リストはここにあります
一度に1つのファイルのみを転送するスクリプトを作成し、そのスクリプトでメッセージgrep
をチェックするために使用し226 Transfer complete
ます。見つかった場合は、grep
0を返します。
ftp -niv < "$2"_ftp.tmp | grep "^226 "
何か問題が発生した場合は、ftp を実行して ftp の終了コードを確認する方が簡単だと思います。
私はこれを以下の例のようにしました:
# ...
ftp -i -n $HOST 2>&1 1> $FTPLOG << EOF
quote USER $USER
quote PASS $PASSWD
cd $RFOLDER
binary
put $FOLDER/$FILE.sql.Z $FILE.sql.Z
bye
EOF
# Check the ftp util exit code (0 is ok, every else means an error occurred!)
EXITFTP=$?
if test $EXITFTP -ne 0; then echo "$D ERROR FTP" >> $LOG; exit 3; fi
if (grep "^Not connected." $FTPLOG); then echo "$D ERROR FTP CONNECT" >> $LOG; fi
if (grep "No such file" $FTPLOG); then echo "$D ERROR FTP NO SUCH FILE" >> $LOG; fi
if (grep "access denied" $FTPLOG ); then echo "$D ERROR FTP ACCESS DENIED" >> $LOG; fi
if (grep "^Please login" $FTPLOG ); then echo "$D ERROR FTP LOGIN" >> $LOG; fi
編集:エラーをキャッチするために、ftp コマンドの出力を grep します。しかし、それは本当に最善の解決策ではありません。
あなたが Perl、Python、Ruby などのスクリプト言語にどれだけ慣れているかはわかりません。それらにはすべて、使用できる FTP モジュールがあります。これにより、各コマンドの後でエラーをチェックできます。Perl での例を次に示します。
#!/usr/bin/perl -w
use Net::FTP;
$ftp = Net::FTP->new("example.net") or die "Cannot connect to example.net: $@";
$ftp->login("username", "password") or die "Cannot login ", $ftp->message;
$ftp->cwd("/pub") or die "Cannot change working directory ", $ftp->message;
$ftp->binary;
$ftp->put("foo.bar") or die "Failed to upload ", $ftp->message;
$ftp->quit;
このロジックを機能させるには、以下のように ftp コマンドから STDERR もリダイレクトする必要があります。
ftp -i -n $HOST >$FTPLOG 2>&1 << EOF
以下のコマンドは、ftp コマンドが成功または失敗を返さないため、常に 0 (成功) を割り当てます。したがって、ユーザーはそれに依存するべきではありません
EXITFTP=$?
私はAnuragのソリューションが好きです。バイト転送の問題については、grep-v"bytes"を使用してコマンドを拡張しました。
すなわち
grep "^ 530" ftp_out2.txt | grep-v"バイト"
-530の代わりに、Anuragが行ったようにすべてのエラーコードを使用できます。
不十分な答えは知っていますが、ftpソースを入手して自分の目で確かめてみませんか
あなたはそこにファイルを FTP で送りたいと言いましたが、通常の BSD FTP クライアントがそこに行きたい唯一の方法であるかどうかについては言いませんでした。BSD FTP は、そのすべての解析を必要とするエラー状態の戻りコードを提供しませんが、あなたまたはあなたの管理者がそれらをインストールすれば、FTP でファイルを転送するために使用できる一連の他の Unix プログラムがあります。少量のコードですべてのエラー状態をキャッチしながら、FTP でファイルを転送する方法の例をいくつか示します。
FTPUSER は、ftp ユーザーのログイン名です。
FTPPASS は ftp パスワードです
FILE は、パス情報なしでアップロードするローカル ファイルです (例: file1.txt、/whatever/file1.txt やwhatever/file1.txt ではありません)。
FTPHOST は、FTP を送信するリモート マシンです。
REMOTEDIR は、アップロード先のリモート マシン上の場所への絶対パスです。
以下に例を示します。
curl --user $FTPUSER:$FTPPASS -T $FILE ftp://$FTPHOST/%2f$REMOTEDIR
ftp-upload --host $FTPHOST --user $FTPUSER --password $FTPPASS --as $REMOTEDIR/$FILE $FILE
tnftp -u ftp://$FTPUSER:$FTPPASS@$FTPHOST/%2f$REMOTEDIR/$FILE $FILE
wput $FILE ftp://$FTPUSER:$FTPPASS@$FTPHOST/%2f$REMOTEDIR/$FILE
これらのプログラムはすべて、何か問題が発生した場合にゼロ以外の終了コードを返し、何が失敗したかを示すテキストを返します。これをテストしてから、必要に応じて、出力、ログ、電子メールなどで必要なことを行うことができます。
ただし、次の点に注意してください。
「%2f」は URL で使用され、次のパスがリモート マシン上の絶対パスであることを示します。ただし、FTP サーバーが chroot する場合、これを回避することはできません。
ユーザーとパスワードが埋め込まれたサーバーへの実際の URL ( ftp://etc ) を使用する上記のコマンドの場合、特殊文字が含まれている場合、ユーザー名とパスワードを URL エンコードする必要があります。
場合によっては、各プログラムの構文に慣れれば、リモート ディレクトリを絶対ディレクトリに、ローカル ファイルを単純なファイル名に柔軟に対応できます。ローカル ディレクトリ環境変数を追加するか、すべてをハードコーディングする必要があるかもしれません。
本当に絶対に通常の FTP クライアントを使用しなければならない場合、失敗をテストできる 1 つの方法は、スクリプト内で、最初にファイルを PUT するコマンドを含め、次に同じファイルの GET を実行して別のファイルを返す別のコマンドを含めることです。名前。FTP が終了したら、シェル スクリプトでダウンロードしたファイルの存在をテストするか、元のファイルに対してチェックサムを実行して、ファイルが正しく転送されていることを確認します。ええ、それは悪臭を放ちますが、私の意見では、考えられるすべてのエラー状態に対して大量の解析を行うよりも、読みやすいコードを作成する方がよいと考えています。BSD FTP はそれほど素晴らしいものではありません。
最終的に行ったのがこちら。すべての助けをありがとう。すべての答えは、私を正しい方向に導くのに役立ちます。結果とログの両方をチェックするのは少しやり過ぎかもしれませんが、すべてのベースをカバーする必要があります。
echo "open ftp_ip
pwd
binary
lcd /out
cd /in
mput datafile.csv
quit"|ftp -iv > ftpreturn.log
ftpresult=$?
bytesindatafile=`wc -c datafile.csv | cut -d " " -f 1`
bytestransferred=`grep -e '^[0-9]* bytes sent' ftpreturn.log | cut -d " " -f 1`
ftptransfercomplete=`grep -e '226 ' ftpreturn.log | cut -d " " -f 1`
echo "-- FTP result code: $ftpresult" >> ftpreturn.log
echo "-- bytes in datafile: $bytesindatafile bytes" >> ftpreturn.log
echo "-- bytes transferred: $bytestransferred bytes sent" >> ftpreturn.log
if [ "$ftpresult" != "0" ] || [ "$bytestransferred" != "$bytesindatafile" ] || ["$ftptransfercomplete" != "226" ]
then
echo "-- *abend* FTP Error occurred" >> ftpreturn.log
mailx -s 'FTP error' `cat email.lst` < ftpreturn.log
else
echo "-- file sent via ftp successfully" >> ftpreturn.log
fi
コマンドからのすべての出力をログ ファイルに保存してから、コマンドからのリターン コードをチェックし、それが 0 でない場合はログ ファイルを電子メールで送信しないのはなぜですか?