May 172012

I’m sure you’ve done this before. You kick off some process in the background that you know will take a while, but then you realise that you need to logout, and that if you do, then the process will die when the shell exits. What to do? Surely you’ll not have to start again?

So you’ve done this:

   # rsync -a host1:/u01/data/ host2:/u02 &

What’s that? You forgot to background it and type the “&” ? Just type “Ctrl-Z” and then type bg – now it’s in the background.

So you’ve realised that you’ve kicked off a process without nohup and that you’ll need to logout. But you don’t want to lose the work the process has done, and don’t want to start it again. You wish you’d thought to run it with nohup in the first place, like this:

  # nohup rsync -a host1:/u01/data/ host2:/u02 &
[2] 4885
nohup: ignoring input and appending output to `nohup.out'

Is it too late? Do you really need to kill the backgrounded process and start it again from the beginning when it’s already come so far?

Not on your life, because there is a little bash builtin tucked away at the back of the man page that’s easy to miss – disown

All you need to do is execute disown with the job number as an argument. This job control procedure goes something like this (the number “[1]” is the job number):

  # jobs
[1]+ Running       rsync -a host1:/u01/data/ host2:/u02 &
  # disown %1

This will detach the detach the process with job number 1 – the rsync – from the running shell and prevent it from being orphaned when the shell is exited. The rsync will continue to run happily on its own while you’re off in the pub. Problem solved.

You’re welcome.

Matt Parsons is a freelance Linux specialist who has designed, built and supported Unix and Linux systems in the finance, telecommunications and media industries.

He lives and works in London.