If i wanted to extract the ttl and display it from the ping command how could i go about doing that?

China☆狼群 提交于 2021-01-05 10:15:14

问题


Scripting and want to ping devices on a network, tell me if it's reachable or not, and then get the ttl data from the ping and tell me the operating system.

Ive tried using the awk command, but I am also new to scripting and may not be using it correctly.

for host in $(seq 1 255);   
do
    ping -c 1 $sn.$host | grep "Unreachable" &>/dev/null
    if [ $? -eq 0 ]; then
        printf "%s\n" "$sn.$host is Offline"
    fi

    ping -c 1 $sn.$host | grep "ttl" &>/dev/null
    if [ $? -eq 0 ]; then
        printf "%s\n" "$sn.$host is Online"
    fi
done

I need the ttl value and to store it into a variable and then tell me what operating system it is based on Linux has a ttl of 64, windows a ttl of 128, and ios of 255


回答1:


You can do things in a bit more concise manner and minimize the time waiting for an Offline host by setting a timeout using the -w (or -W) option. For example you can save the ttl=XX value from ping in the same call that determines whether the host is online or not and then you can use a simple parameter expansion to extract the numeric ttl value from the right side of the equal sign, e.g.

    ttlstr=$(ping -c1 -w1 $sn.$host | grep -o 'ttl=[0-9][0-9]*')

Above the command substitution $(...) executes ping and pipes the output to grep and assigns the results to ttlstr. The command substitution return is the return of the last command in the pipeline telling you whether grep for "ttl=####" succeeded or failed. That's all you need to determine whether the host is online or not. On failure output your "Offline" message and try the next, e.g.

    ## ping with 1 sec timeout store ttl=xx in ttlstr
    ttlstr=$(ping -c1 -w1 $sn.$host | grep -o 'ttl=[0-9][0-9]*') || {
        printf "%s is Offline\n" "$sn.$host"
        continue;
    }

If the command substitution succeeds, you can output your "Online" message and you can isolate the numeric ttl using a simple parameter expansion to remove all characters up to, and including, the '=' sign from the beginning of the string leaving only the numeric ttl, e.g.

    ttl="${ttlstr#*=}"  ## parameter expansion separating numeric ttl
    printf "%s is Online, ttl=%d\n" "$sn.$host" "$ttl"

Putting it altogether you could do:

#!/bin/bash

sn=${1:-192.168.6}

for host in $(seq 1 255); do
    ## ping with 1 sec timeout store ttl=xx in ttlstr
    ttlstr=$(ping -c1 -w1 $sn.$host | grep -o 'ttl=[0-9][0-9]*') || {
        printf "%s is Offline\n" "$sn.$host"
        continue;
    }
    ttl="${ttlstr#*=}"  ## parameter expansion separating numeric ttl
    printf "%s is Online, ttl=%d\n" "$sn.$host" "$ttl"
done

Example Use/Output

note: the sn is taken as the 1st argument to the program (using a default of 192.168.6 above)

$ bash ~/scr/utl/chksubnet.sh
<snip>
192.168.6.14 is Offline
192.168.6.15 is Offline
192.168.6.16 is Offline
192.168.6.17 is Online, ttl=64
192.168.6.18 is Offline
192.168.6.19 is Offline
<snip>

Look things over and let me know if you have further questions.




回答2:


Here's a way of using awk to extract the ttl:

$ ping -c 1  8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: icmp_seq=0 ttl=53 time=48.575 ms

--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 48.575/48.575/48.575/0.000 ms


$ ping -c 1  8.8.8.8 | awk -F'[ =]' '/ttl/ {print $8 }'
53

The -F parameter tells awk what the field separator is. I've indicated spaces or the equals sign. The body of the awk script is written as pattern / command pairs. In the one line script, awk runs the print $8 command for any line that has ttl in line. The command tells awk to print the eigth field (remember, the -F indicated how to break the input line into fields. The /ttl/ pattern could be replaced with $7 == "ttl", too. This latter form is more accurate, since it would only match ttl if it appeared as the 7th field.

There are better more general implementations.

If you want to do this quickly, review the nmap utility. For example,

nmap -sn 192.168.1.0/24

Nmap aside, your program can be improved a bit by ping'ing the IP once and piping the results to awk, letting awk generate ALL the output.




回答3:


Below is the script which you can use to find the Operating System name based on the ttl value if host is Online.

   for host in $(seq 1 255);
    do
        ping -c 1 $sn.$host | grep "Unreachable" &>/dev/null
        if [ $? -eq 0 ]
        then
            printf "%s\n" "$sn.$host is Offline"
            continue
        else
            printf "%s\n" "$sn.$host is Online" 
            ttlValue=`ping -c 1 $sn.$host | grep ttl | awk '{print $6}'|awk -F'=' '{print $2}' &>/dev/null`
            if [ $ttlValue -eq 64 ]
            then
                echo "Operating is Linux"
            elif [ $ttlValue -eq 128 ]
            then
                echo "Operating is Windows"
            else
                echo "Operating is IOS"
            fi
        fi
    done


来源:https://stackoverflow.com/questions/57916431/if-i-wanted-to-extract-the-ttl-and-display-it-from-the-ping-command-how-could-i

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!