답변:
이 스크립트는 카운터 n
를 사용 하여 명령 시도를 5 개로 제한합니다. 명령이 성공 $?
하면 0을 유지하고 루프에서 실행이 중단됩니다.
n=0
until [ $n -ge 5 ]
do
command && break # substitute your command here
n=$[$n+1]
sleep 15
done
if command; then break; fi
간결하게 표현 된 것입니다command && break
n
장애가 발생한 경우 종료하기 전에 한 번 더 잠을 자지 않습니다.
for i in 1 2 3 4 5; do command && break || sleep 15; done
"command"를 명령으로 바꾸십시오. "status code = FAIL"은 0이 아닌 리턴 코드를 의미한다고 가정합니다.
{..}
구문을 사용 합니다. 대부분의 쉘에서 작동하지만 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}
는 유지하기 쉽기 때문.
command
실패 하더라도 코드 0을 반환 합니다.
[[ i -eq 5]]
이것을 피하기 위해 수면 전에 OR 상태로 검사를 할 수 있다고 생각합니다 .
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
복잡한 명령을 사용한 실제 작업 예제는 이 스크립트를 참조하십시오 .
다시 시도하는 기능은 다음과 같습니다.
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 ::
bash retry.sh 3 ping -c1 localhost
여기 내가 좋아하는 한 줄 별칭 / 스크립트가 있습니다.
alias retry='while [ $? -ne 0 ] ; do fc -s ; done'
그런 다음 다음과 같은 작업을 수행 할 수 있습니다.
$ ps -ef | grep "Next Process"
$ retry
"Next Process"를 찾을 때까지 이전 명령을 계속 실행합니다.
fc -e "#"
대신 사용하십시오 fc -s
.
주어진 명령을 재 시도하는이 스크립트를 사용하는데,이 스크립트의 장점은 모든 재 시도에 실패하면 종료 코드를 보존한다는 것입니다.
#!/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
아마도 더 간단해질 수 있습니다.
아래 예를 참조하십시오.
n=0
while :
do
nc -vzw1 localhost 3859
[[ $? = 0 ]] && break || ((n++))
(( n >= 5 )) && break
done
localhost에서 포트 3389를 연결하려고하는데 5 번 실패 할 때까지 재 시도합니다. 성공하면 루프가 끊어집니다.
$?
0이 아닌 경우 명령이 성공적으로 실행되면 명령 상태가 존재하고, 0이 아닌 경우 명령이 실패하면 명령 상태가 존재 함
약간 복잡해 보입니다. 누군가 이것보다 더 잘할 수 있습니다.
$?
0이 아닌 경우 명령이 성공적으로 실행되면 명령 상태가 존재합니다. 0이 아닌 경우 명령이 실패하면
retry
함수형 프로그래밍 전문가를위한 재귀 함수는 다음과 같습니다 .
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
}
다음과 같이 명령 (또는 함수 이름)과 선택적으로 여러 번의 재시도 및 재시도 사이의 휴면 시간을 전달하십시오.
retry some_command_or_fn 5 15 # 5 tries, sleep 15 seconds between each
break
명령의 성공이 다음 루프 중단 할 경우