Tell me more ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I use Tilda (drop-down terminal) on Ubuntu as my "command central" - pretty much the way others might use GNOME Do, Quicksilver or Launchy.

However, I'm struggling with how to completely detach a process (e.g. Firefox) from the terminal it's been launched from - i.e. prevent that such a (non-)child process

  • is terminated when closing the originating terminal
  • "pollutes" the originating terminal via STDOUT/STDERR

For example, in order to start Vim in a "proper" terminal window, I have tried a simple script like the following:

exec gnome-terminal -e "vim $@" &> /dev/null &

However, that still causes pollution (also, passing a file name doesn't seem to work).

share|improve this question
That, too, is a good question. I think it's fair to consider Bash a programming language - although indeed the scope of this question is probably more on the sysadmin side... – AnC Mar 23 '09 at 12:26
This is a duplicate of this question stackoverflow.com/questions/285015/… – Dana the Sane Mar 23 '09 at 13:11
dup of:superuser.com/questions/177218/… – behrooz Apr 25 '11 at 18:07

migrated from stackoverflow.com Aug 21 '10 at 4:05

10 Answers

First of all; once you've started a process, you can background it by first stopping it (hit Ctrl-Z) and then typing bg to let it resume in the background. It's now a "job", and its stdout/stderr/stdin are still connected to your terminal.

You can start a process as backgrounded immediately by appending a "&" to the end of it:

firefox &

To run it in the background silenced, use this:

firefox </dev/null &>/dev/null &

Some additional info:

nohup is a program you can use to run your application with such that its stdout/stderr can be sent to a file instead and such that closing the parent script won't SIGHUP the child. However, you need to have had the foresight to have used it before you started the application. Because of the way nohup works, you can't just apply it to a running process.

disown is a bash builtin that removes a shell job from the shell's job list. What this basically means is that you can't use fg, bg on it anymore, but more importantly, when you close your shell it won't hang or send a SIGHUP to that child anymore. Unlike nohup, disown is used after the process has been launched and backgrounded.

What you can't do, is change the stdout/stderr/stdin of a process after having launched it. At least not from the shell. If you launch your process and tell it that its stdout is your terminal (which is what you do by default), then that process is configured to output to your terminal. Your shell has no business with the processes' FD setup, that's purely something the process itself manages. The process itself can decide whether to close its stdout/stderr/stdin or not, but you can't use your shell to force it to do so.

To manage a background process' output, you have plenty of options from scripts, "nohup" probably being the first to come to mind. But for interactive processes you start but forgot to silence (firefox < /dev/null &>/dev/null &) you can't do much, really.

I recommend you get GNU screen. With screen you can just close your running shell when the process' output becomes a bother and open a new one (^Ac).


Oh, and by the way, don't use "$@" where you're using it.

$@ means, $1, $2, $3 ..., which would turn your command into:

gnome-terminal -e "vim $1" "$2" "$3" ...

That's probably not what you want because -e only takes one argument. Use $1 to show that your script can only handle one argument.

It's really difficult to get multiple arguments working properly in the scenario that you gave (with the gnome-terminal -e) because -e takes only one argument, which is a shell command string. You'd have to encode your arguments into one. The best and most robust, but rather cludgy, way is like so:

gnome-terminal -e "vim $(printf "%q " "$@")"
share|improve this answer
Thanks a lot for this! Sadly I can only accept one answer. I ended up with "nohup $@ &> /dev/null &" and "alias wvim='launch.sh gnome-terminal -x vim'" – AnC Mar 23 '09 at 21:33
1  
What a fantastically detailed and informative answer. +1 – Helgi Hrafn Gunnarsson Oct 19 '11 at 16:06
nohup cmd &

nohup detaches the process completely (daemonizes it)

share|improve this answer
what a fantastically succinct answer. Bravo! – dsummersl Aug 9 '12 at 1:38

If you are using bash, try "disown". Otherwise you can try "at now".

share|improve this answer
"disown" don't seem to be an internal bash command (not available on my machine, and I use bash). "nohup", as Ben suggested, might be a much better (and standard) way of doing this. – Eigir Mar 23 '09 at 12:08
1  
never thought of using "at", thanks for the idea! – cadrian Oct 10 '12 at 15:01
1  
at to delegate execution to someone else, I like it! +1 – Ninsuo Apr 12 at 19:23

I think screen might solve your problem

share|improve this answer

You can run your command using the nohup command, this detach your process and redirects outputs to a given file... but I am not sure that is exactly what you need ..

share|improve this answer
I could swear I had tried nohup before using exec - but apparently not properly, as it does work like this: nohup gnome-terminal -e "vim $@" &> /dev/null & – AnC Mar 23 '09 at 12:30

in tcsh (and maybe in other shells as well), you can use parentheses to detach the process.

Compare this:

> jobs # shows nothing
> firefox &
> jobs
[1]  + Running                       firefox

To this:

> jobs # shows nothing
> (firefox &)
> jobs # still shows nothing
>

This removes firefox from the jobs listing, but it is still tied to the terminal; if you logged in to this node via 'ssh', trying to log out will still hang the ssh process.

share|improve this answer

To disassociate tty shell run command through sub-shell for e.g.

(command)&

When exit used terminal closed but process is still alive.

check -

(sleep 100) & exit

Open other terminal

ps aux | grep sleep

Process is still alive.

share|improve this answer

Try daemon -- should be available from your friendly package manager and comprehensively take care of every way of disassociating itself from the terminal.

share|improve this answer

I have found on Mac OS X that I need to use both nohup AND disown to ensure that the child process is not torn down with the terminal.

share|improve this answer

Don't forget that you can manually background and foreground like so:

./script.sh
# suspend process
{ctrl-Z}
# background process
bg
# list all backgrounded jobs
jobs
# bring it back to foreground
fg
share|improve this answer

Your Answer

 
discard

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