Dos condiciones en la declaración if

Dos condiciones en la declaración if

Estoy luchando con la declaración if

Quiero que aparezca el mensaje "El sistema está muy utilizado" cada vez que el uso de la memoria o el uso de la CPU supere el 70%. Ahora probé las siguientes 2 condiciones en la declaración if pero me da un error.

# This script monitors CPU and memory usage
RED='\033[0;31m'
NC='\033[0m' # No Color


while :
do
  # Get the current usage of CPU and memory

  limit=70.0
  cpuUsage=$(top -bn1 | awk '/Cpu/ { print $2}')
  memTotal=$(free -m | awk '/Mem/{print $2}')
  memUsage=$(free -m | awk '/Mem/{print $3}')
  memUsage=$(( (memUsage * 100) / memTotal ))

  # Print the usage
  echo "CPU Usage: $cpuUsage%"
  echo "Memory Usage: $memUsage%"
  # Sleep for 1 second
  sleep 1

  if  (( $(echo "$cpuUsage > $limit ; $memUsage > $limit" |bc -l) ))
  then
         printf "${RED}The system is highly utilized${NC}\n"
  else
        echo The system is not highly utilized
  fi
done

Hasta donde yo sé; ejecuta verifica la primera condición y luego pasa a la segunda independientemente del éxito. De todos modos recibo este error: 0: error de sintaxis en la expresión (el token de error es "0")

Respuesta1

bcentiende ||y &&.

if (( $(echo "$cpuUsage > $limit || $memUsage > $limit" | bc -l) ))

Respuesta2

Aunque (como ha visto) puede combinar expresiones usando lógica en GNU bc (y en Busybox bc), POSIX 1|| no lo admite .

Dado que ya está usando awk para analizar las salidas topy free, un enfoque alternativo sería realizar también las pruebas aritméticas y relacionales en awk; luego puede usar una comparación de enteros simple en el shell (sin siquiera requerir bash):

#!/bin/sh

# This script monitors CPU and memory usage

RED='\033[0;31m'
NC='\033[0m' # No Color

limit=${1:-70.0}

while :
do
  # Get the current usage of CPU and memory
  top -bn1 | awk -v limit="$limit" '
    /^%Cpu/ {printf "CPU Usage: %.1f%%\n", $2; exit ($2+0 > limit ? 1 : 0)} 
  '
  cpuHi=$?

  free -m | awk -v limit="$limit" '
    /^Mem/ {usage = 100*$3/$2; printf "Memory Usage: %.0f%%\n", usage; exit (usage > limit ? 1 : 0)}
  '
  memHi=$?

  sleep 1

  if [ "$cpuHi" -ne 0 ] || [ "$memHi" -ne 0 ]
  then
         printf "${RED}The system is highly utilized${NC}\n"
  else
        printf "The system is not highly utilized\n"
  fi

done

  1. de hecho, POSIX bc ni siquiera admite operadores relacionales fuera de una construcción o bucle condicional, por ejemplo:

     $ echo '2 > 1 || 1 > 2' | bc
     1
    

    pero con las advertencias habilitadas:

     $ echo '2 > 1 || 1 > 2' | bc -w
     (standard_in) 1: (Warning) || operator
     (standard_in) 2: (Warning) comparison in expression
     1
    

    y de manera similar con ocupadobox

     $ echo '2 > 1 || 1 > 2' | busybox bc -w
     bc: POSIX does not allow boolean operators; this is bad: ||
     bc: POSIX does not allow comparison operators outside if or loops
     1
    

Respuesta3

Para ampliar un poco la respuesta de @choroba:

echo "$cpuUsage > $limit ; $memUsage > $limit" |bc -l

saldrá2 lineas.

una demostracion

$ set -x
+ set -x
$ ans=$(echo "1==1; 2==1" | bc -l)
++ bc -l
++ echo '1==1; 2==1'
+ ans='1
0'
$ if (( $ans )); then echo yes; fi
+ ((  1
0  ))
bash: ((: 1
0 : syntax error in expression (error token is "0 ")

información relacionada