Есть ли краткий способ проверить состояние выхода набора команд в bash?
У меня есть простой скрипт для извлечения данных с удаленного сервера, поскольку процесс генерирует их с помощью rsync
:
while :
do
rsync -avz --remove-source-files -e ssh me@remote:path/to/foo* ./
rsync -avz --remove-source-files -e ssh me@remote:path/to/bar* ./
rsync -avz --remove-source-files -e ssh me@remote:path/to/baz* ./
rsync -avz --remove-source-files -e ssh me@remote:path/to/qux* ./
sleep 900 #wait 15 minutes, try again
done
Если нет файлов, rsync
возвращает статус выхода 12 (по-видимому). В случае, если ни один из вышеперечисленных rsync
находит любые данные, которые я хотел бы вырвать из цикла (процесс, генерирующий данные, вероятно, завершился). Чтобы избежать путаницы, я не хочу выходить из цикла, если хотя бы 1 из rsync
процессы успешны.
Есть краткий способ сделать это в Bash?
3 ответа
Этот способ подсчитывает количество сбоев из-за отсутствия файла.
while :
do
nofile=0
rsync -avz --remove-source-files -e ssh me@remote:path/to/foo* ./
(( $? == 12 )) && let nofile++
rsync -avz --remove-source-files -e ssh me@remote:path/to/bar* ./
(( $? == 12 )) && let nofile++
rsync -avz --remove-source-files -e ssh me@remote:path/to/baz* ./
(( $? == 12 )) && let nofile++
rsync -avz --remove-source-files -e ssh me@remote:path/to/qux* ./
(( $? == 12 )) && let nofile++
# if all failed due to "no files", break the loop
if (( $nofile == 4 )); then break; fi
sleep 900 #wait 15 minutes, try again
done
Вы можете сделать это, сложив возвращаемые значения, так что если они все возвращают 12, сумма равна 48:
while :
do
rc=0
rsync -avz --remove-source-files -e ssh me@remote:path/to/foo* ./
let rc+=$?
rsync -avz --remove-source-files -e ssh me@remote:path/to/bar* ./
let rc+=$?
rsync -avz --remove-source-files -e ssh me@remote:path/to/baz* ./
let rc+=$?
rsync -avz --remove-source-files -e ssh me@remote:path/to/qux* ./
let rc+=$?
if [[ $rc == 48 ]]; then # 48 = 4 * 12
break;
fi
sleep 900 #wait 15 minutes, try again
done
Обратите внимание, что это может пострадать, если вы получите другую комбинацию кодов возврата сумм до 48, то есть 0 + 0 + 12 + 36
Вдохновленный другими ответами, я думаю, что это самый чистый способ сделать это до сих пор...
while :
do
do_continue=0
rsync -avz --remove-source-files -e ssh me@remote:path/to/foo* ./ && do_continue=1
rsync -avz --remove-source-files -e ssh me@remote:path/to/bar* ./ && do_continue=1
rsync -avz --remove-source-files -e ssh me@remote:path/to/baz* ./ && do_continue=1
rsync -avz --remove-source-files -e ssh me@remote:path/to/qux* ./ && do_continue=1
if [[ $do_continue == 0 ]]; then
break
fi
sleep 900 #wait 15 minutes, try again
done
который может быть реорганизован больше для удаления оператора разрыва и соответствующего условного теста:
do_continue=1
while [ do_continue -eq 1 ]; do
do_continue=0
rsync -avz --remove-source-files -e ssh me@remote:path/to/foo* ./ && do_continue=1
#...
sleep 900
done