运行以下脚本后,我收到错误“bash:第 1 行:[:-ne:预期一元运算符”

运行以下脚本后,我收到错误“bash:第 1 行:[:-ne:预期一元运算符”

该脚本提供了预期的输出,但抛出错误“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 会扩展$( ... )和。$UPssh

另外,引号不能嵌套,因此命令字符串中的双引号不会执行您想要的操作 - 每对中的第一个被视为闭引号(匹配其之前的双引号),即假定的部分被引用的部分根本不在引号中,下一个双引号开始一个新的引用部分。因为这些是引号大约参数的各个部分,本地 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"

相关内容