Network monitoring ping - bash

i am reading from a txt file several hundred ip addresses, want to ping the list to the end of the file. would like this to run in a loop instead, read to the end of the file, then start at the first address again.
trap 'echo ****Interrupted****; exit'INT
echo -n "Enter the file name with the ip addresses"
read file
echo -n "Enter the file name for the log file"
read log
while read line
do
echo "pinging: "$line
echo -e "">>$log
echo -n "NEXT PING: ">>$log
echo -n "$line" : " >>$log
$ping -c 3 -W 2 $line >>$log
done <"$file"

Use fping.
http://fping.org/
From the fping man page:
DESCRIPTION
fping is a program like ping(8) which uses the Internet Control Message
Protocol (ICMP) echo request to determine if a target host is responding.
fping differs from ping in that you can specify any number of targets on the
command line, or specify a file containing the lists of targets to ping.
Instead of sending to one target until it times out or replies, fping will
send out a ping packet and move on to the next target in a round-robin
fashion.

Related

bash to automate input file daily + ping test

I'm running a ping test for 100 IP's daily, every day the input file IP will get updated becauses its dynamic. And I'm specifying input(100 IP list) as first argument. As the below script will ran for every 10 mins
Note:- I'm using different IP's everyday, so need to change the input file every day at 12AM
Running script as background at Apr 1 at 12AM
sh ping.sh IPlist_apr1.txt &
on second day my secondary script(which will create updated IP's) will choose other set of IP's in this file format 'IPlist_apr2.txt'
On third day - IPlist_apr3.txt ... and it will log $1.log every day on the CWD.
likewise this process continue, What I'm actually looking my ping script should handle the list day by day as first argument.
Snippet of my actual script.
t=10m
ip=$1 #### specify the file having IP's
while sleep $t
do
if ping -c1 $ip >/dev/null 2>&1; then
echo "`date +%H:%M`: $ip is up";
else
echo "`date +%H:%M`: $ip is down";
fi >>$1.log;
done
You need to read the IP addresses from the file named by the argument.
while IFS= read -r ipaddr; do
if ping -c1 "$ipaddr"; then
status=up
else
status=down
fi
printf '%s: %s is %s\n' "$(date +%H:%M)" "$ipaddr" "$status"
done < "$1"
Note that this runs one batch of pings, then exits. The caller should be responsible for sleeping 10 minutes and specifying the correct file name for the input.

bash read timeout from serial port

I'm trying something like Linux serial port listener and interpreter?
However, I want a timeout
#!/bin/bash
stty -F /dev/ttyUSB1 300 cs7 parenb -parodd
echo -n -e 'Sending '
echo -n -e "\x2F\x3F\x21\x0D\x0A">/dev/ttyUSB1
read LINE -r -t1 </dev/ttyUSB1
echo -n "Read "
echo $LINE
I'd like to continue if I do not get input; it just hangs.
(It is part of an input routine for reading a powermeter https://electronics.stackexchange.com/questions/305745/ir-data-from-landisgyr-e350)
Based on this answer, I think you can use the timeout function to get what you want.
You'll probably have to do a bit of formatting and redirect the file to stdout, like in this answer, so it would look like this :
LINE="$(timeout 1 cat /dev/ttyUSB1)"
echo -n "Read "
echo $LINE
You can also just use a combination of sleep and kill, like in here.

the bash script only reboot the router without echoing whether it is up or down

#!/bin/bash
ip route add 10.105.8.100 via 192.168.1.100
date
cat /home/xxx/Documents/list.txt | while read output
do
ping="ping -c 3 -w 3 -q 'output'"
if $ping | grep -E "min/avg/max/mdev" > /dev/null; then
echo 'connection is ok'
else
echo "router $output is down"
then
cat /home/xxx/Documents/roots.txt | while read outputs
do
cd /home/xxx/Documents/routers
php rebootRouter.php "outputs" admin admin
done
fi
done
The other documents are:
lists.txt
10.105.8.100
roots.txt
192.168.1.100
when i run the script, the result is a reboot of the router am trying to ping. It doesn't ping.
Is there a problem with the bash script.??
If your files only contain a single line, there's no need for the while-loop, just use read:
read -r router_addr < /home/xxx/Documents/list.txt
# the grep is unnecessary, the return-code of the ping will be non-zero if the host is down
if ping -c 3 -w 3 -q "$router_addr" &> /dev/null; then
echo "connection to $router_addr is ok"
else
echo "router $router_addr is down"
read -r outputs < /home/xxx/Documents/roots.txt
cd /home/xxx/Documents/routers
php rebootRouter.php "$outputs" admin admin
fi
If your files contain multiple lines, you should redirect the file from the right-side of the while-loop:
while read -r output; do
...
done < /foo/bar/baz
Also make sure your files contain a newline at the end, or use the following pattern in your while-loops:
while read -r output || [[ -n $output ]]; do
...
done < /foo/bar/baz
where || [[ -n $output ]] is true even if the file doesn't end in a newline.
Note that the way you're checking for your routers status is somewhat brittle as even a single missed ping will force it to reboot (for example the checking computer returns from a sleep-state just as the script is running, the ping fails as the network is still down but the admin script succeeds as the network just comes up at that time).

output of dns-sd browse command not redirected to file in busybox shell(ash)

To check if mdnsd is in probing mode we are using below command to browse for service and redirect its output a file, and hostname of the device is found in the command we decide that mdnsd is in probing mode.
command used for publishing service
dns-sd -R "Test status" "_mytest._tcp." "local." "22"
To browse the service following command is used (Running in background)
dns-sd -lo -Z _mytest._tcp > /tmp/myfile &
To display the content of the file used cat.
cat /tmp/myfile
myfile is empty, if > replaced with tee , I see output on console myfile remains empty.
I am unable to understand what is going on.
Is there any pointer, help
EDIT
Just for completeness adding output, which i missed adding before.
# dns-sd -lo -Z _mytest._tcp local
Using LocalOnly
Using interface -1
Browsing for _mytest._tcp
DATE: ---Tue 25 Apr 2017---
11:09:24.775 ...STARTING...
; To direct clients to browse a different domain, substitute that domain in place of '#'
lb._dns-sd._udp PTR #
; In the list of services below, the SRV records will typically reference dot-local Multicast DNS names.
; When transferring this zone file data to your unicast DNS server, you'll need to replace those dot-local
; names with the correct fully-qualified (unicast) domain name of the target host offering the service.
_mytest._tcp PTR Test\032status._mytest._tcp
Test\032status._mytest._tcp SRV 0 0 22 DevBoard.local. ; Replace with unicast FQDN of target host
Test\032status._mytest._tcp TXT ""
You appear to have a program with behavior that differs based on whether its output is to a TTY. One workaround is to use a tool such as unbuffer or script to simulate a TTY.
Moreover, inasmuch as the use of a file at all is done as a workaround, I suggest using a FIFO to actually capture the line you want without needing to write to a file and poll that file's contents.
#!/bin/sh
newline='
'
# Let's define some helpers...
cleanup() {
[ -e /proc/self/fd/3 ] && exec 3<&- ## close FD 3 if it's open
rm -f "fifo.$$" ## delete the FIFO from disk
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then ## if our pid is still running...
kill "$pid" ## ...then shut it down.
fi
}
die() { cleanup; echo "$*" >&2; exit 1; }
# Create a FIFO, and start `dns-sd` in the background *thinking* it's writing to a TTY
# but actually writing to that FIFO
mkfifo "fifo.$$"
script -q -f -c 'dns-sd -lo -Z _mytest._tcp local' /proc/self/fd/1 |
tr -d '\r' >"fifo.$$" & pid=$!
exec 3<"fifo.$$"
while read -t 1 -r line <&3; do
case $line in
"Script started on"*|";"*|"") continue;;
"Using "*|DATE:*|[[:digit:]]*) continue;;
*) result="${result}${line}${newline}"; break
esac
done
if [ -z "$result" ]; then
die "Timeout before receiving a non-boilerplate line"
fi
printf '%s\n' "Retrieved a result:" "$result"
cleanup

netcat script to send a message to a marquee device

I wrote a script that uses netcat to update the marquee in my office without knowing the ip address of the device. I used fping to calculate candidateIPs.
The script works. But, I still don't know the IP address of the device. Can someone help me understand how to update the script to narrow down the IP address that updated the text on the device?
#!/bin/bash
while read p; do
echo "try $p"
echo "\x00\x00\x00\x00\x00\x01\x5A\x30\x30\x02\x41\x41\x1B\x22\x61 Test message!\x04" | nc $p 3001 &
done < candidateIPs
wait
You can log your outputs an add verbosity e.g.
#!/bin/bash
while read p; do
echo "try $p"
echo "\x00\x00\x00\x00\x00\x01\x5A\x30\x30\x02\x41\x41\x1B\x22\x61 Test message!\x04" | nc -v "$p" 3001 2>&1 | tee "$p.log" &
done < candidateIPs
wait
You can examine either the ip-specific log files after that.

Resources