imll
imll

Reputation: 341

Cannot exit bash script at the end of the for cycle

I wrote a simple IP scanner based on ping (see below), but it has a problem.

#!/bin/bash

counter = 0

for ip in 192.168.44.{1..254}; do
  ping -c 1 -W 1 $ip | grep "64 bytes" &
  let counter++
  if [[ "$counter" -eq 254 ]];
  then
      exit 0;
  fi
done

First of all, the for cycle appears to be launching multiple threads and the only output to the terminal are the ping answers. However, when the script finishes pinging all the machines in the network, it never exits, as you can see in the next screenshot:

Script output

and I have to press Enter to finally end it.

I've also tried to place an exit 0 after the done statement, but it still does not work. How can I make the script exit when the for cycle ends?

Note: I've found this implementation to be the fastest to find the existing machines in a LAN, but if anyone has a suggestion of a more appropriate code, I would appreciate it.

Upvotes: 1

Views: 99

Answers (3)

Ole Tange
Ole Tange

Reputation: 33685

If CTRLc is acceptable:

parallel -j0 --lb ping ::: 192.168.1.{1..250}

Upvotes: 0

dash-o
dash-o

Reputation: 14452

Assuming that you do not want to use a dedicated network scanning tools, You can use bash or xargs to iterate over all addresses in parallel: Bash:

#! /bin/bash -x

for ip in 192.168.44.{1..254}; do
  ping -c 1 -W 1 $ip | grep "64 bytes" &
done
# Wait for all children to finish
wait

Or with xargs, with the advantage that you can control the number of parallel addresses being pinged (20 in this example) - to avoid overloading your server with large number of concurrent process.

echo 192.168.44.{1..254} | xargs --max-args=1 -P20 ping -c 1 -W 1

Upvotes: 1

UtLox
UtLox

Reputation: 4154

You can try this:

#!/bin/bash
for ip in 192.168.44.{1..254}; do
  ping -c 1 -W 1 $ip | grep "64 bytes" & 
done
wait

Upvotes: 1

Related Questions