定期的に物をダウンロードするcronjobを作成します。
if ! su scpuser -c "scp ..." > /dev/null 2>&1 || ! [ -f $scptarget ]; then;
error "did not download stuff"
$scptarget
コンテンツがダウンロードされ、実行中のスクリプトとは異なるボリュームにあります(ただし、状態は変わらず、同じハードドライブのようです)。
問題が発生するたびに入って見てみると、ファイルがすぐそこにありました。少しリラックスすると、ファイルが存在することを確認する部分が成功する可能性がありますか?それともSCPが成功してもエラーは発生しますか?
(もともとこの記事を書いた人が実際のエラーが何であるかを文書化できたらいいのですが。
もしそうなら、このスクリプトにランダムな内容を追加したくありませんsleep
。実際のbashプログラマが行うより古典的な作業はありますか?
答え1
strace
ファイルでscp
一つ作ってみました。scp
そのような一時ファイル名を使わずに、wget
実際に宛先ファイルがあることを確認して、実際に書き込むデータがO_WRONLY|O_CREAT
あればscp
、宛先ファイルが存在しなければならないようです。
ターゲットファイルの存在とその存在確認の間に「競合」はありません。シェルはscp
終了状態を取得し、状態がゼロでないことを確認するために終了時にSIGCHLDを取得する必要があります。私はプロセスが終了したときにカーネルが既存のファイル名を処理すると確信していますscp
。ファイルの作成はアトミックに行う必要があります。あえて追加しないでくださいsleep
。役に立ちません。
サンプルコードがターゲットファイル存在テスト([ -f $scptarget ]
)に到達する唯一の方法は、scp
ゼロ(ゼロ)状態で終了することです。もちろん、ファイルが存在する可能性がありますが、エラー条件があります。$scptarget
エラーが発生した場合、ファイルの正確性と完全性を確認しますか?不完全または破損したファイルを取得できます。
何が起こっているのかを知るには、2つのif
構成を使用する必要があると思います。 1 つ目は終了状態、scp
2 つ目は宛先ファイルの存在です。メッセージが異なることを確認し、プロセス$?
の終了ステータスを記録しますscp
。
答え2
まず、エラーコードを取得します(stderrも便利です。エラーを記録しないスクリプトを作成する人は誰ですか...?)。 'su' または 'scp' は retVal>0 を返すことができます。
OSX用のSCPソースコードの断片:
// I'd put my bet for this case..
void
lostconn(signo)
int signo;
{
if (!iamremote)
fprintf(stderr, "lost connection\n");
exit(1);
}
失敗後、ターゲットファイルがソースファイルとまったく同じであることを確認してください。
から抜粋数マンページ:
終了値
成功すると、suは実行したコマンドの終了値を返します。
コマンドがシグナルによって終了すると、suはシグナル番号に128を加えた値を返します。
suがコマンドを終了する必要がある場合(終了要求を受け取ったがコマンドが時間内に終了しなかったため)、suは255を返します。
繰り返しますが..終了コードや標準エラーの内容がなければ、推測を続ける以外にできることはあまりありません。