내 서버를 지속적으로 테스트하고 서버가 다운되면 나에게 이메일을 보내기 위해 여기에 쉘 스크립트를 작성하려고 합니다.
문제는 ssh 연결에서 로그아웃할 때 &
명령 끝에서 실행했음에도 불구하고 ./stest01.sh &
자동으로 else에 빠지고 다시 로그인하여 종료할 때까지 계속 메일을 보낸다는 것입니다.
#!/bin/bash
while true; do
date > sdown.txt ;
cp /dev/null pingop.txt ;
ping -i 1 -c 1 -W 1 myserver.net > pingop.txt &
sleep 1 ;
if
grep "64 bytes" pingop.txt ;
then
:
else
mutt -s "Server Down!" [email protected] < sdown.txt ;
sleep 10 ;
fi
done
답변1
grep
GNU가 결과를 쓰려고 하면 SSH 연결이 끊어지고 출력을 쓸 곳이 없기 때문에 0이 아닌 종료 상태로 실패합니다.
이는 if
명령문이 항상 else
분기를 취함을 의미합니다.
이것을 설명하기 위해(이것은 아닙니다.정확히현재 상황은 다음과 같습니다. 그러나 grep
GNU가 출력을 작성할 수 없는 경우 어떤 일이 발생하는지 보여줍니다.
$ echo 'hello' | grep hello >&- 2>&-
$ echo $?
2
여기에 grep
생성된 문자열이 있지만 어디에도 쓸 수 없도록 echo
두 출력 스트림을 모두 닫습니다 . grep
보시다시피, GNU의 종료 상태는 grep
0이 아닌 2입니다.
이는 GNU에만 해당되며 grep
BSD grep
시스템에서는 동일하게 작동하지 않습니다.
$ echo 'hello' | grep hello >&- 2>&- # using BSD grep here
$ echo $?
0
이 문제를 해결하려면 스크립트가 출력을 생성하지 않는지 확인하십시오. 를 사용하여 이 작업을 수행할 수 있습니다 exec >/dev/null 2>&1
. 또한 우리는 다음에 관심이 있으므로 옵션을 grep
사용해야 합니다.-q
보다출력( grep
전체 파일을 구문 분석할 필요가 없기 때문에 일반적으로 더 빠르지만 이 경우 파일이 작기 때문에 속도 차이가 최소화됩니다).
간단히 말해서:
#!/bin/sh
# redirect all output not redirected elsewhere to /dev/null by default:
exec >/dev/null 2>&1
while true; do
date >sdown.txt
ping -c 1 -W 1 myserver.net >pingop.txt
if ! grep -q "64 bytes" pingop.txt; then
mutt -s "Server Down!" [email protected] <sdown.txt
break
fi
sleep 10
done
또한 중간 파일 중 하나가 필요하지 않고 테스트를 직접 사용할 수도 있습니다 ping
(실제로 날짜 스탬프만 포함하는 다른 중간 파일도 제거됨).
#!/bin/sh
exec >/dev/null 2>&1
while true; do
if ! ping -q -c 1 -W 1 myserver.net; then
date | mutt -s "Server Down!" [email protected]
break
fi
sleep 10
done
위 스크립트의 두 변형 모두에서 전송되는 이메일 수를 최소화하기 위해 호스트에 연결할 수 없을 때 루프를 종료하도록 선택했습니다. 서버를 결국 다시 시작하려면 break
예를 들어 서버를 다른 것으로 바꿀 수 있습니다.sleep 10m
ping
-i 1
와 함께 사용하는 것이 별로 의미가 없기 때문에 와 함께 사용되는 옵션도 약간 조정했습니다 -c 1
.
더 짧게(호스트에 연결할 수 없을 때 이메일을 계속 보내려는 경우 제외):
#!/bin/sh
exec >/dev/null 2>&1
while ping -q -c 1 -W 1 myserver.net; do
sleep 10
done
date | mutt -s "Server Down!" [email protected]
1분마다 실행되는 크론 작업(서버가 계속 다운되면 이메일은 1분마다 계속 전송됩니다):
* * * * * ping -q -c 1 -W 1 >/dev/null 2>&1 || ( date | mail -s "Server down" [email protected] )