bash script: повторите команду, если она возвращает ошибку

23

Я хотел бы создать цикл, который повторяет передачу ncftp, если он возвращает ошибку.

Я немного не уверен, как переменную кода выхода можно использовать в цикле. Будет ли что-то вроде этой работы?

until [$? == 0]; do
    ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file
done
Рой
источник

Ответы:

40

Я нашел основу для этого элегантного цикла в другом месте на сервере. Оказывается, нет необходимости сохранять код выхода, так как вы можете проверить непосредственно по самой команде;

until ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file; do
  echo Tansfer disrupted, retrying in 10 seconds...
  sleep 10
done
Рой
источник
8

Почти. Возможно, вам лучше сохранить возвращаемое значение как переменную, чтобы вы могли предварительно установить его перед циклом. В противном случае это будет зависеть от команды последнего запуска.

Вы также можете захотеть добавить sleepтуда, чтобы он не появлялся слишком быстро.

RET=1
until [ ${RET} -eq 0 ]; do
    ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file
    RET=$?
    sleep 10
done
Дэн Карли
источник
Я думаю, забыл передать код выхода в переменную RET, но я понял. Мой главный вопрос: когда будет оцениваться предложение до? В Си это не будет оцениваться до первого запуска цикла, и в этом случае мой цикл должен работать. Ваш, тем не менее, лучше, так как он допускает промежуточные команды, такие как сон. Благодарность!
Рой
Хорошо подмечено. Я редактировал это. Предложение будет оценено перед первым запуском. Поэтому ранее он использовал код возврата любой предыдущей команды. Bash не применяет двойное равенство, но это хорошая практика для использования.
Дэн Карли
== для равенства строк не числовой, хотя я не думаю, что это имеет значение в этом случае ...
Кайл Брандт
Одиночные и двойные равны одинаковы. Но было бы лучше использовать целочисленное равенство теперь, когда вы упомянули это.
Дэн Карли
1
Вам не нужно проверять номер кода возврата - вы можете просто проверить код возврата самой программы - до программы; спать 3; сделанный .
Крис
3

Немного странно, но мое решение состояло в том, чтобы просто создать функцию bash, которая запускается сама, если она завершается с ошибкой

function retry { the_command_you_want && echo "success" || (echo "fail" && retry) }; retry
Qwertie
источник
0

Вы можете сделать цикл, пока ваша команда возвращает ошибку:

    while [ -n $(ncftpput -DD -z -u user -p password remoteserver /remote/dir /local/file) ]; do
            sleep 1;
    done;
Андрес Ривас
источник
3
Этот ответ требует объяснения.
kasperd
Добавлено объяснение @kasperd
Андрес Ривас