Unary operator expected
Solution 1
The problem
The problem is that CPU_USAGE
ends up as an empty string. This causes a problem here:
[ $CPU_USAGE -gt 85 ]
After the shell variable is evaluated, the above becomes:
[ -gt 85 ]
This fails because the argument before the -gt
is now missing.
The solution
To get a non-empty CPU_USAGE
, we need to replace:
CPU_USAGE=$(top -b -n1 | awk '/^Cpu/ {print $2}' | cut -d. -f1)
with:
CPU_USAGE=$(top -b -n1 | awk '/^%Cpu/ {print $2}' | cut -d. -f1)
where a %
was added.
Quoting
As mentioned above, when CPU_USAGE
is empty and unquoted, we get the "Unary operator" error:
$ CPU_USAGE=""; [ $CPU_USAGE -gt 85 ] && echo yes
bash: [: -gt: unary operator expected
It is best practice to quote shell variables in situations like this. If we do quote it, then we get a different error message:
$ CPU_USAGE=""; [ "$CPU_USAGE" -gt 85 ] && echo yes
bash: [: : integer expression expected
While we still get an error, this error message is at least more informative: it says that $CPU_USAGE
is not a number.
Simplification
The cut
process is not needed. We can replace:
CPU_USAGE=$(top -b -n1 | awk '/^%Cpu/ {print $2}' | cut -d. -f1)
with:
CPU_USAGE=$(top -b -n1 | awk -F'[ .]+' '/^%Cpu/ {print $2}')
Solution 2
Your line
top -b -n1 | awk '/^Cpu/ {print $2}' | cut -d. -f1
is incorrect. First of all , you're asking AWK to find line starting with Cpu
, when in fact it starts with %Cpu
.
Second, you dont need cut
part. You can use awk
directly:
$ top -b -n1 | awk '/^%Cpu/ {gsub(/\./," ");print $2}'
31
For future, you can debug scripts with set -x
at the top of the script after #!/bin/bash
line. Also , use https://www.shellcheck.net/ which will check the syntax of a shell script
Related videos on Youtube
darshan krishnaiah
Updated on September 18, 2022Comments
-
darshan krishnaiah over 1 year
#!/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
What might be the reason -
darshan krishnaiah over 7 yearsI have made the necessary changes and the script has executed error free. But the script is unable to send the mail to the respective mail id. Since i am using ubuntu i have installed
apt-get install mailutils
. The mail is sent to/var/mail/root
instead of the given mail id. -
John1024 over 7 years@darshankrishnaiah I'm glad that helped. Your
mail
command works fine for me but I am using BSD-mailx. Unfortunately, I have no experience with GNU'smailutils
.