Je dois calculer le trafic réseau moyen sur une interface. Je connais un logiciel comme iftop
, mais je ne peux pas l'utiliser dans mon cas.
J'exécute un programme qui doit faire des calculs avec le trafic réseau moyen sur une interface. Par conséquent, j'ai besoin d'une commande qui produit une sortie simple. Des programmes comme iftop
affichent les valeurs d'une manière très complexe qui ne peut pas être facilement analysée par d'autres applications.
Je cherche quelque chose comme:
Commander:
$ get-avg-traffic --interface=eth0 --seconds-interval=30 --type=incoming --unit=KB
Sortie:
783846
Existe-t-il déjà un logiciel qui supporte (certains) ces fonctionnalités?
Vous voulez probablement jeter un oeil à 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 |
Vous pouvez avoir des statistiques horaires journalières et mensuelles.
La commande ip
(anciennement netstat
) vous donnera ce type d'informations, mais vous devrez effectuer une analyse syntaxique pour obtenir simplement un nombre AFAICT (je ne suis pas expert en la matière).
localhost-$ ip -s -h -c link show wlan15
donne une sortie comme:
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
Donc par exemple:
ip -s -c link show wlan15 | tail -n1 | cut -d " " -f5
Donnerait 146013456
ou quelque chose comme ça, le 146M en octets bruts comme volume de transmission sur l'interface particulière. tail
prend la dernière ligne (utilisez-la avec head
pour choisir une ligne arbitraire [il existe de nombreuses autres manières]), cut sépare cette sortie dans les champs avec "" comme délimiteur et choisissez le cinquième domaine.
L'utilisation de cette valeur dans votre programme pour calculer le débit de transmission moyen devrait être simple.
Un exemple codé en dur utilisant ifconfig
. Pour une surveillance à plus long terme, vnstat
est plus approprié.
#!/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
Ma suggestion est le script suivant, basé sur ifconfig
et une de mes réponses précédentes, où fournissent plus d'explications.
1. Créez un fichier de script exécutable, appelé get-traffic
, situé dans /usr/local/bin
afin qu'il soit accessible en tant que commande Shell (- étapes plus détaillées ).
2. Le contenu du script get-traffic
est:
#!/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. La syntaxe d'appel de script:
get-traffic <interface name> <units of measurement> <period of measure> <type of the output>
get-traffic enp0s25 MiB 30 total
4. Paramètres d'entrée:
<interface name>
utilisez la commande ifconfig
pour obtenir le nom de l'interface. Valeur par défaut: eth0
<units of measurement>
valeurs disponibles: B
, KB
, KiB
, MB
, Mib
, Gb
, Gib
. Par défaut: MB
<period of measure>
en secondes. Valeur par défaut: 30
<type of the output>
valeurs disponibles: verbose
, all
, incoming
, outgoing
, total
.5.. Exemples d'utilisation:
Vous pouvez obtenir les valeurs vous-même de la même manière que les autres programmes, en consultant le contenu de, par exemple. /proc/net/dev
ou /sys/class/net/eth0/statistics/rx_bytes
périodiquement et en calculant vous-même le delta.
Donc, pour votre exemple spécifique,
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