web-dev-qa-db-fra.com

Opérateur unaire attendu

#!/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 Quelle pourrait être la raison

6
darshan krishnaiah

Le problème

Le problème est que CPU_USAGE finit comme une chaîne vide. Cela pose un problème ici:

[ $CPU_USAGE -gt 85 ] 

Une fois la variable Shell évaluée, ce qui précède devient:

[ -gt 85 ] 

Cela échoue car l'argument précédant le -gt est maintenant manquant.

La solution

Pour obtenir un CPU_USAGE non vide, nous devons remplacer:

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

avec:

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

où un % a été ajouté.

Citant

Comme mentionné ci-dessus, lorsque CPU_USAGE est vide et non cité, nous obtenons l'erreur "Opérateur unaire":

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

Il est recommandé de citer les variables Shell dans des situations comme celle-ci. Si nous le citons, nous obtenons un message d'erreur différent:

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

Bien que nous obtenions toujours une erreur, ce message d'erreur est au moins plus informatif: il indique que $CPU_USAGE n'est pas un nombre.

Simplification

Le processus cut n'est pas nécessaire. Nous pouvons remplacer:

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

avec:

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

Votre ligne

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

est incorrect. Tout d'abord, vous demandez à AWK de trouver la ligne commençant par Cpu, alors qu'en fait, elle commence par %Cpu.

Deuxièmement, vous n’avez pas besoin de la partie cut. Vous pouvez utiliser awk directement:

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

À l'avenir, vous pourrez déboguer les scripts avec set -x en haut du script après la ligne #!/bin/bash. Utilisez également https://www.shellcheck.net/ qui vérifiera la syntaxe d'un script Shell

4