skrip bash: ulangi perintah jika itu mengembalikan kesalahan

23

Saya ingin membuat loop yang mengulangi transfer ncftp jika mengembalikan kesalahan.

Saya sedikit tidak yakin bagaimana variabel kode keluar dapat digunakan dalam satu lingkaran. Apakah sesuatu seperti ini berfungsi?

until [$? == 0]; do
    ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file
done
Roy
sumber

Jawaban:

40

Saya menemukan dasar untuk loop elegan ini di tempat lain di serverfault. Ternyata tidak perlu menyimpan kode keluar, karena Anda dapat menguji langsung pada perintah itu sendiri;

until ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file; do
  echo Tansfer disrupted, retrying in 10 seconds...
  sleep 10
done
Roy
sumber
8

Hampir. Anda mungkin lebih baik menyimpan nilai kembali sebagai variabel sehingga Anda dapat mengaturnya sebelum loop. Kalau tidak, itu akan dipengaruhi oleh perintah yang terakhir dijalankan.

Anda mungkin juga ingin menggantungkan sling sleepdi sana untuk menghentikan respawning terlalu cepat.

RET=1
until [ ${RET} -eq 0 ]; do
    ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file
    RET=$?
    sleep 10
done
Dan Carley
sumber
Saya pikir saya lupa untuk melewatkan kode keluar ke variabel RET, tapi saya mengerti. Pertanyaan utama saya adalah kapan klausa sampai dievaluasi? Dalam C tidak akan dievaluasi sampai setelah putaran pertama dijalankan, dalam hal ini loop saya harus bekerja. Anda masih lebih baik, karena memungkinkan untuk perintah menengah seperti tidur. Terima kasih!
Roy
Terlihat dengan baik. Saya sudah mengeditnya. Klausa akan dievaluasi sebelum menjalankan pertama. Jadi sebelumnya akan menggunakan kode kembali dari perintah sebelumnya. Double-sama tidak dipaksakan oleh Bash tetapi itu praktik yang baik untuk digunakan.
Dan Carley
== adalah untuk kesetaraan string yang tidak numerik, meskipun saya tidak berpikir itu penting dalam hal ini ...
Kyle Brandt
Sama dan ganda sama dengan. Tetapi akan lebih baik menggunakan persamaan integer sekarang setelah Anda menyebutkannya.
Dan Carley
1
Anda tidak perlu menguji nomor kode pengembalian - Anda cukup menguji kode pengembalian program itu sendiri - hingga program; tidur 3; selesai
chris
3

Agak macet tapi solusi saya adalah hanya membuat fungsi bash yang berjalan sendiri jika keluar dengan kegagalan

function retry { the_command_you_want && echo "success" || (echo "fail" && retry) }; retry
Qwertie
sumber
0

Anda dapat melakukan perulangan sementara perintah Anda mengembalikan kesalahan:

    while [ -n $(ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file) ]; do
            sleep 1;
    done;
Andrés Rivas
sumber
3
Jawaban ini perlu penjelasan.
kasperd
Penjelasan @kasperd ditambahkan
Andrés Rivas