276

I have a process originally running in the foreground. I suspended by Ctrl+Z, and then resume its running in the background by bg <jobid>.

I wonder how to suspend a process running in the background?

How can I bring a background process to foreground?

Edit:

The process outputs to stderr, so how shall I issue the command fg <jobid> while the process is outputting to the terminal?

bahamat
  • 39,666
  • 4
  • 75
  • 104
Tim
  • 101,790
  • 2
    You can still type commands in a terminal that is spewing errors. The text spewed on STDERR doesn't count as input, only the keys you send. It looks confusing on screen but it works. – Caleb Aug 08 '12 at 19:42
  • @Caleb: Even when the process outputs to stdout, I can still type fg <jobid> to make it foreground? – Tim Aug 08 '12 at 19:59
  • @Tim: Yes, you can. – Caleb Aug 08 '12 at 21:22
  • Thanks! I mean, wasted less time, instead of reading the docs. – micrub May 28 '21 at 09:19

5 Answers5

339

As Tim said, type fg to bring the last process back to foreground.

If you have more than one process running in the background, do this:

$ jobs
[1]   Stopped                 vim
[2]-  Stopped                 bash
[3]+  Stopped                 vim 23

fg %3 to bring the vim 23 process back to foreground.

To suspend the process running in the background, use:

kill -STOP %job_id

The SIGSTOP signal stops (pauses) a process in essentially the same way Ctrl+Z does.

example: kill -STOP %3.

sources:

Manuel Jordan
  • 1,728
  • 2
  • 16
  • 40
fromnaboo
  • 6,932
  • 29
    signal 19 is SIGCONT for me; I use kill -STOP and kill -CONT in preference to remembering the numbers anyway, but you can check kill -l to remind yourself of the numeric values – Useless Aug 08 '12 at 13:04
  • The process outputs to stderr, so how shall I issue the command job and fg <jobid> while the process is outputting to the terminal? – Tim Aug 08 '12 at 13:19
  • 1
    @Tim Just type the command as you normally would. As long as the job is backgrounded, it is not reading what you type - your shell is. What you type might look broken up to you, but the shell will understand it just fine. –  Aug 08 '12 at 14:30
  • @AlexWebr: Thanks, it works! (1) Does a background job not accept any input and output including "Ctrl+Z" etc, right? (2) Can a job running in the background be suspended directly? If yes, how? If no, must it be first changed to run in the foreground before it can be suspended? – Tim Aug 08 '12 at 15:02
  • 2
    Can a job running in the background be suspended directly yes: kill -STOP %job_id, as explained – Useless Aug 08 '12 at 16:38
  • after suspend a process you can use something like ps -eo pid,s | grep T | cut -d' ' -f1 | xargs kill -SIGCONT to resume all process – ton Dec 11 '15 at 13:43
  • it would be insanely useful to me if there was a shortcut to typing kill -STOP %1 such as st %1 as my typing error rate seems to increase exponentially when the terminal is spewing output and I can't see what I'm typing, so the likelihood I will correctly type kill -STOP %1 when I'm in a hurry to stop that output is a lot lower than something shorter. – Michael Dec 19 '17 at 21:10
  • @Mihael you can write a shell script, a text file, with the top line !/bin/bash if that is ypur shell, the second line kill -STOP $1 where $1 is the first parameter given to this script. Save it wirh file name 'st' in an executable folder like /usr/local/bin/. Then make it executable with command chmod a+x /usr/local/bin/st and now you can type st %1 from everywhere. – FrancescoMM Jul 18 '19 at 06:36
  • Why not use SIGTSTP instead? It is the signal used and sent through ctrl + z from the beginning – Manuel Jordan May 12 '22 at 23:23
  • About the first comment - for macos signal 19 is SIGCONT - for linux signal 19 is SIGSTOP - for each OS is mandatory execute kill -l to see the complete list with the correct codes – Manuel Jordan May 12 '22 at 23:35
56

This should be true of any shell with job control, which (for the most part) you can take for granted unless dealing with a truly ancient shell. It's in the POSIX standard, so even dash supports job control (when run interactively or with -m).

Interactive

  • Ctrl+z will suspend the currently foregrounded program
  • bg will background the most recently suspended program
    (use bg %2 with the job number, which you can check with jobs)
  • fg will foreground the most recently suspended program

In zsh, you can write a key binding to implicitly run fg from the prompt via another Ctrl+z:

_zsh_cli_fg() { fg; }
zle -N _zsh_cli_fg
bindkey '^Z' _zsh_cli_fg

There's probably also a clever way to implicitly run bg upon suspending, but it seems unwise; at least for me, the majority of my Ctrl+z usage is because Ctrl+c is failing to break out; I want to follow that with e.g. kill %1 rather than bg, and I certainly don't want to default to killing! (This logic also extends into why I no longer use this key binding: If I'm hammering on Ctrl+z to stop a process, the last thing I want it to do is resume!)

Non-interactive

If you're in a different shell instance (or a different user, sometimes including sudo commands), you likely won't be able to use job numbers.

You can still act on another process once you know its process ID (PID). You can get the PID with pgrep …, or ps aux |grep … (or from the same shell, jobs -l, or $!) and you can then run:

kill -STOP $PID  # suspend
kill -CONT $PID  # continue (resume)

If you do not know the process ID and aren't worried about suspending other instances of the process by name, you can pass signals to one of these:

killall -STOP program_name
pkill -STOP program_name
pkill -f -STOP program_name_or_args

A CONT signal to a program stopped with Ctrl+z (and not bg'd) will resume its progress (in the foreground), the same as if you were to fg it.

Re: Standard Error

The edit to this question asks about standard error:

The process outputs to stderr, so how shall I issue the command fg <jobid> while the process is outputting to the terminal?

Unless the job in question has components that are backgrounded (or the whole job is backgrounded, perhaps via kill -CONT), you shouldn't actually see output while it is suspended.

If it is still outputting data (be it to standard output or standard error), it will certainly make your terminal visually cluttered, but all of that output will be ignored as it is not part of your input. This might make it harder to know you haven't entered any typos, but (blindly) typing fgEnter should suffice (unless you have multiple jobs and the one in question isn't the most recent, in which case you will indeed need the job descriptor).

If you do need to find the job descriptor, use another terminal to send it the STOP signal via the non-interactive methods above. This should free up your display (perhaps hit Enter a few times or run clear or Ctrl+L) so you can then run jobs to find the job descriptor and then run fg %N where N is that number.

Adam Katz
  • 3,965
  • The only problem with pausing and resuming processes is that if you made any connections to some other program (like RabbitMQ for instance), the connection would be lost when you resume. – Nav Feb 06 '17 at 23:31
  • @Nav – That's because you didn't run it headless. In bash and zsh, I believe you merely need to disown a backgrounded process. I prefer to run such tasks with nohup or a terminal multiplexer like screen or tmux.
 
 
You can't pick up a nohup process (just as you can't resume a backgrounded process from a separate connection), but you can connect to a multiplexer. – Adam Katz Feb 07 '17 at 00:37
  • It was a background process. I had closed the terminal and then logged in to the server from another terminal. – Nav Feb 07 '17 at 06:09
  • Yeah, you can't resume a process from another shell unless it was launched with that in mind. I recommend screen or tmux for that. – Adam Katz Feb 07 '17 at 18:45
  • I believe that if you send a CONT signal to a process (job/pipeline) stopped with Ctrl+Z, it will resume in the background, even if you haven't bg'd it. – G-Man Says 'Reinstate Monica' May 10 '17 at 22:18
  • Why not use SIGTSTP instead? It is the signal used and sent through ctrl + z from the beginning – Manuel Jordan May 12 '22 at 23:40
  • 1
    @ManuelJordan – You're supposed to use SIGSTOP programmatically and SIGSTP interactively. SIGSTOP cannot be ignored while SIGSTP can. See this answer. – Adam Katz May 13 '22 at 00:48
  • 1
    Very nice. I had set up barrier on two new machines and was sharing a keyboard and mouse. I suspended the barrier client program with ctrl+z from the other machine, and immediately lost control of the machine. Oops. Thankfully a quick google got me here. ssh, ps, and kill -CONT worked the magic! – poleguy May 15 '23 at 19:34
15

Type fg to bring it to the foreground.

Tim
  • 6,141
  • Thanks! The process outputs to stderr, so how shall I issue the command fg <jobid> while the process is outputting to the terminal? – Tim Aug 08 '12 at 13:16
4
  1. list jobs with jobs command
  2. Bring your target job to the foreground with fg; e.g.: fg %4
  3. Hit CTRL Z to suspend
  4. To start it running in the background, use bg; e.g.: bg %4
kmiklas
  • 161
0

Ending a process can be done in several different ways. Often, from a console-based command, sending a Ctrlc keystroke (the default interrupt character) will exit the command. This works when process is running in foreground mode.

If a process is running in background mode then first you would need to get its Job ID using the ps command and after that you can use kill command to kill the process as follows:

$ps -f
UID      PID  PPID C STIME    TTY   TIME CMD
amrood   6738 3662 0 10:23:03 pts/6 0:00 first_one
amrood   6739 3662 0 10:22:54 pts/6 0:00 second_one
amrood   3662 3657 0 08:10:53 pts/6 0:00 -ksh
amrood   6892 3662 4 10:51:50 pts/6 0:00 ps -f
$kill 6738
Terminated

Here the kill command would terminate the first_one process. If a process ignores a regular kill command, you can use kill -9 followed by the process ID as follows:

$kill -9 6738
Terminated
jasonwryan
  • 73,126