unbuffer udevadm monitor --environment
Использование unbuffer
является дополнительным, но когда вывод передачи по каналу к grep
сохраняет Вас головная боль. Выводом по умолчанию буферизуется в 4k блоках, ничто не будет распечатано, пока тот буфер не будет полон.
Вы не забыли перезагружать правила? sudo udevadm control --reload
Этот сценарий использует счетчик n
ограничить попытки команды к пять. Если команда успешна, $?
будет содержать нуль, и выполнение повредится от цикла.
n=0
until [ $n -ge 5 ]
do
command && break # substitute your command here
n=$[$n+1]
sleep 15
done
for i in 1 2 3 4 5; do command && break || sleep 15; done
Замена "команда" с Вашей командой. Это предполагает, что "состояние code=FAIL" означает любой ненулевой код возврата.
Используя {..}
синтаксис. Работы в большинстве оболочек, но не BusyBox sh
:
for i in {1..5}; do command && break || sleep 15; done
Используя seq
и проведение кода выхода неудавшейся команды:
for i in $(seq 1 5); do command && s=0 && break || s=$? && sleep 15; done; (exit $s)
То же как выше, но пропуск sleep 15
после заключительного сбоя. Так как лучше только определить максимальное количество циклов однажды, это достигается путем сна в начале цикла если i > 1
:
for i in $(seq 1 5); do [ $i -gt 1 ] && sleep 15; command && s=0 && break || s=$?; done; (exit $s)
for i in 1 2 3 4 5
с for i in {1..5}
потому что легче поддержать.
– Paddy Landau
11.07.2013, 16:03
&&
оценен перед ||
из-за приоритета
– gene_wood
04.09.2015, 22:50
[[ i -eq 5]]
как ИЛИ условие передо сном для предотвращения этого.
– Dave Lugg
15.01.2018, 20:46
Вот функция для повторной попытки
function retry()
{
local n=0
local try=$1
local cmd="${@: 2}"
[[ $# -le 1 ]] && {
echo "Usage $0 <retry_number> <Command>"; }
until [[ $n -ge $try ]]
do
$cmd && break || {
echo "Command Fail.."
((n++))
echo "retry $n ::"
sleep 1;
}
done
}
retry $*
Вывод:
[test@Nagios ~]$ ./retry.sh 3 ping -c1 localhost
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.207 ms
--- localhost ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.207/0.207/0.207/0.000 ms
[test@Nagios ~]$ ./retry.sh 3 ping -c1 localhostlasjflasd
ping: unknown host localhostlasjflasd
Command Fail..
retry 1 ::
ping: unknown host localhostlasjflasd
Command Fail..
retry 2 ::
ping: unknown host localhostlasjflasd
Command Fail..
retry 3 ::
Посмотрите ниже примера:
n=0
while :
do
nc -vzw1 localhost 3859
[[ $? = 0 ]] && break || ((n++))
(( n >= 5 )) && break
done
Я пытаюсь соединить порт 3389 на localhost, он повторит до сбоя 5 раз, если успех затем он повредит цикл.
$?
это, существуют состояние команды, если это обнуляет команду средств, успешно выполненную, если кроме нулевых средств управляют fai
Кажется немного сложным, может быть кто-то, делают это лучше, чем это.
$?
это, существуют состояние команды, если это обнуляет команду средств, успешно выполненную, если кроме нулевых средств управляют,
– Rahul Patil
11.07.2013, 10:34
function fail {
echo $1 >&2
exit 1
}
function retry {
local n=1
local max=5
local delay=15
while true; do
"$@" && break || {
if [[ $n -lt $max ]]; then
((n++))
echo "Command failed. Attempt $n/$max:"
sleep $delay;
else
fail "The command has failed after $n attempts."
fi
}
done
}
Пример:
retry ping invalidserver
выдает этот вывод:
ping: unknown host invalidserver
Command failed. Attempt 2/5:
ping: unknown host invalidserver
Command failed. Attempt 3/5:
ping: unknown host invalidserver
Command failed. Attempt 4/5:
ping: unknown host invalidserver
Command failed. Attempt 5/5:
ping: unknown host invalidserver
The command 'ping invalidserver' failed after 5 attempts
Для реального примера работы со сложными командами см. этот сценарий .
Вот мой любимый однострочный псевдоним / сценарий
alias retry='while [ $? -ne 0 ] ; do fc -s ; done'
Затем вы можете делать что-то вроде:
$ ps -ef | grep "Next Process"
$ retry
, и он будет продолжать выполнять предыдущую команду, пока не найдет «Следующий процесс»
Я использую этот скрипт, который делает повторные попытки данной команды, преимущество этого скрипта в том, что если все повторные попытки не удались, он сохраняет код выхода.
#!/usr/bin/env bash
if [ $# -ne 3 ]; then
echo 'usage: retry <num retries> <wait retry secs> "<command>"'
exit 1
fi
retries=$1
wait_retry=$2
command=$3
for i in `seq 1 $retries`; do
echo "$command"
$command
ret_value=$?
[ $ret_value -eq 0 ] && break
echo "> failed with $ret_value, waiting to retry..."
sleep $wait_retry
done
exit $ret_value
Возможно, это может стать проще
Aquí hay una función recursiva retry
para los puristas de la programación funcional:
retry() {
cmd=$1
try=${2:-15} # 15 by default
sleep_time=${3:-3} # 3 seconds by default
# Show help if a command to retry is not specified.
[ -z "$1" ] && echo 'Usage: retry cmd [try=15 sleep_time=3]' && return 1
# The unsuccessful recursion termination condition (if no retries left)
[ $try -lt 1 ] && echo 'All retries failed.' && return 1
# The successful recursion termination condition (if the function succeeded)
$cmd && return 0
echo "Execution of '$cmd' failed."
# Inform that all is not lost if at least one more retry is available.
# $attempts include current try, so tries left is $attempts-1.
if [ $((try-1)) -gt 0 ]; then
echo "There are still $((try-1)) retrie(s) left."
echo "Waiting for $sleep_time seconds..." && sleep $sleep_time
fi
# Recurse
retry $cmd $((try-1)) $sleep_time
}
Pásele un comando (o un nombre de función )y, opcionalmente, un número de reintentos y una duración de sueño entre reintentos, así:
retry some_command_or_fn 5 15 # 5 tries, sleep 15 seconds between each
GNU Parallel имеет--retries
:
parallel --retries 5 --delay 15s :::./do_thing.sh
Пример:
parallel -t --retries 5 --delay 0.1s 'echo {};exit {}' ::: {0..10}
Поскольку мне приходилось делать это несколько раз, скрипты выходили из-под контроля, поэтому я создал для этого специальный инструмент под названием retry.
retry --until=success --times=5 --delay=15 command...
Повторная попытка доступна здесь:https://github.com/minfrin/retry
Отвечая на этот вопрос, поскольку существующие ответы не позволяют,
exit errCode
, Bash не учитывает некоторые ловушки, такие какtrap somefunc ERR
COMMAND="SOMECOMMAND"
TOTAL_RETRIES=3
retrycount=0
until [ $retrycount -ge $((TOTAL_RETRIES-1)) ]
do
$COMMAND && break
retrycount=$((retrycount+1))
sleep 1
done
if [ $retrycount -eq $((TOTAL_RETRIES-1)) ]
then
$COMMAND
fi
Это старый вопрос, но я часто возвращаюсь к нему. Мой вариант использования заключался в том, чтобы иметь один вкладыш, который может повторять команду до n
раз, который можно использовать с модулем kubernetes (, конечно, если он будет работать для скрипта bash ).
TRY=6; until [ $TRY -eq 0 ] || <your command over here> ; do echo $TRY; echo "<output message>"; TRY=$(expr $TRY - 1); sleep 15; done;
Один лайнер немного сложно уложить в голове, но он может оказаться очень полезным.
небольшие модификации для одного -лайнера , который имеет увеличивающуюся задержку в секундах для следующего выполнения
DELAYS=(0 1 3 5); (for i in 1 2 3 4; do sleep ${DELAYS[$i]}; <COMMAND> && break || [ $i -lt 4 ] && echo "retry in ${DELAYS[$i+1]}s"; done)
пример (git push используется для устранения ошибки)
✗ DELAYS=(0 1 3 5); (for i in 1 2 3 4; do sleep ${DELAYS[$i]}; git pish && break || [ $i -lt 4 ] && echo "retry in ${DELAYS[$i+1]}s"; done)
git: 'pish' is not a git command. See 'git --help'.
The most similar command is
push
retry in 1s
git: 'pish' is not a git command. See 'git --help'.
The most similar command is
push
retry in 3s
git: 'pish' is not a git command. See 'git --help'.
The most similar command is
push
retry in 5s
git: 'pish' is not a git command. See 'git --help'.
The most similar command is
push
заменить git pish
на правильныйgit push
✗ DELAYS=(0 1 3 5); (for i in 1 2 3 4; do sleep ${DELAYS[$i]}; git push && break || [ $i -lt 4 ] && echo "retry in ${DELAYS[$i+1]}s"; done)
Everything up-to-date
break
если успехи команды затем, это повредит цикл – Rahul Patil 11.07.2013, 10:39if command; then break; fi
или более кратко простоcommand && break
– tripleee 11.07.2013, 11:05n
отказы, это напрасно спит одно дополнительное время перед выходом. – ron rothman 11.03.2016, 21:17