Мне нужно рассчитать средний сетевой трафик на интерфейсе. Я знаю о программном обеспечении, подобном iftop
, но я не могу использовать его в моем случае.
Я запускаю программу, которая выполняет вычисления со средним сетевым трафиком на интерфейсе. Поэтому мне нужна команда, которая выдает простой вывод . Программы типа iftop
выводят значения очень сложным способом, который не может быть легко проанализирован другими приложениями.
Я ищу что-то вроде:
Команда:
$ get-avg-traffic --interface=eth0 --seconds-interval=30 --type=incoming --unit=KB
Вывод:
783846
Уже есть программное обеспечение, которое поддерживает (некоторые из ) это функциональность?
Вы, вероятно, хотите взглянуть на vnstat
$ vnstat -d -i wlp3s0
wlp3s0 / daily
day rx | tx | total | avg. rate
------------------------+-------------+-------------+---------------
2017-10-24 166,63 MiB | 37,33 MiB | 203,96 MiB | 19,34 kbit/s
2017-10-25 214,68 MiB | 130,26 MiB | 344,94 MiB | 32,71 kbit/s
2017-10-26 1,01 GiB | 4,09 GiB | 5,10 GiB | 495,31 kbit/s
2017-10-27 1,16 GiB | 113,28 MiB | 1,27 GiB | 123,04 kbit/s
2017-10-28 201,09 MiB | 299,21 MiB | 500,31 MiB | 47,44 kbit/s
2017-10-29 1,92 GiB | 174,35 MiB | 2,09 GiB | 202,92 kbit/s
2017-10-30 559,56 MiB | 69,18 MiB | 628,73 MiB | 59,61 kbit/s
2017-10-31 397,73 MiB | 43,62 MiB | 441,35 MiB | 41,85 kbit/s
2017-11-01 665,81 MiB | 83,05 MiB | 748,86 MiB | 71,00 kbit/s
2017-11-02 282,20 MiB | 239,91 MiB | 522,11 MiB | 49,50 kbit/s
2017-11-03 4,06 GiB | 4,85 GiB | 8,92 GiB | 865,61 kbit/s
2017-11-04 220,95 MiB | 40,12 MiB | 261,07 MiB | 24,75 kbit/s
2017-11-05 320,91 MiB | 8,86 GiB | 9,18 GiB | 890,93 kbit/s
2017-11-06 639,67 MiB | 13,77 GiB | 14,39 GiB | 1,40 Mbit/s
2017-11-07 694,91 MiB | 80,48 MiB | 775,39 MiB | 73,52 kbit/s
2017-11-08 178,64 MiB | 32,43 MiB | 211,07 MiB | 28,97 kbit/s
------------------------+-------------+-------------+---------------
estimated 257 MiB | 46 MiB | 303 MiB |
У Вас может каждый час быть ежедневная и ежемесячная статистика.
Жестко закодированный пример с использованием ifconfig
. Для более долгосрочного мониторинга vnstat
более целесообразно.
#!/bin/bash
INTERFACE=wlp2s0
A=($(ifconfig $INTERFACE | grep bytes | sed -e 's/[(|)]//g' -e 's/:/ /g' -e 's/ */ /g'))
sleep 30
B=($(ifconfig $INTERFACE | grep bytes | sed -e 's/[(|)]//g' -e 's/:/ /g' -e 's/ */ /g'))
echo -e ${A[@]}"\n"${B[@]}
AVG=$(expr ${B[2]} - ${A[2]})
AVGKB=$(echo AVG | awk '{ byte =$1 /1024; print byte " KB" }')
#AVGMB==$(echo AVG | awk '{ byte =$1 /1024/1024; print byte " MB" }')
#AVGMB==$(echo AVG | awk '{ byte =$1 /1024/1024/1024/; print byte " GB" }')
echo -e "30 sec average\n"$AVG"\n"$AVGKB
Вы можете получать значения сами тот же способ, которым те другие программы делают это путем рассмотрения содержания, например, /proc/net/dev
или /sys/class/net/eth0/statistics/rx_bytes
периодически и вычисления дельты сами.
Так для Вашего определенного примера,
start=$(< /sys/class/net/eth0/statistics/rx_bytes) # get received bytes
sleep 30 # wait 30 seconds (make this a variable in your program!)
end=$(< /sys/class/net/eth0/statistics/rx_bytes)
delta=$((end-start)) # calculate bytes received over the period
echo $(($((delta+512))/1024)) # roughly round to nearest 1k
Команда ip
(раньше netstat
) даст Вам этот тип информации, но необходимо будет сделать парсинг для получения просто числа AFAICT (я не эксперт по нему).
localhost-$ ip -s -h -c link show wlan15
дает вывод как:
3: wlan15: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1372 qdisc mq state UP mode DORMANT group default qlen 1000
link/ether a0:f3:c1:28:2b:68 brd ff:ff:ff:ff:ff:ff
RX: bytes packets errors dropped overrun mcast
78.2M 137k 0 0 0 0
TX: bytes packets errors dropped carrier collsns
146M 197k 0 0 0 0
Так, например:
ip -s -c link show wlan15 | tail -n1 | cut -d " " -f5
Дал бы 146013456
или somesuch, 146M в необработанных байтах как объем передачи в конкретном интерфейсе. tail
проводит последнюю строку (используйте ее с head
для выбора произвольной строки [существует много других путей]), сокращение разделяет тот вывод в к полям с "" как разделитель и выбирает пятое поле.
Используя это значение в Вашей программе для вычисления средней скорости передачи должно быть простым.
Мое предложение является следующим сценарием, на основе ifconfig
и один мой предыдущий ответ, где даны больше объяснений.
1. Создайте исполняемый файл сценария, названный get-traffic
, это расположено в /usr/local/bin
быть доступным как команда оболочки (более подробные шаги).
2. Содержание сценария get-traffic
:
#!/bin/bash
# Set the default values or Read the users input
[ -z "${1}" ] && IFACE="eth0" || IFACE="$1" # Get the name of the target interface, default: eth0
[ -z "${2}" ] && UNIT="MB" || UNIT="$2" # Get the unit (B, KB, MB, GB, Kib, Mib, Gib), default: MB
[ -z "${3}" ] && PERIOD="30" || PERIOD="$3" # Get the period of measure in seconds, default: 30
[ -z "${4}" ] && OUTPUT="verb" || OUTPUT="${4,,}" # Get the type of the output (verbose, all, incoming, outgoing, total) in lower case, default: all
LANG=C # Set envvar $LANG to `C` due to grep, awk, etc.
# Do the conversion
if [ "$UNIT" == "B" ]; then UN="1"
elif [ "$UNIT" == "KB" ]; then UN="1000"
elif [ "$UNIT" == "KiB" ]; then UN="1024"
elif [ "$UNIT" == "MB" ]; then UN="1000000"
elif [ "$UNIT" == "MiB" ]; then UN="1048576"
elif [ "$UNIT" == "GB" ]; then UN="1000000000"
elif [ "$UNIT" == "GiB" ]; then UN="1073741824"
else echo "Wrong UNIT."; exit 1; fi
# Whether the $PERIOD is integer
if ! [[ "$PERIOD" =~ ^[0-9]+$ ]]; then echo "Enter the PERIOD in seconds"; exit 1; fi
# Get the IP address of the interface
get_ip(){ /sbin/ifconfig "$IFACE" 2>/dev/null | grep -Po '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | head -1; }
# The main program: If the interface has IP adders it is UP
if [[ "$(get_ip)" =~ ${IPPT} ]]; then
bRX="$(/sbin/ifconfig "$IFACE" | grep -Po "RX bytes:[0-9]+" | sed 's/RX bytes://')" # Get the incoming traffic into the Beginning of the period
bTX="$(/sbin/ifconfig "$IFACE" | grep -Po "TX bytes:[0-9]+" | sed 's/TX bytes://')" # Get the outgoing traffic into the Beginning of the period
bXX=$(( bRX + bTX )) # Calculate the total traffic into the Beginning of the PERIOD
sleep "$PERIOD" # Sleep for the PERIOD, seconds
eRX="$(/sbin/ifconfig "$IFACE" | grep -Po "RX bytes:[0-9]+" | sed 's/RX bytes://')" # Get the incoming traffic into the End of the period
eTX="$(/sbin/ifconfig "$IFACE" | grep -Po "TX bytes:[0-9]+" | sed 's/TX bytes://')" # Get the outgoing traffic into the End of the period
eXX=$(( eRX + eTX )) # Calculate the total traffic into the End of the PERIOD
RX=$(awk -v e="${eRX}" -v b="${bRX}" -v un="${UN}" 'BEGIN{ print ( e - b) / un }') # Calculate the amount of the incoming traffic for the PERIOD
TX=$(awk -v e="${eTX}" -v b="${bTX}" -v un="${UN}" 'BEGIN{ print ( e - b) / un }') # Calculate the amount of the outgoing traffic for the PERIOD
XX=$(awk -v e="${eXX}" -v b="${bXX}" -v un="${UN}" 'BEGIN{ print ( e - b) / un }') # Calculate the amount of the total traffic for the PERIOD
# Output
if [[ "$OUTPUT" =~ ^verb ]]; then printf 'Interface: %s\nUnit: %s\nPeriod of measure: %s sec.\n\nReceived: %s\nTransmited: %s\nTotal: %s\n' "$IFACE" "$UNIT" "$PERIOD" "$RX" "$TX" "$XX"
elif [[ "$OUTPUT" =~ ^all ]]; then printf '%s\n%s\n%s\n' "$RX" "$TX" "$XX"
elif [[ "$OUTPUT" =~ ^in ]]; then printf '%s\n' "$RX"
elif [[ "$OUTPUT" =~ ^out ]]; then printf '%s\n' "$TX"
elif [[ "$OUTPUT" =~ ^tot ]]; then printf '%s\n' "$XX"
else echo "Wrong OTPUT type."; fi
else
echo "The INTERFACE \"$IFACE\" is down."
fi
3. Синтаксис вызова сценария:
get-traffic <interface name> <units of measurement> <period of measure> <type of the output>
get-traffic enp0s25 MiB 30 total
4. Входные параметры:
<interface name>
используйте команду ifconfig
получить имя интерфейса. Значение по умолчанию: eth0
<units of measurement>
доступные значения: B
, KB
, KiB
, MB
, Mib
, Gb
, Gib
. Значение по умолчанию: MB
<period of measure>
в секундах. Значение по умолчанию: 30
<type of the output>
доступные значения: verbose
, all
, incoming
, outgoing
, total
.5. Примеры использования: