How to test if link is up in bash script

17,784

Solution 1

You simply need

if /sbin/ethtool eth0 | grep -q "Link detected: yes"; then
    echo "Online"
else
    echo "Not online"
fi

Also if you want to encapsulate checking, simply use a function:

function check_eth {
    set -o pipefail # optional.
    /sbin/ethtool "$1" | grep -q "Link detected: yes"
}

if check_eth eth0; then
    echo "Online"
else
    echo "Not online"
fi

How it works: if simply interprets a command in front of it and check if the return value of $? is 0. grep returns 0 when it finds a match on its search. And so because of this you don't need to use wc and compare its output to 1.

Solution 2

It appears your script question has been answered. Under Linux I would implement this by reading sysfs directly.

function ifup {
    if [[ ! -d /sys/class/net/${1} ]]; then
        printf 'No such interface: %s\n' "$1" >&2
        return 1
    else
        [[ $(</sys/class/net/${1}/operstate) == up ]]
    fi
}

if ifup enp7s0; then
    echo Online
else
    echo 'Not online'
fi

My second choice would probably be ip link.

# Returns true if iface exists and is up, otherwise false.
function ifup {
    typeset output
    output=$(ip link show "$1" up) && [[ -n $output ]]
}

...

Solution 3

At least at my machine (Debian 7.5) only root is allowed to determine link status with ethtool and it is not installed in all distributions.

I can think of three alternatives to ethtool to determine network link status:

  1. ifconfig eth0

  2. ip link show (you have to grep for your interface and "state UP" or "state DOWN")

  3. send one ping to some known online host (could also be given as parameter) in your network (ping -c 1 -w 1 ip_address &> /dev/null, -c specifies the number of packets to send and -w is the timeout in seconds)

Share:
17,784
ElkeAusBerlin
Author by

ElkeAusBerlin

Updated on June 05, 2022

Comments

  • ElkeAusBerlin
    ElkeAusBerlin almost 2 years

    using this script I am trying to detect if there is a network link. I am failing in putting multiple commands in one line (ethtool...). What to do?

    #!/bin/bash
    
    COMMAND="( /sbin/ethtool eth0 ) | ( /bin/grep \"Link detected: yes\" ) | ( wc -l )"
    ONLINE=eval $COMMAND 
    
    if $ONLINE; then 
        echo "Online"
    else
        echo "Not online"
    fi
    
  • ElkeAusBerlin
    ElkeAusBerlin almost 10 years
    Added a missing then and a ';' (otherwise I got "syntax error near unexpected token `else'") and it works as expected. Thanks!
  • konsolebox
    konsolebox almost 10 years
    I see. Welcome :) (I added ; then)
  • konsolebox
    konsolebox almost 10 years
    @ormaaj Thanks for the edit, but I'm not sure if -q is available in all versions of grep.
  • ormaaj
    ormaaj almost 10 years
    @konsolebox It should be in any POSIX-compliant version. I don't know how recent of an addition to the standard it was, but it's a very common option. Really just a cosmetic change otherwise. :)
  • ElkeAusBerlin
    ElkeAusBerlin almost 10 years
    Great, cool solution. And, of course, every unix not linux compatible is broken nowadays ;-)
  • ElkeAusBerlin
    ElkeAusBerlin almost 10 years
    Hmmm, it seems /sys/class/net/eth0 is always there even the network cable is unplugged. Sorry, to be more specific, I try to detect if there is a link (=network cable is plugged in).
  • Joe
    Joe over 3 years
    Great solution here, works perfectly. Especially the ip link version. Thanks!