4

Here's script I wrote out of boredom, for download speed test:

#!/bin/bash

get_ispeed() {
    echo $(ifconfig eth0 | grep bytes | grep RX | cut -d ':' -f 2 | cut -d ' ' -f 1);
}

for((;;));
do
    s1=`get_ispeed`;

    sleep 1s;

    s2=`get_ispeed`;

    d=$(($s2-$s1));

    echo $(($d / 1000))" kB/s";
done

Not sure if it's "doing the job", though I'm not true bashist :p
Since ifconfig yields RX bytes, I divide it by 1000 to get kB/s

  • On Linux, you can do it more efficiently with read s1 < /sys/class/net/eth0/statistics/rx_bytes – Stéphane Chazelas Aug 5 '13 at 10:09
  • You'd better use wget or ntp. – Eddy_Em Aug 5 '13 at 10:20
  • For a reliable measurement, you might need to extend the time you measure. If you want to have a TUI, look at iftop. You measure the receive bandwidth over one second. As there is package overhead, this is not exactly download speed. If you want to determine the link speed of your network card (10/100/1000/... MBit) use ethtool. – jofel Aug 5 '13 at 10:29
7

link speed

I don't think you're really looking for link speed, this is the dedicated connection speed of your connection. If you have ethtool installed (in repos) you can use this command to get your link speed:

$ sudo ethtool eth0 | grep -i speed
    Speed: 100Mb/s

bandwidth (kernel)

You want to see your bandwidth speed. How much of the total speed you're using over a given amount of time. There are a couple of ways to get the bytes read by the eth0 interface:

$ cat /sys/class/net/eth0/statistics/rx_bytes 
3431530366

There is also /proc/net/dev, which I believe is the kernel structure that provides the data for ifconfig:

$ cat /proc/net/dev
Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
    lo:629956414  572909    0    0    0     0          0         0 629956414  572909    0    0    0     0       0          0
  eth0:3431888253 329701689    0    0    0     0          0    359127 831203319 353144288    0    0    0     0       0          0
  sit0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0

measuring using tools

Better still would be to use an actual tool for measuring your bandwidth usage. There are many options here:

  1. use wget/curl

    These are pretty straightforward. Pick a large file to download and see the stats reported by either tool after it's completed.

    $ wget --output-document=/dev/null http://speedtest.wdc01.softlayer.com/downloads/test500.zip
    
    -or-
    
    $ curl -O /dev/null http://speedtest.wdc01.softlayer.com/downloads/test500.zip
    
  2. use a cli monitoring tool

    There are numerous tools in this category. Here are a couple to get you started.

  3. use speedtest-cli

    This makes use of the venerable speedtest.net website from the command line.

    $ ./speedtest-cli
    Retrieving speedtest.net configuration...
    Retrieving speedtest.net server list...
    Testing from Comcast Cable (x.x.x.x)...
    Selecting best server based on ping...
    Hosted by FiberCloud, Inc (Seattle, WA) [12.03 km]: 44.028 ms
    Testing download speed........................................
    Download: 32.29 Mbit/s
    Testing upload speed..................................................
    Upload: 5.18 Mbit/s
    
  4. use iperf

    For this you'll setup your own server and client and then measure the bandwidth performance between two of your computers. This is a better in the sense that you'll get a more accurate picture of your computer/network performance than depending on the performance of a specific internet target.

    on server:

    $ iperf -s
    

    on client:

    $ iperf -c myserver.mydom
     ------------------------------------------------------------
    Client connecting to 192.168.1.1, TCP port 5001
    TCP window size: 16.0 KByte (default)
    ------------------------------------------------------------
     [  3] local 192.168.1.3 port 52143 connected with 192.168.1.1 port 5001
     [ ID] Interval       Transfer     Bandwidth
     [  3]  0.0-10.0 sec    113 MBytes  94.7 Mbits/sec
    

References

  • Another way to get the bandwidth is to parse ip -s link show eth0 or to use iftop. – jofel Aug 5 '13 at 12:00
  • You should be able to read link bandwidth directly from sysfs (without ethtool), it's in /sys/class/net/<interface>/speed - possibly dependent on your kernel version and how you configured it. Units are Mb/s. – Toby Speight Feb 5 '18 at 15:34
4

I'm really agreed with your question and answers, thus, I can really do this in a single line:

m1=`cat /sys/class/net/eth0/statistics/tx_bytes` ; sleep 10s ; m2=`cat /sys/class/net/eth0/statistics/rx_bytes` ; echo $((($m2-$m1)/10240))

And it prints pretty well.

In a more sophisticated way:

#!/bin/bash                                                                          

intervalo=3                                                                          
info="/sys/class/net/"                                                               
cd $info                                                                             
for interface in eth*                                                                
do                                                                                   
  rx1=`cat $info$interface/statistics/rx_bytes`                                      
  tx1=`cat $info$interface/statistics/tx_bytes`                                      
 `sleep $((intervalo))s`                                                            
  rx2=`cat $info$interface/statistics/rx_bytes`                                      
  tx2=`cat $info$interface/statistics/tx_bytes`
  echo $interface
  echo ----
  echo RX: $((($rx2-$rx1)/($intervalo*1024))) Kbps
  echo TX: $((($tx2-$tx1)/($intervalo*1024))) Kbps
done

That works fine, but can be improved using arrays to save each interface result, so it would only need to do a sleep for all the interfaces, and not one by any of them.

  • Indeed I do prefer you script than the original. However, it would be far more interesting to measure the difference between different calls (keeping the last result in a file for instance) than doing a sleep. That way, when calling from a cron, for instance, every five minutes, we could have the real usage of the server, and not the instant speed. – Rui F Ribeiro Nov 17 '15 at 8:23
  • Did you mean to mix tx_bytes and rx_bytes in the first example? – Toby Speight Feb 5 '18 at 15:30
  • Also, I think you've actually computed KB/s rather than Kb/s - change the label, or change the divisor to 128. – Toby Speight Feb 5 '18 at 15:35
0

The advertised speed and the actual speed of the link can be different

sudo ethtool enp1s0
Settings for enp1s0:
Supported ports: [ TP ]
Supported link modes:   10baseT/Half 10baseT/Full 
                        100baseT/Half 100baseT/Full 
                        1000baseT/Full 
Advertised link modes:  10baseT/Half 10baseT/Full 
                        100baseT/Half 100baseT/Full 
                        1000baseT/Full 

This reports the actual link speed as negotiated between both devices on each end of the link. My laptops network card the local switch I connect to.

Whereas the actual speed reported by these tools is

sudo mii-tool enp1s0
enp1s0: negotiated 100baseTx-FD flow-control, link ok

sudo ethtool enp1s0 | grep -i speed
Speed: 100Mb/s

I will only ever reach the link speed when I download something connected in the same LAN at the same speed.

If I download a file from a server on the same LAN. I will get the full 100Mb/s.

So where I connet to will make a difference to the speed I get.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.