Life of a geek is not without its temptations, they come sometimes in the guise of friends asking me to join for a steaming hot cup of coffee or the company of a sweet young thing :o)
Mostly I give in to temptations and allow myself to be drawn away from my computer terminal. Being a little paranoid about security I don't leave my console unattended instead I prefer to log off completely. But that's not always possible since I have quite a few jobs running in background, now what is fastest and the best way to get rid of them so that I can log off and leave them running after I am gone? disown is the answer. This bash specific command allows us to unbind various jobs from the current login session. I use 'disown <jobid>' to get rid of the job(s) running on my console login session. Volia now I can logoff and run.
But wait why not use some computing time while I am gone, perhaps I can compile a new kernel or download a package with wget. Using the nohup command is apt here since I am planning to logoff leaving the computer to do the tasks. Just prefix nohup before any command and run it in the background by placing "&" at the end of the command, that's it.
How does disown and nohup commands work? What they do is that they connect all your process to the parent process of the computer which happens to init (the granddaddy of all process running on the computer). Viewing all the process on the computer help us understand it better, Look a the the output of the pstree command below. The init is first (root of the inverted tree) process which radiates all the other process in the computer. Here you can see various daemons like cron,dbus etc, and also various programs like emacs, iceweasel (firefox), pidgin, xterm, xpdf.
$ pstree
init-+-cron
|-daemon
|-another-daemon
|-emacs
|-getty
|-login---bash---links
|-login---bash---startx---xinit-+-Xorg
| `-fluxbox-+-bash-+-firefox-bin---7*[{firef+
| | `-pidgin
| `-xterm---bash-+-pstree
| `-xpdf.bin
|-preload
|-syslogd
`-udevd
You might ask me why I don't use screen instead of nohup ? Well, I tend not to use screen for those commands that don't need my supervision. I might run my rss reader raggle under screen but not commands like updating locate databases, downloading packages or files using bittorrent I leave it to nohup.
It's not "disown <pid>" but "disown <jobid>". It can be quite misleading! :-)
ReplyDeleteIt's not "disown <pid>" but "disown <jobid>". It can be quite misleading! :-)
ReplyDeleteYou are so right Roberto! What was I think when I wrote that post.
ReplyDelete> Just prefix nohup before any command
ReplyDelete> and run it in the background by placing
> "&" at the end of the command, that's it.
Just a hint: that fills your directories with "nohup.out" files, please see http://www.basicallytech.com/blog/index.php?/archives/70-Shell-stuff-job-control-and-screen.html
That's a good point
ReplyDeleteDefinitely loving this idea, but is there any way to reattach a job later?
ReplyDeleteHi Jay,
ReplyDeleteScreen and nohup allows you to do that but not disown.
dettach is a command you might like Jay.
ReplyDeleteI'm not a fan of nohup especially when running a process that uses stdout and stderr for different things. nohup does &>nohup.out. I prefer to use a subshell and redirect output appropriately to a logic name with date stamps. Something like:
ReplyDelete$ (./do.sh >out.$(date +%s) 2>err.$(date +%s) &)
I just ran into a situation where I wanted to disown a command so that it wouldn't die when the terminal it was started under was closed (I forgot to run it in screen and didn't want to start it over). Using ctrl-z, I stopped the job, but forgot to start it again using bg before I disowned it.
ReplyDeleteYou can send control signals to processes using kill, so in this instance I issued SIGCONT to the PID of the command that was stopped:
$ sudo kill -SIGCONT $PID
Note that processes that have been stopped (either by kill -SIGSTOP or hitting ctrl-z while the job is in the foreground) have a state of T in ps aux/top.
You might have to issue the SIGCONT signal to more than one process if it was running as part of a group.