I follow this pattern of suspending the task and then letting it to continue too often with the Ctrl-Z bg sequence.

I was wondering is there any way to compress that to single keypress?

My shell is zsh


The Ctrl+Z sequence is handled by the terminal, not by the shell. (Useful background: What is the exact difference between a 'terminal', a 'shell', a 'tty' and a 'console'?)

Only a small, non-extensible set of functions can be bound to a key in a terminal. You can customize the keys bound to these functions but not add another function. These functions fall into three categories:

  • Command line edition in programs that don't provide their own (canonical mode, also called cooked mode (by opposition with raw mode), which you'll rarely use in practice): end of file (eof, Ctrl+D), end of line (eol, Ctrl+M), erase character left (erase, Ctrl+H), erase word left (werase, Ctrl+W), erase line (kill, Ctrl+U).
  • Manual flow control: stop (Ctrl+S), start (Ctrl+Q). Only useful on old serial terminals that dropped characters when the terminal couldn't keep up with the computer or vice versa.
  • Signalling: interrupt (intr, Ctrl+C), force quit (quit, Ctrl+\), suspend (Ctrl+Z).

Some systems, including Linux, extend that list, but I've never seen one that included backgrounding. Note that it would take support both in the terminal driver in the kernel, and in the terminal emulator. So you have to make do with suspend, which sends the foreground job a SIGTSTP signal. This triggers a SIGCHLD in the parent process of the foreground job's leader, which is usually the shell. When the shell received SIGCHLD, it calls waitpid to figure out why it was notified, and upon detection that a background job was suspended, it displays a notification (e.g. [1] + 12345 suspended mycommand) and a new prompt.

You could program the shell to send a SIGCONT signal to the foreground job. I don't think zsh has a hook for that, you'd need to patch the source code. And there's no way for zsh to know whether you really meant to interrupt the program (oops, this program may be doing the wrong thing, let me suspend it while I sort it out) or to background it.

What I do is to set the Ctrl+Z key sequence in zsh to background the current job (%%). That way, I can send the foreground job to the background by pressing Ctrl+Z Ctrl+Z. While I'm at it, I make Ctrl+Z do something else useful when the current input line is not empty (so I haven't just come back from a subprocess): “suspend” the current input line, allowing me to type another command, after which the interrupted line is pushed back into the input buffer.

fancy-ctrl-z () {
  if [[ $#BUFFER -eq 0 ]]; then
    zle redisplay
    zle push-input
zle -N fancy-ctrl-z
bindkey '^Z' fancy-ctrl-z
  • Gilles, this is an incredibly complete, educating and thoughtful answer I couldn't expect to get! Thank you so much! – Evgeniy Dolzhenko Jan 16 '12 at 15:28

So found the solution, not exactly what I want but darn close from here https://superuser.com/a/161922/35223

On an empty command line runs bg (so that Ctrl+Z Ctrl+Z suspends a program and immediately resumes it in the background).

  • I will note that this requires zsh; it is not supported in bash. (out of the box, anyway) – Kevin M Jan 13 '12 at 16:55
  • @KevinM You can write an analogous function in bash (at least the basic version making Ctrl+Z call bg, I'm not sure about detecting a non-empty input line). – Gilles Jan 13 '12 at 19:22

^z ^z like zsh above is possible in bash, though it's a bit kludgy and I haven't run this for long:

  • In your .inputrc include the mapping "\C-z": "bg\n"
  • In the PS0 bash variable include `$(stty susp ^z)'
  • In the PROMPT_COMMAND bash variable include 'stty susp ^@'

so ^z for suspend is turned on when a command is run, then turned off for the bash prompt.


Are these commands that you wanted to run in the foreground initially, and then switch to the background? I don't know if there's a simpler way to do that. But if you'd like to run commands that will be in the background to begin with, you can just add an ampersand to the end of the line. e.g., ping google.com & will start pinging in the background; you won't be able to interact with it unless you type fg.

  • 1
    Thanks, the problem is that sometimes you don't have an idea of how much time running the command would take, so you run interactively and then realize you better let it continue on background. The accepted answer works wonders for me, using it daily! – Evgeniy Dolzhenko Feb 29 '12 at 11:34
  • Thanks for the response. The accepted answer is pretty neat! – octern Mar 1 '12 at 19:23

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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