Home > Software design >  ping several times and get return status for each ip
ping several times and get return status for each ip

Time:09-16

I am trying to ping all ip's on 192.168.2-254 simultaneously and get the return status of each one. this is what I have so far but it doesn't work and instead just returns the status of xargs. Any help is appreciated! I do not want to use nmap...

subnet="192.168.1"
num="2"
  while [ "$num" -lt "254" ]; do
     num=$((num 1))
     printf "${subnet}.${num}\n"
  done | xargs -n 1 -I ^ -P 50 ping -c2 -t3

CodePudding user response:

The well-established and documented behavior of xargs is to return an exit code of its own which indicates what happened to all of the subprocesses you started. To wit;

xargs exits with the following status:

0 - if it succeeds

123 - if any invocation of the command exited with status 1-125

124 - if the command exited with status 255

125 - if the command is killed by a signal

126 - if the command cannot be run

127 - if the command is not found

1 - if some other error occurred.

(Source: GNU xargs man page. The POSIX spec is slightly less specific, and simply lumps all of 1-125 into "A command line meeting the specified requirements could not be assembled, one or more of the invocations of utility returned a non-zero exit status, or some other error occurred.")

There is no simple way to communicate the status of multiple processes in a single exit code (recall that the value is a single byte, so even if you were to encode return values as bit fields, indicating only success or failure, you could still only cram eight of them into one value) but if I understand your request correctly, just run ping in the loop you are running anyway, and wait individually for each one. The following uses a Bash array to keep track of the individual processes:

declare -a procs

for((num=2; num<254; num  )); do
    ping -c2 -t3 "192.168.1.${num}" &
    procs =($!)
done
for p in "${procs[@]}"; do
    wait $p; echo $?
done

The output from over 200 ping processes running in parallel will be rather noisy; perhaps add >/dev/null after the first done. (Redirecting everything once is more efficient than redirecting each ping separately.)

This doesn't yet keep track of which process ID belonged to which IP address; if you need that, probably use an associative array (Bash 4 ) or put the IP addresses into a second array and keep them aligned so that ${ip[x]} is the IP address belonging to process ${procs[x]} (e.g. MacOS still ships with Bash 3.2.57(1)-release which doesn't support associative arrays).

Here's a refactoring to use an associative array.

declare -A procs

for((num=2; num<254; num  )); do
    ping -c2 -t3 "192.168.1.${num}" &
    procs[$num]=$!
done >/dev/null
for p in "${!procs[@]}"; do
    wait ${procs[$p]}
    printf "%s:%i\n" "192.169.1.$p" $?
done

CodePudding user response:

@M Horton Will this serve your purpose . In xargs field use xargs -n1 -P50 ping -c2

  • Related