Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Sometimes you run a program from the terminal, say, lxpanel. The terminal won't drop you back to the prompt, it'll hang. You can press Ctrl+C to get back to the prompt, but that will kill lxpanel. However, pressing Alt+F2 (which pops up a window to take a command) and running lxpanel works gracefully.

Why is this? What is different between running a command from the terminal and from the 'run' window that appears when you press Alt+F2?

lxpanel here was just used as an example. I have experienced this with multiple programs

share|improve this question
1  
Tip: GNU Screen (screen) can, among other things, be used to "wrap" longer-running processes. You can detach from it, going back to shell, then reattach and see output from the running process. Reattachment can even be done from another terminal, SSH etc. There may also be other programs that let you do this sort of thing. –  poplitea Dec 28 '11 at 7:10

4 Answers 4

up vote 23 down vote accepted

By default the terminal will run the program in the foreground, so you won't end up back at the shell until the program has finished. This is useful for programs that read from stdin and/or write to stdout -- you generally don't want many of them running at once. If you want a program to run in the background, you can start it like this:

$ lxpanel &

Or if it's already running, you can suspend it with Ctrl+Z and then run bg to move it into the background. Either way you will end up with a new shell prompt, but the program is still running and its output will appear in the terminal (so it can suddenly show up while you're in the middle of typing)

Some programs (typically daemons) will fork a separate process when they start, and then let the main process immediately exit. This lets the program keep running without blocking your shell

share|improve this answer
1  
Beat me to it :) –  phunehehe Dec 26 '11 at 7:29
2  
@phunehehe I'm impressed this got three answers in the first 15 minutes on Christmas night. Go U&L –  Michael Mrozek Dec 26 '11 at 7:33
2  
@lyrae: by default, the shell waits for the program to complete before continuing the shell session, it does not "hang", by any definition of "hang"; alt+f2 does not wait for the program. The reason the shell waits for the program to complete is because the shell can redirect whatever the user typed into the shell to the program's standard input and/or display program's standard output. Since alt+f2 is primarily used for starting a GUI program, alt+f2 do not provide the possibility of using standard input/output and so it do not need to wait. –  Lie Ryan Dec 26 '11 at 10:20
1  
@lyrae: alt+f2 does not do anything special to start the program in background; it is the shell that's doing something special, adding '&' is the shell's functionality. When starting a command without a '&', the shell redirects the program's standard input to its own standard input and the program's standard output to its own standard output (a bit contrived, since the shell also provides many other services, such as intercepting Ctrl-C, to send a SIGINT signal command to the foreground program). The '&' tells the shell not to do those and just start the program (also contrived). –  Lie Ryan Dec 26 '11 at 10:31
1  
@LieRyan some of what you're saying the shell does is in fact handled by the kernel's terminal driver, and "with &" is generally more "special" than "without &", other than that the shell calls wait() [or waitpid or equivalent] which isn't done by alt-f2. –  Random832 Dec 26 '11 at 18:12

When you start a program in a terminal, the terminal will "hang" until your program stops. By pressing Ctrl+c you are closing your program, and thus get back to the prompt. You will see this with all GUI apps, try Firefox, for example.

When you use some other method such as Alt+F2 or clicking through the menus, your program is started in the background so nothing weird happens (and there is no command prompt anyway).

If you still want to launch GUI apps from the terminal, append & at the end of your command, like so

lxpanel &

This tells the terminal to run lxpanel in the background and give you another prompt immediatelly.

share|improve this answer

Programs run via a shell run in the foreground of that shell by default. This causes the shell to suspend operation and direct stdin/stdout/sterr from the terminal to the program. Programs run via the desktop environment are forked, which causes them to run independent of the program that ran them. This can be simulated in most shells by appending a & to the command, although this will still connect std* to the terminal (although reading from stdin on a backgrounded program has further complications).

share|improve this answer

The & backgrounds well except for programs that come back requiring console interaction later on (for example, an "apt -y update &" that eventually enters the STOP state since it's wanting to prompt the user a "really really force?" question much later....when no one is watching anymore).

To plug that hole and inform the process a terminal will really never never become available to it, I append a <&- to some of my commands, completely detaching them from the active terminal telling them STDIN is no longer possible. Make sure /bin/bash is your shell if you use that though. The script will carry on logging any errors related to no pseudoterminal being available on which to cast any prompt.

For example:

`./runme.sh &> runme.log <&- & disown`

is my ultimate way of disassociating from current terminal session. Both STDOUT and STDERR get logged to runme.log, it won't matter if your console or shell terminate sooner or if you logout/su to a different account (no terminal garbage from runme), and thanks to disown even the parent-child PID relationship is removed.

UPDATE: even with that I've had trouble with a semaphore associating it with the name of the original parent, so now I recommend instead:

at now <<< "(cmd1; cmd2; etc.) &> logfile.log"

Of course, remove the &> if you want to get emailed the output from CRON, or redirect it all to /dev/null instead of a file.

share|improve this answer
    
A slightly less convoluted way to achieve that I began using is at now <<< "(cmd1; cmd2; etc.) &> logfile.log" –  Marcos Jan 31 '12 at 11:11

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.