Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I want to run a command until it completes sucessfully, then stop. I know I can set up a bash loop to do this, but I'm curious if there are any portable ways to do this similar to watch -n5 that would do what I'm looking for.

The use case: I'm trying to connect via SSH to a server that may not be up yet.

share|improve this question

5 Answers 5

up vote 4 down vote accepted

Just wrap said bash loop in a script, using $1 to specify the actual command to be executed and $2 for an arbitrary sleep value. Doing this, you'd be able to run the command like:

$ reallyrunit "ls" 5
share|improve this answer
# xxx.xxx.xxx.xxx = ipaddr ssh host
until [ `nmap --open -p 22 xxx.xxx.xxx.xxx |grep -c "ssh"` -eq 1 ]
do 
sleep 4
done 

# ssh stuff here
share|improve this answer

I'm not aware of a builtin to so this, but the bash to use is something like:

RET=1;until [[ $RET = 0 ]];do echo "$(date): About to make an attempt to connect"; ssh 192.168.33.12; RET="$?";sleep 1;done

EDIT: Added date and comment so you can track how long it has been failing for.

share|improve this answer

I would structure this in a bash loop. I suppose you could also poll the system (ping, nmap or otherwise) to determine the service state and connect if successful.

share|improve this answer

You can set the exit value to a non-zero value and then loop until the command returns with a exit 0 (success). Here is a script I have that does that:

#!/bin/sh

cd /exports/home/exports/sl
$(exit 1)


while [ $? != 0 ]; do rsync -avlH --delete  --exclude=6.1/archive --exclude=6.1/i386/archive --exclude=6.1/x86_64/archive --exclude=6.1/i386/iso --exclude=
6.1/x86_64/iso rsync://rsync.gtlib.gatech.edu/scientific/6.1 6.1/; done

Not the best of scripts - it was more of a thought experiment of ensuring that the rsync will restart when it fails until it has finished successfully.

Edit: In your case, you probably want something like:

#!/bin/sh

$(exit 1) ; while [ $? != 0 ]; do sleep 1 ; nc -vvv  -z 192.168.15.37 22  && ssh 192.168.15.37  ; done

You can add error conditions here and there, but the important thing is to immediately connect once you verify the port is open, which is what the && operation is for - it will execute the next command if the previous command was successful. (Until then, a failed connection will return a non-zero exit code, which will cause the loop to continue). Once you login successfully and then log out, the exit code that is returned from that successful login session will terminate the loop.

(the sleep command is optional, but note that in some cases, without a sleep loop, your display may slow down until you either minimize it or switch to the next window, which could be a problem if your display is a remote desktop)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.