How to make command ping to output with domain name which I ping? - linux

E.g., I type ping www.domain.com and the output I want is like:
64 bytes from yyy.xxx.com (www.domain.com): icmp_seq=32 ttl=52 time=84.8 ms
(or other format with domain name).

Not possible by any flag ping command provides.
But we always can roll up our sleeves and get hands dirty.
ping google.com | sed -e 's/\([[:digit:]]*\+\:\)/\1 (google.com)/g'
Considering output format includes something like that "64 bytes from 192.168.0.1: icmp_seq=1 ttl=64 time=0.397 ms" we can try to parse with sed.
So, sed looks for digit and ":" symbol afterwards, replaces it to "digit: (google.com)".

Related

Searching for a particular string using Regex in Bash/Shell Scripting

I am trying to echo out the the average round trip time for 4 ICMP echo/echo rely packets (in ms) for a website like google. This is my code as of now.
echo "$(ping -c 4 google.com | grep '??????')"
Pinging the website works but I have no idea how to echo out only the average round trip time. I have only used Regex for validation on web forms, but I haven't used it in awhile. I assume I can use Regex to find only what I am searching for, but if there is a better way of doing this, that would also be great. I am writing this using shell scripting for linux ubuntu
This is an example of the output. The only part of this I need is the part at the bottom where it says rtt min/avg/max/mdev = 14.556/14.579/14.614/0.088 ms.
PING google.com (142.250.74.238) 56(84) bytes of data.
64 bytes from par10s40-in-f14.1e100.net (142.250.74.238): icmp_seq=1 ttl=108 tim e=14.5 ms
64 bytes from par10s40-in-f14.1e100.net (142.250.74.238): icmp_seq=2 ttl=108 tim e=14.5 ms
64 bytes from par10s40-in-f14.1e100.net (142.250.74.238): icmp_seq=3 ttl=108 time=14.5 ms
64 bytes from par10s40-in-f14.1e100.net (142.250.74.238): icmp_seq=4 ttl=108 time=14.6 ms
--- google.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3003ms
rtt min/avg/max/mdev = 14.556/14.579/14.614/0.088 ms
Assuming the ping output looks like the following:
$ ping -c 4 google.com
PING google.com (172.217.14.238): 56 data bytes
64 bytes from 172.217.14.238: icmp_seq=0 ttl=118 time=78.019 ms
64 bytes from 172.217.14.238: icmp_seq=1 ttl=118 time=62.416 ms
64 bytes from 172.217.14.238: icmp_seq=2 ttl=118 time=63.019 ms
64 bytes from 172.217.14.238: icmp_seq=3 ttl=118 time=62.415 ms
--- google.com ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 62.415/66.467/78.019/6.674 ms
In this scenario the average time is 66.467 (ms)
One awk solution:
awk '/avg/ {split($0,arr,"/"); print arr[5]}'
Where:
/avg/ - look for line with the string avg
split($0,arr,"/") - split the line using a forward slash (/) as the delimiter, place the segments in the arr[] array
print arr[5] - print the 5th element of the arr[] array
Combining with the ping:
ping -c 4 google.com | awk '/avg/ {split($0,arr,"/"); print arr[5]}'
66.467
And if we need to include the measurement of time (ms in this case), we can also print the last field of the line that contains the string avg, eg:
ping -c 4 google.com | awk '/avg/ {split($0,arr,"/"); print arr[5],$NF}'
66.467 ms
NOTES:
OP may need to tweak the awk command if their ping output is in a different format
obviously (?) each time the ping is run we're likely to get a slightly different value.
if OP wants to be 100% certain of the value then the ping command output should be saved to a file (or variable) and then run the awk command against said file (or variable)

Is there a way to monitor and create a log file for my internet connection in Linux Mint 19.3 for a Time interval?

I'm experiencing some problems with my internet connection so my provider told me to make a logfile for an evening (min. 3 Hours) to see when the connection drops out to see what's the cause of the problem.
When I'm losing connection, I still remain in the network but my Inernet is simply 0B/s. Is there a way to make a log for a certain Time interval that constantly checks the internet connection (and ideally the download/upload speed). I'm kinda beginner in the Linux world and it would be very helpful when the answer will be good explained and every step will be described.
Thanks in advance.
For checking every 10 seconds that your connection is available you could use
ping 8.8.8.8 -D -i 1 2>&1 | tee my.log
where 8.8.8.8 is a DNS server run by Google.
File my.log will receive entries like:
[1583495940.797787] 64 bytes from 8.8.8.8: icmp_seq=1 ttl=55 time=17.9 ms
[1583495950.809658] 64 bytes from 8.8.8.8: icmp_seq=2 ttl=55 time=18.7 ms
ping: sendmsg: Network is unreachable
The number in square brackets is the time in seconds since 1970-01-01T00:00:00Z. For our example:
1583495950 = 2020-03-06T11:59:10Z
If you want to really transfer data, you could use a script like:
#!/bin/sh
URL=https://example.com
while [ true ]
do
wget $URL -O /dev/null 2>&1 | grep 'saved' | tee my.log
sleep 10
done
But mind the traffic cost on both sides.

Unable To Ping External Hosts Using In Perl Using Net::Ping

In Perl (5.16.3), I'm trying to use Net::Ping to test whether a remote host is available or not. I'm able to ping "internal" hosts which I know are online within my company's LAN, but I'm unable to ping "external" ones. Specifically, trying to ping 'www.google.com' fails.
My code:
#!/usr/bin/perl
use strict;
use warnings;
use Net::Ping;
my $hostname1 = 'prophet'; #internal
my $hostname2 = 'www.google.com'; #external
my $p;
my $rv1;
my $rv2;
$p = Net::Ping->new();
$rv1 = $p->ping($hostname1);
$rv2 = $p->ping($hostname2);
print "Response1: $rv1\n";
print "Response2: $rv2\n";
Yields this result:
[oracle#prophet:bin]$ ./ping_test
Response1: 1
Response2: 0
[oracle#prophet:bin]$
Even though using the (CentOS) ping utility does show that 'www.google.com' is available:
[oracle#prophet:bin]$ which ping; ping www.google.com
/usr/bin/ping
PING www.google.com (64.233.177.105) 56(84) bytes of data.
64 bytes from 64.233.177.105: icmp_seq=1 ttl=46 time=15.6 ms
64 bytes from 64.233.177.105: icmp_seq=2 ttl=46 time=15.6 ms
64 bytes from 64.233.177.105: icmp_seq=3 ttl=46 time=15.7 ms
64 bytes from 64.233.177.105: icmp_seq=4 ttl=46 time=16.5 ms
^C
--- www.google.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 15.614/15.884/16.547/0.394 ms
[oracle#prophet:bin]$
I realize that if I do this (in my Perl program):
$p = Net::Ping->new('icmp');
Then su - root before I run the program, it'll work...
[oracle#prophet:bin]$ su root
Password:
[root#prophet:bin]# ./ping_test
Response1: 1
Response2: 1
[root#prophet:bin]#
... but, I'd like to be able to use Net::Ping (w/ icmp packets) without having to su - root. It's actually a requirement for an automation program I need to write. It seems a little crazy to me that I can run the ping (CentOS) utility as a regular user and get the expected results, but that trying to use Net::Ping as a regular user is a no-go.
Any ideas?
G
The ping utility works because it's setuid — it runs with root privileges, even when executed by a normal user:
-rwsr-xr-x 1 root root 44168 May 7 2014 /bin/ping
Like it or not, using ICMP inherently requires root privileges. You can't do it as a normal user.
If you want to check for connectivity, consider making a TCP connection. (Or, heck, a full HTTP request.)

Why ping unknown host is happening when inside a while loop?

I am trying to get a column from a csv file and ping each line in a while loop
But every time it just show ping:unknown host (website)
#!/bin/bash
while IFS=, read num ip; do
echo $num
ping -c 10 $ip
done <site.csv
And the format of the csv file is
1, facebook.com
2, google.com
And the result will always be
ping: unknown host facebook.com
ping: unknown host google.com
But when I just ping the website directly, it is actually working, so i think is not the network problem
-bash-4.1$ ping -c 2 facebook.com
PING facebook.com (173.252.120.6) 56(84) bytes of data.
64 bytes from edge-star-shv-12-frc3.facebook.com (173.252.120.6): icmp_seq=1 ttl=70 time=94.1 ms
64 bytes from edge-star-shv-12-frc3.facebook.com (173.252.120.6): icmp_seq=2 ttl=70 time=93.8 ms
--- facebook.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1094ms
rtt min/avg/max/mdev = 93.882/94.040/94.199/0.345 ms
Is it the while loop or read the column from the csv causing the prooblem?
Is there a way to use a wile loop to read the site from the csv file and ping it?
Following up on Glenn Jackman's suggestion that the problem is DOS line-endings, here is a simple way to make sure that they are removed from the input. Replace:
while IFS=, read num ip; do
With:
while IFS=$',\r' read num ip; do
By adding \r to IFS, this makes the shell treat the DOS character as a field separator. This means it does not become part of ip.

Linux - ping all devices in a file to check accessibility

I have a file with about 500 devices which I need to ping to check if they're currently accessible or not from various subnets around my network. It's essentially a basic test to check for routing/accessibility issue.
Not sure where to start really. I have a basic file in which I have put each individual IP in a file line-by-line.
For example, the file looks like this:
192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.4
I'd need it to return something like the following, if the third in line didn't get a reply:
192.168.1.1 Accessible
192.168.1.2 Accessible
192.168.1.3 Inaccessible
192.168.1.4 Accessible
I'm running Ubuntu here. Apologies for not having any idea where to start !
Cheers
Steve.
You should use nmap in ping scan mode with:
nmap -sn -oG - -v -iL hosts_to_scan.txt
This will try to ping all hosts contained in the hosts_to_scan.txt file.
By the way, you can also specifify a subnet, if that is the case:
nmap -sn -oG - -v 192.168.1.0/24
And/or save the result to file:
nmap -sn -oG status.txt -v 192.168.1.0/24
nmap -sn -oG status.txt -v -iL hosts_to_scan.txt
I would use nmap probably for a long list, but if you are in a command line and need a quick one-liner, this will do also:
$ for i in `cat file.txt `;do ping -c 1 $i;done
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: icmp_seq=0 ttl=50 time=16.271 ms
--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 16.271/16.271/16.271/0.000 ms
PING 8.8.4.4 (8.8.4.4): 56 data bytes
64 bytes from 8.8.4.4: icmp_seq=0 ttl=50 time=16.030 ms
--- 8.8.4.4 ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 16.030/16.030/16.030/0.000 ms
On a positive note, this method it's quick and easy to remember. Works (probably) with all major shells (bash, zsh, *sh?).
On the other hand it's fairly verbose and you don't want that in say 200 IP's, even 10 might be hard to monitor.
I would write a script in ruby, or pytho or whatever language you like if nmap can't cut it.
EDIT: This one is cleaner and also has some additional stats:
for i in `cat file.txt `;do ping -c 1 $i|grep 64;done
64 bytes from 8.8.8.8: icmp_seq=0 ttl=50 time=15.397 ms
64 bytes from 8.8.4.4: icmp_seq=0 ttl=50 time=13.170 ms
There's virtually nothing that can't be done with gnu-tools.
Basic schema would be to ping each one of the servers and print the result.
If you store the IPs in a ips.txt file, you could do:
while read my_ip
do
test_ping $my_ip
done < ips.txt
And then create a function such as test_ping, that pings once to each IP:
test_ping () {
if ping -c 1 $1 &> /dev/null
then
echo "$1 Accessible"
else
echo "$1 Inaccessible"
fi
}

Resources