27

I already know that pressing ctrl+z stops the app, then I can send the app to background with the bg command, but that means there is a brief preiod of time that the app is stopped.

How do I send the app directly to the background without stopping it?

3
  • 1
    Pretty sure you can't, if it's already running.
    – Kevin
    Mar 31, 2013 at 23:39
  • 1
    If your task requires your input "before disappearing" into the background, you can use tools like zenity or yad (if you like guis). They can still send and receive output from the background. I'm sure that playing with pipes and devices would also get you access to the console from background, but I'm not sure how to do it.
    – Joe
    Apr 5, 2013 at 23:06
  • @Joe That's cool, but not at all what I mean. I just want to send an app directly to background without pausing it. i.e. without pressing ctrl+z followed by running the command bg. Is there a single keystroke combo to send the app to background?
    – trusktr
    Apr 9, 2013 at 0:47

3 Answers 3

19

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).

A close approximation is to send the application to the background really fast. After all, an application shares CPU time with others and a pause of a few hundredths of a second shouldn't matter. (It does for real-time applications, so make sure to start those in the background.) I use a shell binding for Ctrl+Z that sends the last-foregrounded job to the background. That way, pressing Ctrl+Z Ctrl+Z sends a job to the background with minimal suspension time.

Here's my zsh binding, which also “background” a half-typed command when the command line is not empty.

fancy-ctrl-z () {
  emulate -LR zsh
  if [[ $#BUFFER -eq 0 ]]; then
    bg
    zle redisplay
  else
    zle push-input
  fi
}
zle -N fancy-ctrl-z
bindkey '^Z'          fancy-ctrl-z

In English, for the non-zsh-users in the audience:

  • Define a shell function that does the following:

    • If the length of the input buffer is 0, then put the current job (the job that was last suspended or started) in the background, and redisplay the prompt.
    • Otherwise, push the input buffer onto a stack and show a new prompt. Once the user enters a command or cancels it with Ctrl+C, the pushed buffer is brought back for further edition.
  • Bind this function to Ctrl+Z.

If you just want the backgrounding behavior regardless of whether the command line is empty:

function bg_ { builtin bg "$@"; }
zle -N bg_
bindkey '^Z' bg_

I don't know if you can do the same in bash. It should be as easy as bind -x '"\C-z": bg', except that bash leaves the tty stop character in place, so it never gets Ctrl+Z as input.

3
  • Interesting, let me see if this can be done in Bash. If so, this would be a solution. I'm not familiar with zsh. Mind explaining what your script does?
    – trusktr
    Apr 9, 2013 at 0:54
  • @trusktr See my edit. Apr 9, 2013 at 11:06
  • Thanks! I'm about to switch to zsh. I've been hearing so much good stuff about it.
    – trusktr
    Apr 13, 2013 at 5:33
18

You can background a task by adding a & after it.

For instance tail -f /var/log/messages & will background the task immediately.

As always you can see what tasks you backgrounded with the jobs command.

This of course assumes you have not yet run the command.

4
  • That's useful, but not what I mean. If I have the app in the foreground, then want to send it to background later, I can press ctrl+z then execute bg at the command line to the app runs in the background. But between pressing ctrl+z and executing bg, there's a timeframe that the app is completely paused. I don't want that. How do I send it to background immediately?
    – trusktr
    Apr 9, 2013 at 0:49
  • @trusktr like Gilles said. You need to inform both the shell and the terminal. Sorry, I don't know of a way to do that.
    – prateek61
    Apr 12, 2013 at 1:14
  • It does not answer the question. Sep 29, 2016 at 12:00
  • It's interesting that you chose tail -f as an example, since A) that was exactly what I was trying to make work, and B) it doesn't work, at least not as expected. Since tail overwrites the screen buffer every second or so, even though it's run in the background, it still writes to screen once. My solution is to add sleep 1 or 2 after executing tail, then clear screen buffer, eg. tail -f file.log &; sleep 1; echo -n -e '\e[2J\e[3J\e[1;1H'; Disgusting, but effective! May 13, 2021 at 17:35
5

Backgrounding a command is done by appending an ampersand to the command.

sleep 300 &

If it's already running your only option is to stop it then background it.

2
  • 1
    Between pressing ctrl+z and executing bg, there's a timeframe that the app is completely paused, which is what I don't want. So there's no way to send it to background immediately?
    – trusktr
    Apr 9, 2013 at 0:50
  • 1
    Nope. As Giles said, it takes both the shell and the terminal. You need to inform each.
    – bahamat
    Apr 9, 2013 at 19:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.