if文の2つの条件

if文の2つの条件

if文で苦労しています

メモリ使用量または CPU 使用量が 70% を超えるたびに「システムの使用率が高い」というメッセージが表示されるようにしたいのですが、if ステートメントで次の 2 つの条件を試しましたが、エラーが発生します。

# 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

私の知る限り、; は最初の条件をチェックし、成功に関係なく 2 番目の条件に進みます。とにかく、次のエラーが発生します: 0: 式の構文エラー (エラー トークンは "0 " です)

答え1

bc理解||し、&&

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

答え2

(すでに見たように) ||GNU bc (および busybox bc) では論理を使用して式を組み合わせることができますが、これは POSIX 1ではサポートされていません。

topすでに awk を使用して出力を解析しているのでfree、別の方法としては、算術テストと関係テストも awk で実行します。そうすれば、シェルで単純な整数比較を使用できます (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. 実際、POSIX bc は条件構文やループの外側では関係演算子をサポートしていません。例:

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

    ただし警告が有効になっている場合:

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

    同様に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
    

答え3

@choroba の回答を少し詳しく説明します:

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

出力します2行

デモンストレーション

$ 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 ")

関連情報