но я оставлю это как просто комментарий сейчас.

о нужно сделать что-то простое, что я мог бы сделать самостоятельно, но оказалось, что у меня есть сомнения в результате, который я получаю ...

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

ssh server1 df -mP | egrep "/dev/md10|/dev/md11" | sort ; ssh server1 df -mP --total | grep "total" | egrep -v "/dev/md10|/dev/md11

Результат:

/dev/md10                                                   183004016  87303581  95700436      48% /si001c1
/dev/md11                                                   183004016 165986430  17017587      91% /si001c2
total                                                       366565396 253332843 113232554      70%

И затем я использовал ту же команду на 2-м сервере, чтобы получить общий итог. Мой вопрос, общий итог, который я получаю, кажется неправильным (я не уверен) и как произвести общий итог, комбинируя оба с использованием одной и той же команды в любом случае, используя однострочную команду или как базовый скрипт в bash. Спасибо за помощь.

Обновление: это обновление после следования руководству от @EdmCoff.

printf "Grand total: " ; (ssh server1 df -m /dev/md11 ; ssh server2 df -m /dev/md1*) | awk 'a+=$2;b+=$3;c+=$4;d+=$5/3} END {print a" "b" "c" "d%}'

Результат:

Grand total: 549012050 501832399 47179652 92%

Встроенный скрипт (переделано):

#!/bin/bash
(ssh server1 df -m --no-sync "/dev/md11" ; ssh server2 df -m --no-sync "/dev/md1*") | sed -e /^Filesystem/d | sort > df_udsall
#(cat df_udsall)
printf "\nUDS:\nserver1 & server2\n"
printf "Mounted on       Free space   Disk usage   Use"%%"   Disk state"
while read df_udsall 
do
USAGE=$(echo $df_udsall ; echo $grand_total) | awk '{print $5}' | cut -d"%" -f1
if [[ "$USAGE" -ge " 95" ]]
then
STATUS='CRITICAL'
elif [[ "$USAGE" -ge " 90" ]]
then
STATUS='WARNING'
else
STATUS='OK'
fi
printf "$(echo $df_udsall | awk '{print $6, $4, $3, $5}' > df_udsall_stats)"
column -t df_udsall_stats | perl -ne 'chomp ; printf "\n%-18s %8s %12s %6s %-2s", split / +/' ; printf "`echo -ne $STATUS`"
done < df_udsall
printf "\n\nGrand total " ; cat df_udsall | awk '{b+=$4;c+=$3;d+=$5/3} END {print b" "c" "d "%"}' > grand_total
column -t grand_total | perl -ne 'chomp ; printf "%15s %12s %6s %-2s", split / +/' ; printf "`echo -ne $STATUS`"
rm -f df_udsall df_udsall_stats grand_total

Сценарий выше нуждается в тонкой настройке.

Ожидаемый результат:

UDS:
server1 & server2
Mounted on         Free space   Disk usage   Use%   Disk state
/sic1                16202762    166801255    92%   WARNING
/sic2                15648157    167355860    92%   WARNING
/sic3                15256569    167747448    92%   WARNING

Grand total:         47107488    501904563    92%   OK

Исправлен результат вывода скрипта tripleee:

UDS:
server1 & server2
Mounted on         Free space   Disk usage   Use%   Disk state
/sic001c1          92146461     90857556    50% OK
/sic001c2          16873531    166130486    91% WARNING
/sic001c3          16832710    166171307    91% WARNING
/sic001c4          16362388    166641629    92% WARNING

Grand total:       142215090    589800978     81 OK%
 Inian28 дек. 2017 г., 06:38
Там будетвсегда несколько% файловой системы зарезервировано дляroot пользователь. Так что это не удивительно, что ваш итог не складывается
 emilee28 дек. 2017 г., 07:55
@EdmCoff спасибо за команду, но я все же предпочитаю что-то более или менее получать одинаковые результаты на обоих серверах, как упомянуто выше. Я не парень из Linux, но мне нравится играть каждый день из-за моего любопытства попробовать что-то отличное от других ОС. Я пытаюсь запустить команду(ssh server1 df -mP --total /dev/md1* ; ssh server2b df -mP --total /dev/md1*) | awk '/total/ {a+=$2;b+=$3;c+=$4} END {print a" "b" "c}' но результат не такой, как ожидалось. Хорошо узнать какую-то новую команду, которую я на самом деле не знал.
 EdmCoff30 дек. 2017 г., 06:09
Извините, я неправильно понял, что вы имели в виду под общим итогом (я думал, что вы хотите объединить итоги с двух серверов). Мое предложение по-прежнему awk, если вы хотите суммировать три столбца одновременно. Так,ssh server1 df -mP /dev/md1* | awk '{a+=$2;b+=$3;c+=$4} END {print a" "b" "c}' (т. е. ваша командабез сумма и сумма всех столбцов) илиssh server1 df -mP --total /dev/md1* | awk '!/total/ {a+=$2;b+=$3;c+=$4} END {print a" "b" "c}' (т.е. включите сумму в вашу команду, но исключите ее в команду awk).
 EdmCoff30 дек. 2017 г., 06:12
Если вы действительно хотите использовать bc, я бы предложил что-то вродеssh server1 df -mP /dev/md1* | tr -s ' ' | cut -d" " -f 2,2 | paste -sd+ - | bc где я используюtr команда заменить несколько пробелов одним пробелом,cut команда, чтобы получить только второй столбец чисел,paste команда переформатировать столбец как num1 + num2 + num3 + и так далее, иbc Команда сделать математику. Очевидно, вам нужно изменить команду вырезания для любого столбца, который вы хотите суммировать.
 EdmCoff28 дек. 2017 г., 06:48
Чтобы объединить две команды для общего итога, вы рассматривали возможность использования awk? Я представляю что-то вроде(command for server 1; command for server 2) | awk '/total/ {a+=$2;b+=$3;c+=$4} END {print a" "b" "c}'

Ответы на вопрос(1)

Решение Вопроса

где Awk полностью контролирует вычисления и форматирование вывода, как предложено в нескольких комментариях. У меня есть встроенные комментарии, которые вы можете удалить.

#!/bin/bash
# use a loop to reduce duplication of ssh options etc
while read -r server mounts; do
    ssh "$server" df -m --no-sync $mounts </dev/null
done <<\____SERVER__MOUNTS |
    server1 /dev/md10 /dev/md11
    server2 /dev/md12 /dev/md13
____SERVER__MOUNTS
# sed -e /^Filesystem/d inlined into Awk below
sort |
# pipe into awk
awk 'BEGIN { print "UDS:\nserver1 & server2"
        # Maybe use printf here too
        print "Mounted on         Free space   Disk usage   Use%   Disk state"
        fmt="%-18s %8i %12i %6s %-2s"
    }
    function status(num) {
        # Awk conveniently ignores any trailing string
        # so you can compare 95% to 95 numerically
        if (num > 95) result="CRITICAL"
        else if (num > 90) result="WARNING"
        else result="OK"
        return(result)
    }
    ! /^Filesystem/ {
        printf fmt "\n", $6, $4, $3, $5, status($5)

        # EdmCoff''s hack, too lazy to change to legible variable names
        # adapted to defer division until we know the final value of n
        a+=$2;b+=$3;c+=$4;dd+=$5;n++
    }
    END { d=dd/n;
        printf "\n" fmt "%%\n",
     "Grand total:", c, b, int(d), status(d) }'

Очевидно, у меня нет возможности проверить это с реальным вводом, поэтому, возможно, есть небольшие ошибки форматирования и т. Д. Я надеюсь, что я собрал достаточно логики, чтобы хотя бы показать вам, как реализовать тело этой обработки в виде сценария Awk.

Обратите внимание на отсутствие каких-либо временных файлов (которые ваш исходный скрипт не сможет очистить, если он был прерван;использованиеtrap) и использование отступов, чтобы помочь вам увидеть циклы и условные выражения.

 tripleee10 янв. 2018 г., 08:49
Код Awk - это довольно простой перевод сценария оболочки «один к одному», но если есть что-то конкретное, чего вы не понимаете, спросите, и я постараюсь уточнить. Это действительно просто извлекает несколько полей из каждой строки, которая не является/^Filesystem/ линии и выполняет расчеты из вашего кода.
 emilee11 янв. 2018 г., 02:59
Я запустил скрипт, сначала выглядит хорошо. Затем я заметил, что скрипт не видит устройства server2, только показывает только устройство server1. Каждый сервер имеет 2 устройства. Поэтому я изменил строки № 6 и № 7server1 /dev/md10 /dev/md11 & server2 /dev/md12 /dev/md13, server1 в порядке, но не server2. Мне нужно, чтобы процент округлялся без десятичной точки и порога состояния диска. Я действительно не знаю, как соединить это.
 tripleee10 янв. 2018 г., 08:46
Я отредактировал ответ, чтобы удалить трейлинг%s Вы спрашивали о, но может быть больше; У меня явно нет возможности проверить это. Если вы можете предоставить некоторые реалистичные тестовые данные, не должно быть проблем с устранением оставшихся ошибок.
 emilee10 янв. 2018 г., 08:45
спасибо за сценарий, но я не понимаю некоторые его функции, что выдает ошибку. awk: cmd. строка: 12: (FILENAME = - FNR = 1) неустранимый: недостаточно аргументов для удовлетворения строки формата `% -18s% 8s% 12s% 6s% -2s% s '^ закончился для этого
 tripleee12 янв. 2018 г., 07:09
Лучший способ рассчитатьd было бы100.0*c/(c+b) но я оставлю это как просто комментарий сейчас.

Ваш ответ на вопрос