Bash команда для проверки свободного места на диске (была «проверить значение десятичного числа») - PullRequest
0 голосов
/ 05 апреля 2020

У меня есть этот код, который проверяет, остается ли дисковое пространство на указанном диске c, а затем запускает набор команд.

if [ "$(echo "$(df -h | awk '$1 == "drive_name" {print $4}' | sed 's/[T]//') >= 0.2" | bc)" -eq 1 ]; then 
    <run_these_commands>; 
else 
    <run_other_commands>; 
fi

Работает, но [] test беспорядок. Есть ли лучший способ сделать это?

Ответы [ 3 ]

4 голосов
/ 05 апреля 2020

Делайте все с правильными df аргументами:

declare -- drive='/'
declare -i minsize=$((2*10**11)) # 200 GB
if (($(df -B1 --output=avail "$drive" | tail -1)>=minsize))
then
   printf 'There is more than 200 GB left on %s\n' "$drive"
else
   printf 'There is less than 200 GB left on %s\n' "$drive"
fi

df:

  • -B1: устанавливает размер блока отображения в 1 байт, так что это всегда целое число.

  • --output=avail: отображает только доступное поле.

  • "$drive": показывать только для устройства или точка монтирования

| tail:

  • -1: показать только последнюю строку (пропустить строки заголовка, поэтому он возвращает только целое число байтов свободного пространства ).

((…)): Bash допускает автономную арифметику c, поэтому используйте ее в условии if. Поскольку обрабатываются только целочисленные значения, оболочка может обрабатывать ее без необходимости bc.

1 голос
/ 05 апреля 2020

В качестве списка итеративных улучшений я бы предложил следующее:

  • Вместо сравнения выходных данных от bc до 1 используйте условную конструкцию ((...)) , который возвращает статус успешного завершения для 1, т.е. переводит вывод bc напрямую. Это позволяет нам отбросить внешнюю подстановку команд и -eq 1:

    if (($(echo "$(df -h | awk '$1 == "drive_name" {print $4}' | sed 's/[T]//') >= 0.2" | bc))); then
    
  • Вместо echo "$(cmd) >= 0.2 | bc мы можем использовать bc <<< "$cmd >= 0.2", что спасает нас от подоболочек и является немного короче:

    if (($(bc <<< "$(df -h | awk '$1 == "drive_name" {print $4}' | sed 's/[T]//') >= 0.2"))); then
    
  • T в команде sed не нужно go заключать в квадратные скобки, это не особенное:

    if (($(bc <<< "$(df -h | awk '$1 == "drive_name" {print $4}' | sed 's/T//') >= 0.2"))); then
    
  • На самом деле нам вообще не нужен sed для удаления T:

    if (($(bc <<< "$(df -h | awk '$1 == "drive_name" {sub(/T/, "", $4); print $4}') >= 0.2"))); then
    
  • Нам также не нужно bc, потому что awk может сравниваться с самим 0.2:

    if (($(df -h | awk '$1 == "drive_name" {sub(/T/, "", $4); print $4 >= 0.2}'))); then
    
  • Мы можем избавиться от всего бизнеса T, не используя флаг -h и сравнивая его с килобайтами вместо терабайтов:

    if (($(df | awk '$1 == "drive_name" {print $4 >= 0.2*1e9}'))); then
    

    (Это на самом деле не совсем то же самое, поскольку df -h использует кратные 1024, но, вероятно, достаточно хорошо.)

  • Мы можем сказать df просто чтобы рассказать нам о интересующей нас файловой системе, мы точно знаем, что нужная нам информация находится во второй строке вывода:

    if (($(df drive_name | awk 'NR == 2 {print $4 >= 0.2*1e9}'))); then
    
  • Мы можем иметь df дайте нам только доступное пространство:

    if (($(df --output=avail drive_name | awk 'NR == 2 {print $1 >= 0.2*1e9}'))); then
    
  • И, наконец, мы можем сделать сравнение в Bash напрямую, нам просто нужно что-то удалить в первой строке вывода df :

    if (($(df --output=avail drive_name | sed '1d') >= 2*10**8)); then
    

    Обратите внимание, что мы переключились с 0.2e9 на 2 * 10**8, чтобы обойти с помощью плавающей запятой.

0 голосов
/ 05 апреля 2020

Для простой команды вы можете использовать:

[ $(df -m --output=avail /|tail -n1) -lt 200 ] && echo issue || echo not issue

или с , если , чтобы сделать его более читабельным:

if [ $(df -m --output=avail /|tail -n1) -lt 200 ]; then
 commands
else
  commands
fi

-m означает мегабайт. Вы можете использовать тестовую команду для сравнения (-lt означает меньше)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...