13

Say you start the job like this

foo

and then desire that you want to place it in background. Typing Ctrl+Z and then bg does the trick but will freeze foo between Ctrl+Z and bg. How can I place foo in the background without first freeze it?

Pro Backup
  • 4,924
  • 7
    What is the use case? Why is it a problem that the process freezes for a short time? – l0b0 Aug 05 '14 at 07:00

4 Answers4

6

Adding an & sign after the command (foo &) will background it immediately. But I believe there is no way, in a standard terminal/shell configuration, to background something immediately once it's foregrounded.

l0b0
  • 51,350
3

Technically foo already runs in the background. You can start a second terminal session, and the first one will continue to run foo while you do other things.

In X, this simply involves starting a second terminal application, or opening another tab if your terminal emulator of choice has such features.

On the console, if you didn't plan for it, you'd need to switch to a different virtual terminal and log in again.

If you use a terminal multiplexer like screen or tmux you can start another session within it. For example, in screen, this is done using Ctrl+A immediately followed by Ctrl+C. To switch between them, use C-a C-n and C-a C-p to go back and forth between terminal sessions.

user
  • 28,901
  • 1
    That is, it is not possible in bash. – user877329 Aug 05 '14 at 06:47
  • 3
    This answer seems to be based on a misunderstanding of the concept of a background job. A terminal has a "foreground process group" attribute, usually set by the shell, which makes processes in that group able to read from the terminal and receive tty-related signals like SIGINT. All processes running on the terminal which are not in the foreground process group are background processes. When you create a new terminal, the foreground job of the original terminal is still the foreground job on that terminal, even if you aren't looking at it. –  Aug 05 '14 at 15:47
  • @WumpusQ.Wumbley The point of my answer is that most (all?) systems that can run bash are multi-tasking by their very nature. On such a system, even if a process has, say, input focus, there is nothing inherently "foreground" about the process itself; foo itself (absent specific checking, which I'd guess in the wild is somewhere between rare and nonexistent) doesn't care whether it's running in the top-most window or even if there's something displaying its output. – user Aug 05 '14 at 20:06
  • 3
    my point is that when the question specifically mentions the words "background" and "job" - both of which are technical terms with meanings defined by the POSIX process group framework - as well as the mechanisms of Ctrl-Z and bg, both of which operate on process groups - and your answer suggests not using the process group functionality at all, and you use the word "background" in a way that doesn't match its actual definition - you aren't fitting your answer to the question. And to start off with "Technically foo already runs in the background"... just... No. Technically. –  Aug 05 '14 at 20:24
  • @WumpusQ.Wumbley Somehow I don't think the OP read the POSIX standard and thought "hmm, I'd like to use this, but I already started foo so now what do I do?". If you feel this answer (or other answers) is not useful in answering the question, I would encourage you to exercise your voting privileges as well as leaving an answer of your own answering the question from what you feel is the correct angle, rather than arguing about one of the answers left on the question. Maybe you feel for example l0b0's answer is better, but my answer offers a way to do at least roughly what the OP wants. – user Aug 05 '14 at 21:13
3

Sending an application from the foreground to the background requires cooperation from both the terminal and the shell. The terminal can't do it alone, because the shell has to set the foreground process group. The shell can't do it alone, because the terminal has to process the key press (the shell isn't in the foreground, so it can't receive a key press).

I have a zsh configuration where I can press Ctrl+Z twice in quick succession; the first press suspends the process, and the second press resumes it in the background. I don't know how to port it to bash.

If you're running in a terminal emulator that allows you to inject keystrokes, you could inject ^Zbg^M (using ^ notation for control characters). For example, with an X11 terminal emulator, run xdotool --window 1234 Ctrl_L+Z b g Return where 1234 is the window ID of the terminal emulator. With Screen, run screen -S foo -p 12 -X stuff $'\032bg\r' where foo is the name of the screen session and 12 is the window ID.

2

If your typing is not quick enough for the case then run kill -s SIGSTOP 1023 && kill -s SIGCONT 1023 from another shell, supposing 1023 as target PID.

DISCLAIMER: As Ruslan probably knew, that sequence actually restarts the job so quickly bash does not notice it.

41754
  • 95