Ошибка при сравнении целых чисел с десятичной запятой в сценарии bash

Предполагая под датой создания, вы имеете в виду время последнего изменения файла (как сообщается в ls -l), то с GNU find, вы можете сделать (здесь используя формат RFC 4180 CSV):

find . -regextype posix-extended \
       -regex '.*\([0-9]{4}\)\.[[:alnum:]]+' \
       -type f \
       -printf '%TF/%f\0' |
  perl -l -0pe '
    s/"/""/g;
    s{(.*)/(.*?)\s*\((\d{4})\)\.([^.]*)$}{"$2",$3,$4,$1\r}s'

0
17.11.2018, 22:15
7 ответов
set -- $(cat /proc/loadavg)
load=${2/./}
if [ "$load" -ge 500 ]; then
  echo alert
fi

Получите среднее значение нагрузки из /proc и установите параметры позиционирования на основе этих полей. Возьмите второе поле и удалите точку. Если это (теперь числовое) значение больше или равно 500, выдается предупреждение. Это предполагает (текущее) поведение, при котором средние значения нагрузки представлены с точностью до двух знаков после запятой. Спасибо Arrowза указание лучшего способа.

1
28.01.2020, 02:14

Для сравнения можно использовать только целую часть:

load=$(awk '{print $2}' /proc/loadavg | cut -d. -f1)
2
28.01.2020, 02:14

Короткий ответ: вы не можете этого сделать. На самом деле, bash не может этого сделать, хотя вы, человек, можете это сделать. Подробнее см. https://stackoverflow.com/questions/11541568/how-to-do-float-comparison-in-bash.

1
28.01.2020, 02:14

Поскольку у вас есть awk и он может обрабатывать значения с плавающей запятой, сделайте:

awk '($1>5){print("yes")}'

Отредактированный скрипт:

#!/bin/bash

load=`echo $(cat /proc/loadavg | awk '{print $2}')`
loadtest=$(echo "$load" | awk '($1>5){print("yes")}')
if [ "$loadtest" = yes ]; then
    echo "foo alert!"
fi

конечно, весь скрипт можно упростить, используя только awk .

Возможно:

#!/bin/bash
awk '($2>5){print("foo alert!")}' /proc/loadavg
2
28.01.2020, 02:14

Преобразование в целое число и массив может быть кратчайшим способом:

!/bin/bash
# Remove decimal point (multiply by 100) and put it into an array
declare -a load=( $(tr -d . < /proc/loadavg) )
if [ ${load[0]} -gt 500 ]; then
    echo "foo alert!"
fi
echo "System Load $(cat /proc/loadavg)"
0
28.01.2020, 02:14

Я по-прежнему отдаю должное @jeff -Schaller, но для полноты картины я применил вот такой подход:

#!/bin/bash

#Threshold value for minimum load average necessary to trigger an alert. 
loadthreshold=30

#Admin defined value for where to send email alert
alertrecipient=foo@fooexample.blah

#Time/date for filename saving later.
logtimestamp=`date +%Y-%m-%d.%H-%M-%S`

#Check the load average value for the past 5-minute time span.
load=`echo $(cat /proc/loadavg | awk '{print $2}')`

#Truncate the load average value (leaving off the fractional values) and trigger an alert action if it's greater than (or equal to) the admin-defined threshold.
if [ "${load%.*}" -ge "$loadthreshold" ]; then
    echo "Yo admin, your system load average is pretty high: $load.  Check the server  " | mail -s "System load average spike detected" "$alertrecipient"
    tar cvzf "high-la-logs$logtimestamp.tar.gz" /var/log/ 
fi

Единственная реальная разница заключается в использовании "${load%.*}", чтобы отсечь материал справа от десятичной дроби.

0
28.01.2020, 02:14

bashне может работать с плавающей запятой. Используйте zsh, ksh93или yashвместо :

.
#! /bin/zsh -
read ignore load ignore < /proc/loadavg || exit
if ((load > 5)); then
  echo >&2 Alert
fi

Или поскольку вы уже используете awk(вместе с несколькими ненужными командами):

#! /bin/sh -
awk '$2 > 5 {print "Alert"}' < /proc/loadavg >&2

Или, если вам это нужно в конструкцииshif:

#! /bin/sh -
if awk '{exit !($2 > 5)}' < /proc/loadavg; then
  echo >&2 Alert
fi
1
28.01.2020, 02:14

Теги

Похожие вопросы