Как точно вернуть выходные значения bash-скрипта - PullRequest
3 голосов
/ 03 июля 2019

У меня есть следующая команда:

$ snmpnetstat -v2c -c public -Cs -Cp udp 10.10.0.32 

с выводом терминала:

udp:
           198 total datagrams received
            65 datagrams to invalid port
             0 datagrams dropped due to errors
           265 output datagram requests

Я хочу написать скрипт bash, который возвращает следующее:

желаемый вывод скрипта bash:

Received Datagrams: 198 
Invalid port:65 
Dropped datagrams: 0 
Datagram requests: 256

Я начал с:

#!/bin/bash
    rs="$(snmpnetstat -v2c -c public -Cs -Cp udp 10.10.0.32)"
ReceivedDatagrams=$(echo $rs | cut -d"/" -f1)
InvalidPort=$(echo $rs | cut -d"/" -f2)
DroppedDatagrams=$(echo $rs | cut -d"/" -f3)
DatagramRequests=$(echo $rs | cut -d"/" -f4)

echo "Received Datagrams:$ReceivedDatagrams Invalid port:$InvalidPort Dropped datagrams:$DroppedDatagrams Datagram requests:$DatagramRequests"

Вывод:

    zsz@bme-ib112-05:~/bash_scripts$ ./script.sh         
Received Datagrams:udp: 242 total datagrams received 37 datagrams to invalid port 0 datagrams dropped due to errors 638 output datagram requests Invalid port:udp: 242 total datagrams received 37 datagrams to invalid port 0 datagrams dropped due to errors 638 output datagram requests Dropped datagrams:udp: 242 total datagrams received 37 datagrams to invalid port 0 datagrams dropped due to errors 638 output datagram requests Datagram requests:udp: 242 total datagrams received 37 datagrams to invalid port 0 datagrams dropped due to errors 638 output datagram requests

Выходные значения повторяются снова и снова, а не так, как я хотел.

Ответы [ 3 ]

4 голосов
/ 03 июля 2019

Простое awk решение, которое, как указал shellter, устраняет накладные расходы всех этих дополнительных процессов:

$ cat udp.out
udp:
           198 total datagrams received
            65 datagrams to invalid port
             0 datagrams dropped due to errors
           265 output datagram requests

$ awk '
/received/ {printf "Received Datagrams: %s\n", $1}
/invalid/  {printf "Invalid port: %s\n"      , $1}
/dropped/  {printf "Dropped datagrams: %s\n" , $1}
/requests/ {printf "Datagram requests: %s\n" , $1}
' udp.out

Received Datagrams: 198
Invalid port: 65
Dropped datagrams: 0
Datagram requests: 265
3 голосов
/ 03 июля 2019

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

awk '
/total datagrams/                 { print "Received Datagrams:", $1 }
/datagrams to invalid port/       { print "Invalid port:", $1 }
/datagrams dropped due to errors/ { print "Dropped datagrams:", $1 }
/output datagram requests/        { print "Datagram requests:", $1 } 
' 

В некотором смысле, awk выполняет весь анализ для вас и выжимает (tr -s) весь ваш пробел. Я считаю, что это облегчает чтение кода.

2 голосов
/ 03 июля 2019

Я не могу воссоздать точный вывод команды snmpnetstat, поэтому я просто скопировал / вставил вывод вашего терминала в файл tmp.

Следующий скрипт выполняет ту работу, которую вы запрашивали на моем конце, используя вашу логику

Я бы порекомендовал воспользоваться советами Shellter и Ed Morton и посмотреть, как работает цитирование переменных, чтобы запретить расширение в пробелах / символах новой строки, и использовать Awk для более надежного и легко расширяемого решения.

#!/bin/bash

rs="$(cat tmp)"

# You have to quote "$rs" so newlines don't break
ReceivedDatagrams="$(echo "$rs" | cut -d$'\n' -f2 | tr -s ' '| cut -d' ' -f2)"
InvalidPort="$(echo "$rs" | cut -d$'\n' -f3 | tr -s ' '| cut -d' ' -f2)"
DroppedDatagrams="$(echo "$rs" | cut -d$'\n' -f4 | tr -s ' '| cut -d' ' -f2)"
DatagramRequests="$(echo "$rs" | cut -d$'\n' -f5 | tr -s ' '| cut -d' ' -f2)"

echo "Received Datagrams:$ReceivedDatagrams"
echo "Invalid port:$InvalidPort"
echo "Dropped datagrams:$DroppedDatagrams"
echo "Datagram requests:$DatagramRequests"
...