2007/12/01

Issue a sequence of commands, and walk away

You're ssh'd into a server and need to issue a sequence of commands that'll take awhile - and your connection might drop, terminating those commands. Try this:
nohup bash -c "cmd1; cmd2; cmd3" &

Which starts the sequence and sends it immediately to the background (the trailing ampersand) - and also sets it so that even if the controlling terminal goes away, it continues to run (via "nohup"). If you really do need to kill it, use the -KILL signal.

Caveats: Watch your stdin/stdout/etc - this is generally most useful for commands that require no input and generate no output, since, for example, you just disconnected stdin and stdout by sending it to the background.

The above is handy to know if you need to sudo the commands - since you will: a) not see the "Password:" prompt, and b) not be able to respond to it. Here's the cheat: As long as you're in a default ssh config, there's a timeout; sudo commands issued within the timeout don't prompt. So if you need to sudo the above, issue an innocuous "sudo ls" (or some such) just before, to authenticate and get the timer running.

To find out what background jobs there are:
jobs -l

Which also shows the process ID, so you can watch it via top or some such.

Want a little more feedback? How about:
nohup time bash -c "date; cmd1; cmd2; cmd3" &

Which will display the date the inner commands started and then some stats about the time the other commands took, after they're all done.

Need to make sure they each work, before going to the next? Try this:
nohup bash -c "cmd1 && cmd2 && cmd3" &

The double ampersand tells bash to execute following commands ONLY if the previous one succeeded. (More specifically, if it's exit code was zero.)

And you can get more fancy by putting some "echo" commands in there, piping the output to mail, etc.

No comments: