스크립트는 예상되는 출력을 제공하지만 "bash: line 1: [: -ne: unary 연산자가 예상됨" 오류를 발생시킵니다. 기술자가 문제 해결을 돕습니다.
#!/bin/bash
USR="root"
# Email
SUBJECT="NTP Service Status Report"
EMAIL="[email protected]"
EMAILMESSAGE="/tmp/ntp_status.txt"
# create new file
>$EMAILMESSAGE
# connect each host and pull up user listing
for host in `cat SAP_Prod_servers_51`
do
echo "--------------------------------" >>$EMAILMESSAGE
echo "* HOST: $host " >>$EMAILMESSAGE
echo "--------------------------------" >>$EMAILMESSAGE
ssh $USR@$host "UP=$(ps -ef | grep -v grep | grep ntpd | wc -l);
if [ "$UP" -ne 1 ];
then
echo "NTP is down.";
sudo service ntpd start
else
echo "NTP Service is running.";
fi" >> $EMAILMESSAGE
done
# send an email using /bin/mail
/bin/mail -s "$SUBJECT" "$EMAIL" < $EMAILMESSAGE
답변1
기본적인 문제는 전송되는 명령이 ssh
큰따옴표로 묶여 있으므로 로컬 쉘이 $( ... )
및 를 확장한다는 것입니다.$UP
ssh
또한 따옴표는 중첩될 수 없으므로 명령 문자열의 큰 따옴표는 원하는 대로 작동하지 않습니다. 각 쌍의 첫 번째는 닫는 따옴표(앞의 큰 따옴표와 일치)로 처리됩니다. 부분이 전혀 따옴표로 묶이지 않은 경우 다음 큰따옴표는 새로운 인용 부분을 시작합니다. 따옴표이기 때문에에 대한로컬 셸이 인수를 전달하기 전에 인수에서 제거하는 인수의 다양한 부분입니다 ssh
.
이 두 가지 사이에서 ntpd
로컬 시스템에서 실행되지 않는다고 가정하면 실제로 원격 시스템에 명령으로 전달되는 내용은 다음과 같습니다.
UP= 0;
if [ -ne 1 ];
then
echo NTP is down.;
sudo service ntpd start
else
echo NTP Service is running.;
fi
표현식 [ -ne ]
에 왼쪽 피연산자가 누락되어(따옴표가 제거되었음을 기억하세요) 이에 [
대한 불만이 제기됩니다. 나에게는 2행처럼 보이기 때문에 왜 1행에 있다고 생각하는지 모르겠습니다.
해결 방법 1: 전체 명령 주위에 작은따옴표를 사용합니다. 작은따옴표가 없기 때문에 중첩은 문제가 되지 않으며 작은따옴표는 확장을 억제합니다.모든 것이므로 $
원격 시스템에서 다양한 확장이 발생합니다.
해결 방법 2: 명령을 인수가 아닌 여기 문서에서 인용하여 전달합니다(그런데 일반 원칙도 두 번 인용 $EMAILMESSAGE
하고 필요하지 않은 줄 끝에서 세미콜론을 제거했습니다).
ssh $USR@$host >> "$EMAILMESSAGE" <<'EOF'
UP=$(ps -ef | grep -v grep | grep ntpd | wc -l);
if [ "$UP" -ne 1 ]
then
echo "NTP is down."
sudo service ntpd start
else
echo "NTP Service is running."
fi
EOF
해결 방법 3: 변수를 건너뛰고 직접 grep -q
테스트 로 사용하고 if
내부 큰따옴표를 이스케이프 처리하거나 작은따옴표로 전환합니다.
ssh $USR@$host "if ps -ef | grep -v grep | grep -q ntpd
then
echo \"NTP is down.\"
sudo service ntpd start
else
echo \"NTP Service is running.\"
fi" >> "$EMAILMESSAGE"