5

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
Chris Maes
  • 35,025
  • 12
  • 111
  • 136
ElkeAusBerlin
  • 565
  • 1
  • 4
  • 18

5 Answers5

7

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.

ormaaj
  • 6,201
  • 29
  • 34
konsolebox
  • 72,135
  • 12
  • 99
  • 105
  • Added a missing then and a ';' (otherwise I got "syntax error near unexpected token `else'") and it works as expected. Thanks! – ElkeAusBerlin Jun 03 '14 at 07:24
  • @ormaaj Thanks for the edit, but I'm not sure if `-q` is available in all versions of grep. – konsolebox Jun 03 '14 at 09:10
  • 1
    @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. :) – ormaaj Jun 03 '14 at 09:25
6

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 ]]
}

...
ormaaj
  • 6,201
  • 29
  • 34
  • Great, cool solution. And, of course, every unix not linux compatible is broken nowadays ;-) – ElkeAusBerlin Jun 03 '14 at 11:33
  • 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). – ElkeAusBerlin Jun 03 '14 at 11:41
  • Great solution here, works perfectly. Especially the ip link version. Thanks! – Joe Nov 19 '20 at 17:15
2

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)

PradyJord
  • 2,136
  • 12
  • 19
lutzhell
  • 104
  • 4
1

Looking at your question can you use /sbin/ifconfig eth0 and check if it has inet or inet6 address, or you can also check for the line UP BROADCAST RUNNING MULTICAST. If the network is down the line will be UP BROADCAST MULTICAST
You can check the man page of ifconfig for more information.

Pratham
  • 1,522
  • 1
  • 18
  • 33
0

Different functions for different purposes:

## (1) check if there is any interface UP
## loopback interface (lo) is excluded
_isInterfaceUp(){
  ip link|grep -v '[0-9]: lo:' 2>/dev/null|grep -l '^[0-9].* UP ' >/dev/null 2>&1
}

## (2) check if there is a valid default gateway in the routing table
## note: routes via non-active interfaces are excluded
_isNetworkUp(){
  ip route|grep '^default via ' 2>/dev/null|grep -lv 'linkdown' >/dev/null 2>&1
}

## (3) check if Internet is connected properly
_isInternetConnected(){
if ! ping -c 4 8.8.8.8 >/dev/null 2>&1; then
  ## ping might be firewalled, so check a webpage then
  curl -Hfs www.google.com >/dev/null 2>&1 || return 1
fi
return 0
}

In real practices, I do not use the function (1), because it rarely useful simply to check if there is an interface UP. However I do use funtions (2) + (3):

  • The function (2) _isNetworkUp is called periodically in a script just to show whether my computer is networked
  • The function (3) _isInternetConnected is called in a script before doing something with internet, like sync computer time and check email. Because the function (3) costs more time and resources than function (2), so it is not suitable for periodically usage of short time interval. curl is more costly than ping; so ping first, then curl later.

(sorry if my English is lousy).

Examples:

## if Internet is connected, then sync time
## with world time server
if _isInternetConnected; then
  sudo ntpdate pool.ntp.org
  sudo hwclock --systohc --utc
fi

Explanations:

  • grep -l : grep stops immediate after 1st found.
  • grep -v : grep exclusively.
  • ping -c 4: ping only 4 times.
Bach Lien
  • 1,030
  • 6
  • 7