编写 Shell 用于在磁盘 Space 上发送电子邮件的脚本已满 - 需要整数表达式?

Write a Shell Script for sending email on Disk Space Full - integer expression expected?

Shell 脚本编写新手。

我在执行 SH 脚本时遇到以下异常:

/dev/mapper/VolGroup00-root
./DiskSpace.sh: line 7: [: /dev/mapper/VolGroup00-root: integer  expression expected
/ 5.2G
./DiskSpace.sh: line 7: [: /: integer expression expected
29% /dev/xvda1
/dev/mapper/VolGroup00-home
./DiskSpace.sh: line 7: [: /dev/mapper/VolGroup00-home: integer expression expected
/home 5.2G
./DiskSpace.sh: line 7: [: /home: integer expression expected
/dev/mapper/VolGroup00-opt
./DiskSpace.sh: line 7: [: /dev/mapper/VolGroup00-opt: integer expression expected
/opt 5.3G
./DiskSpace.sh: line 7: [: /opt: integer expression expected
/dev/mapper/VolGroup00-var
./DiskSpace.sh: line 7: [: /dev/mapper/VolGroup00-var: integer expression expected
/var 5.3G
./DiskSpace.sh: line 7: [: /var: integer expression expected

以下是我要执行的脚本:

#!/bin/sh
df -H | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print  " "  }' |   while read output;
do
  echo $output
  usep=$(echo $output | awk '{ print }' | cut -d'%' -f1  )
  partition=$(echo $output | awk '{ print  }' )
if [ $usep -ge 90 ]; then
  echo "Running out of space \"$partition ($usep%)\" on $(hostname) as on $(date)" |
  mail -s "Alert: Almost out of disk space $usep%" azrael@opinkerfi.com
fi
done

以下是 df -h 在 linux 系统上的输出:

Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup00-root
                  4.8G  1.9G  2.7G  42% /
tmpfs                 3.9G     0  3.9G   0% /dev/shm
/dev/xvda1            194M   52M  132M  29% /boot
/dev/mapper/VolGroup00-home
                  4.9G  1.9G  2.8G  41% /home
/dev/mapper/VolGroup00-opt
                  5.0G  4.4G  360M  93% /opt
/dev/mapper/VolGroup00-var
                  5.0G  3.7G  1.1G  78% /var

我建议将大部分逻辑从外部命令移到 shell 本身;通过消除对 awk、grep 和 c 的所有不必要调用而节省的性能。不仅可以节省开始 bash 而不是 /bin/sh 的额外费用。

至于眼前的错误,请确保您的值实际上是整数。这意味着不仅要删除 % 符号,还要删除任何小数点。此外,使用 df -P,以确保符合 POSIX 的输出(这将确保您的列号实际上是您认为的内容和位置)。

#!/bin/bash
ignore_re='^Filesystem|tmpfs|cdrom'
while read -r line; do
  [[ $line ]] || continue # skip empty lines
  [[ $line =~ $ignore_re ]] && continue
  read -r filesystem blocks_total blocks_used blocks_avail cap_pct mounted_at _ <<<"$line"
  # below is a noop but makes set -x output more useful
  : filesystem="$filesystem" blocks_total="$blocks_total" blocks_used="$blocks_used" blocks_avail="$blocks_avail" cap_pct="$cap_pct" mounted_at="$mounted_at"
  usep=${cap_pct%"%"} # trim trailing % sign
  usep=${usep%.*}     # round (down) to nearest decimal
  if (( usep >= 90 )); then
    mail -s "Alert: Almost out of disk space $usep%" azrael@opinkerfi.com <<EOF
$filesystem (mounted on $mounted_at) usage is $usep on $(hostname) as of $(date)
EOF
  fi
done < <(df -P)

如果您的 shell 是 bash 4.1 或更新版本,您还可以消除对 $(date) 的外部调用,转而使用 printf 的新 %()T 内置调用 strftime.