该脚本提供了预期的输出,但抛出错误“bash:第 1 行:[:-ne:预期一元运算符”。技术人员帮助解决这个问题。
#!/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
是用双引号引起来的,因此在命令传递到命令并随后传递到远程 shell之前,本地 shell 会扩展$( ... )
和。$UP
ssh
另外,引号不能嵌套,因此命令字符串中的双引号不会执行您想要的操作 - 每对中的第一个被视为闭引号(匹配其之前的双引号),即假定的部分被引用的部分根本不在引号中,下一个双引号开始一个新的引用部分。因为这些是引号大约参数的各个部分,本地 shell 在将其传递给 之前将其从参数中删除ssh
。
在这两件事之间,假设ntpd
不在本地计算机上运行,以下是实际作为命令传递到远程计算机的内容:
UP= 0;
if [ -ne 1 ];
then
echo NTP is down.;
sudo service ntpd start
else
echo NTP Service is running.;
fi
该[ -ne ]
表达式缺少其左操作数(请记住,引号已被删除),因此[
对此进行了抱怨。我不知道为什么它认为它在第 1 行,因为它对我来说看起来像第 2 行。
解决方案 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"