These two processes:
cat /dev/tty > /dev/null &
cat /dev/zero > /dev/null &
have to run in the background but i am having trouble bringing the second job to the foreground.
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityWhile $!
contains the process ID of the top-most process of the most recently started job in background, it's surprisingly hard to get its job ID in a fool-proof way.
It's not necessarily the greatest job id as job ids are reused. It's not necessarily the job you may refer to by %%
or %+
(or that fg
without argument would act upon) as suspended jobs take precedence (like in your case where the first job is likely to be suspended as it will try to read from the tty while not in foreground) or the most recently started job may have died already (in which case %+
would refer to the next job in the list).
So you'd need to run jobs
first to know what the job number is for the job you want to fg
(use use fg %thatnumber
), or if there's no other job with zero
in their name, run:
fg %\?zero
With zsh
, you could use:
fg_most_recent() {
local job=${(k)jobstates[(R)*:$!=*]}
((job)) && fg %$job
}
That is, get the k
ey of the $jobstates
associative array whose value matches the *:$!=*
pattern ($jobstates
look like running:+:20162=running:20163=running
giving the status of all the processes in the job that zsh
has started directly).
If this was two ordinary jobs, then a a plain fg
would bring the second job into the foreground if that was the most recently suspended background job, or the most recently started background jobs (with no other jobs being suspended).
However, by the nature of the first job (reading from /dev/tty
), it will get stopped as soon as it tries to read from the TTY. fg
will thus put it back in the foreground.
The solution here is to either use %-
or %2
, given that there are no other jobs.
When a job is put into the background, either by starting the job with a trailing &
, or by suspending a foreground job with Ctrl+Z and then giving the command bg
, the job is given a "job ID" or "job spec". This job ID is usually denoted by %N
where N
is some decimal number.
You may use the job ID with several commands, such as wait
, kill
, fg
and bg
. The kill
command, for example, may be used to send a signal to a background job using its job ID.
The fg
command, by default, works on "the current job". The job ID of the current job is available as %+
or %%
. The current job is the most recently started background job, or, if there are jobs suspended, the most recently suspended job.
To move an arbitrary background job into the foreground, use its job ID:
$ sleep 1000 &
[1] 37327
$ sleep 500 &
[2] 83532
$ jobs
[1]- Running sleep 1000 &
[2]+ Running sleep 500 &
$ fg %1
sleep 1000
The +
in the output of jobs
denotes the "current job" (which is what would be switched to with a plain invocation of fg
).
POSIX standard special job IDs:
%%
, the current job.%+
, same as above.%-
, the previous job.%N
, job number N
.%string
, the job whose command starts with string
.%?string
, the job whose command contains string
.cat /dev/tty > /dev/null &
, it will likely be suspended (by a SIGTTIN), so fg
will resume that one instead of the second one.
– Stéphane Chazelas
Sep 21 '17 at 10:31