How to suspend and bring a background process to foreground
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?
Type fg
to bring it to the foreground.
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:
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
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
(usebg %2
with the job number, which you can check withjobs
)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 fg
Enter 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.
- list jobs with
jobs
command - Bring your target job to the foreground with
fg
; e.g.:fg %4
- Hit
CTRL Z
to suspend - To start it running in the background, use bg; e.g.:
bg %4