web-dev-qa-db-ja.com

単項演算子が必要です

#!/bin/bash

SUBJECT="WARNING CPU USAGE HIGH"
TO=gmail id
MESSAGE=/tmp/messages
echo "#######################" > $MESSAGE
echo "CPU statistics as follows.." >> $MESSAGE
mpstat >> $MESSAGE
echo "#######################" >> $MESSAGE
CPU_USAGE=$(top -b -n1 | awk '/^Cpu/ {print $2}' | cut -d. -f1)
[ $CPU_USAGE -gt 85 ] && mail -s "$SUBJECT" "$TO" < $MESSAGE`

./cpu.sh: line 11: [: -gt: unary operator expected理由は何ですか

6

問題

問題は、CPU_USAGEが最終的に空の文字列になることです。これにより、ここで問題が発生します。

[ $CPU_USAGE -gt 85 ] 

Shell変数が評価された後、上記は次のようになります。

[ -gt 85 ] 

-gtの前の引数がなくなったため、これは失敗します。

ソリューション

空でないCPU_USAGEを取得するには、次のものを置き換える必要があります。

CPU_USAGE=$(top -b -n1 | awk '/^Cpu/ {print $2}' | cut -d. -f1)

で:

CPU_USAGE=$(top -b -n1 | awk '/^%Cpu/ {print $2}' | cut -d. -f1)

%が追加されました。

引用

上記のように、CPU_USAGEが空で引用符で囲まれていない場合、「単項演算子」エラーが発生します。

$ CPU_USAGE=""; [ $CPU_USAGE -gt 85 ] && echo yes
bash: [: -gt: unary operator expected

このような状況では、シェル変数を引用することをお勧めします。引用すると、別のエラーメッセージが表示されます。

$ CPU_USAGE=""; [ "$CPU_USAGE" -gt 85 ] && echo yes
bash: [: : integer expression expected

まだエラーが表示されますが、このエラーメッセージは少なくともより多くの情報を提供します。$CPU_USAGEは数字ではないということです。

単純化

cutプロセスは必要ありません。交換できます:

CPU_USAGE=$(top -b -n1 | awk '/^%Cpu/ {print $2}' | cut -d. -f1)

で:

CPU_USAGE=$(top -b -n1 | awk -F'[ .]+' '/^%Cpu/ {print $2}')
7
John1024

あなたのライン

top -b -n1 | awk '/^Cpu/ {print $2}' | cut -d. -f1

間違っています。まず、AWKにCpuで始まる行を検索するように要求していますが、実際には%Cpuで始まります。

第二に、cut部分は必要ありません。 awkを直接使用できます。

$ top -b -n1 | awk '/^%Cpu/ {gsub(/\./," ");print $2}'                                             
31

将来的には、set -x行の後のスクリプトの先頭で#!/bin/bashを使用してスクリプトをデバッグできます。また、シェルスクリプトの構文をチェックする https://www.shellcheck.net/ を使用します

4