Reputation: 642
I have a netcat installed on my local machine and a service running on port 25565. Using the command:
nc 127.0.0.1 25565 < /dev/null; echo $?
Netcat checks if the port is open and returns a 0 if it open, and a 1 if it closed.
I am trying to write a bash script to loop endlessly and execute the above command every second until the output from the command equals 0 (the port opens).
My current script just keeps endlessly looping "...", even after the port opens (the 1 becomes a 0).
until [ "nc 127.0.0.1 25565 < /dev/null; echo $?" = "0" ]; do
echo "..."
sleep 1
done
echo "The command output changed!"
What am I doing wrong here?
Upvotes: 52
Views: 61513
Reputation: 8446
Keep it Simple
Bash and other sh
shells provide an until
... do
... done
loop:
until nc -z 127.0.0.1 25565
do
echo ...
sleep 1
done
Just let the shell deal with the exit status implicitly
The shell can deal with the exit status (recorded in $?
) in two ways, explicit, and implicit.
Explicit: status=$?
, which allows for further processing.
Implicit:
For every statement, in your mind, add the word "succeeds" to the command, and then add
if
, until
or while
constructs around them, until the phrase makes sense.
until nc
succeeds; do ...; done
* Bash manual: until ... do ... loop
The -z
option will stop nc
from reading stdin, so there's no need for the < /dev/null
redirect.
Upvotes: 123
Reputation: 492
I personally like @Lee Duhem solutions better, although I think I have a better way of executing it.
This will run until it exits success:
while true; do
nc 127.0.0.1 25565 < /dev/null && break
done
This will run until it exits failure:
while true; do
nc 127.0.0.1 25565 < /dev/null || break
done
And a one-line equivalent of the first:
while true; do nc 127.0.0.1 25565 < /dev/null && break; done
Upvotes: 6
Reputation: 15121
You could try something like
while true; do
nc 127.0.0.1 25565 < /dev/null
if [ $? -eq 0 ]; then
break
fi
sleep 1
done
echo "The command output changed!"
Upvotes: 23