スクリプトは予想される出力を提供しますが、「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
。
これら2つの間で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:コマンドを引数ではなくここで引用して渡します(ところで、一般原則も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"