Score:3

Two conditions in if statment

la flag

I'm struggling in if statment

I want the message "The system is highly utilized" pops whenever the memory usage or cpu usage exceeds 70%, now i tried the following 2 conditions in if statment but it gives me 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

as far as i know the ; runs checks 1st condition and then goes to the 2nd regardless of success. I get this error anyways: 0 : syntax error in expression (error token is "0 ")

ar flag
Which distro and version of Linux are you using? Why do you have `echo` inside `if`? You don't need it.
linuxnoobie avatar
la flag
I'm using Ubuntu 22.04.2 LTS
Score:7
tm flag

bc understands || and &&.

if (( $(echo "$cpuUsage > $limit || $memUsage > $limit" | bc -l) ))
linuxnoobie avatar
la flag
Thank you so much :)
Raffa avatar
jp flag
I guess `bc` can be avoided altogether if the floating points are brought to integers that can be calculated/evaluated in `bash` alone ... e.g. multiplying `$limit`, `$cpuusage`, and `$memusage` by a `100`. see for example: https://askubuntu.com/a/1452588
Score:2
hr flag

Although (as you have seen), you can combine expressions using logical || in GNU bc (and in busybox bc), it's not supported by POSIX1.

Since you're already using awk to parse the top and free outputs, an alternative approach would be to do the arithmetic and relational testing in awk as well - then you can use simple integer comparison in the shell (not even requiring 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. in fact, POSIX bc doesn't even support relational operators outside of a conditional construct or loop, ex.:

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

    but with warnings enabled:

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

    and similarly with busybox

     $ 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
    
linuxnoobie avatar
la flag
Thank you mate :)
Score:0
cn flag

To expand a bit on @choroba's answer:

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

will output 2 lines.

A demonstration

$ 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 ")
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.