Making zsh jobs -p behave as in bash
Clash Royale CLAN TAG#URR8PPP
Is there a way to make jobs -p
in zsh behave as in bash, ie. give
only a number, such that one can do kill $(jobs -p)
?
zsh jobs
add a comment |
Is there a way to make jobs -p
in zsh behave as in bash, ie. give
only a number, such that one can do kill $(jobs -p)
?
zsh jobs
jobs -p
gives pgids, not pids. If you want pids, look at the$jobstates
special associative array.
– Stéphane Chazelas
Jan 8 at 23:28
@StéphaneChazelas, see edit.
– Toothrot
Jan 8 at 23:45
add a comment |
Is there a way to make jobs -p
in zsh behave as in bash, ie. give
only a number, such that one can do kill $(jobs -p)
?
zsh jobs
Is there a way to make jobs -p
in zsh behave as in bash, ie. give
only a number, such that one can do kill $(jobs -p)
?
zsh jobs
zsh jobs
edited Jan 8 at 23:45
Toothrot
asked Jan 8 at 23:12
ToothrotToothrot
828521
828521
jobs -p
gives pgids, not pids. If you want pids, look at the$jobstates
special associative array.
– Stéphane Chazelas
Jan 8 at 23:28
@StéphaneChazelas, see edit.
– Toothrot
Jan 8 at 23:45
add a comment |
jobs -p
gives pgids, not pids. If you want pids, look at the$jobstates
special associative array.
– Stéphane Chazelas
Jan 8 at 23:28
@StéphaneChazelas, see edit.
– Toothrot
Jan 8 at 23:45
jobs -p
gives pgids, not pids. If you want pids, look at the $jobstates
special associative array.– Stéphane Chazelas
Jan 8 at 23:28
jobs -p
gives pgids, not pids. If you want pids, look at the $jobstates
special associative array.– Stéphane Chazelas
Jan 8 at 23:28
@StéphaneChazelas, see edit.
– Toothrot
Jan 8 at 23:45
@StéphaneChazelas, see edit.
– Toothrot
Jan 8 at 23:45
add a comment |
1 Answer
1
active
oldest
votes
jobs
reports about jobs, which can have more than one process.
When interactive, jobs are places in process groups, so they can be suspended/resumed/interrupted as a whole.
jobs -p
(in both zsh
and bash
) return the process group id of each job, not the process ids of all the processes in the job.
When the shell doesn't run interactively (where there's no job control), the shell reports the pid of the process that would have been the process group leader if there had been job control (which may not be the same as the one returned in $!
by the way).
$ sleep 1 | sleep 20 &
[1] 29643 29644
$ jobs -p
[1] + 29643 done sleep 1 |
running sleep 20
zsh reports that for job 2 of pgid 29643, zsh started 2 processes, one of which is already done, the other still running.
If you want to get the pgids only like in bash
, you can pipe that do:
awk '/^[/print $3'
If you want to get the pids in the job (only the ones started by the shell), you can look at the $jobstates
special associative array:
$ typeset jobstates
jobstates=( 1 'running:+:29643=done:29644=running' )
To extract the pids of the processes still running in job 1:
$ echo $$(M)$(s/:/)jobstates[1]:#*=running%=*
29644
Now if you want to kill those jobs, you'd want to kill the process groups (in interactive shells), i.e. the whole jobs, not one process at random in the job.
You can kill the process group of id 29643 with kill -- -29643
, kill 29643
would only kill the process of id 29643 (which is already dead in our example above).
Here, it would make more sense to pass job numbers instead of pid or pgid (which wouldn't work in non-interactive shells) to kill. That's what the job numbers are for:
kill %$(k)^jobstates
Unfortunately, I don't think bash
has a reliable equivalent.
bash-4.4$ sleep $(: '
> [213] ...') 2134 &
[1] 29856
bash-4.4$ jobs
[1]+ Running sleep $(: '
[213] ...') 2134 &
It's difficult to extract the job numbers reliably from that. (I also find that even while kill %; do continue; done
doesn't work because of what looks like some race condition bug).
Note that when not running interactively, there's no job control, so when you do kill %1
to kill the job number 1, that job doesn't have a process group. So as a poor man's approximation, the shell (both bash
and zsh
) will kill each process it knows about individually instead. In our example above, instead of:
kill(-29643, SIGTERM);
it will do:
kill(29643, SIGTERM);
kill(29644, SIGTERM);
It will not kill the other processes (if any) that those 2 processes have spawned themselves, though it's still better than killing only 29643 like in your kill $(jobs -p)
approach.
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f493350%2fmaking-zsh-jobs-p-behave-as-in-bash%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
jobs
reports about jobs, which can have more than one process.
When interactive, jobs are places in process groups, so they can be suspended/resumed/interrupted as a whole.
jobs -p
(in both zsh
and bash
) return the process group id of each job, not the process ids of all the processes in the job.
When the shell doesn't run interactively (where there's no job control), the shell reports the pid of the process that would have been the process group leader if there had been job control (which may not be the same as the one returned in $!
by the way).
$ sleep 1 | sleep 20 &
[1] 29643 29644
$ jobs -p
[1] + 29643 done sleep 1 |
running sleep 20
zsh reports that for job 2 of pgid 29643, zsh started 2 processes, one of which is already done, the other still running.
If you want to get the pgids only like in bash
, you can pipe that do:
awk '/^[/print $3'
If you want to get the pids in the job (only the ones started by the shell), you can look at the $jobstates
special associative array:
$ typeset jobstates
jobstates=( 1 'running:+:29643=done:29644=running' )
To extract the pids of the processes still running in job 1:
$ echo $$(M)$(s/:/)jobstates[1]:#*=running%=*
29644
Now if you want to kill those jobs, you'd want to kill the process groups (in interactive shells), i.e. the whole jobs, not one process at random in the job.
You can kill the process group of id 29643 with kill -- -29643
, kill 29643
would only kill the process of id 29643 (which is already dead in our example above).
Here, it would make more sense to pass job numbers instead of pid or pgid (which wouldn't work in non-interactive shells) to kill. That's what the job numbers are for:
kill %$(k)^jobstates
Unfortunately, I don't think bash
has a reliable equivalent.
bash-4.4$ sleep $(: '
> [213] ...') 2134 &
[1] 29856
bash-4.4$ jobs
[1]+ Running sleep $(: '
[213] ...') 2134 &
It's difficult to extract the job numbers reliably from that. (I also find that even while kill %; do continue; done
doesn't work because of what looks like some race condition bug).
Note that when not running interactively, there's no job control, so when you do kill %1
to kill the job number 1, that job doesn't have a process group. So as a poor man's approximation, the shell (both bash
and zsh
) will kill each process it knows about individually instead. In our example above, instead of:
kill(-29643, SIGTERM);
it will do:
kill(29643, SIGTERM);
kill(29644, SIGTERM);
It will not kill the other processes (if any) that those 2 processes have spawned themselves, though it's still better than killing only 29643 like in your kill $(jobs -p)
approach.
add a comment |
jobs
reports about jobs, which can have more than one process.
When interactive, jobs are places in process groups, so they can be suspended/resumed/interrupted as a whole.
jobs -p
(in both zsh
and bash
) return the process group id of each job, not the process ids of all the processes in the job.
When the shell doesn't run interactively (where there's no job control), the shell reports the pid of the process that would have been the process group leader if there had been job control (which may not be the same as the one returned in $!
by the way).
$ sleep 1 | sleep 20 &
[1] 29643 29644
$ jobs -p
[1] + 29643 done sleep 1 |
running sleep 20
zsh reports that for job 2 of pgid 29643, zsh started 2 processes, one of which is already done, the other still running.
If you want to get the pgids only like in bash
, you can pipe that do:
awk '/^[/print $3'
If you want to get the pids in the job (only the ones started by the shell), you can look at the $jobstates
special associative array:
$ typeset jobstates
jobstates=( 1 'running:+:29643=done:29644=running' )
To extract the pids of the processes still running in job 1:
$ echo $$(M)$(s/:/)jobstates[1]:#*=running%=*
29644
Now if you want to kill those jobs, you'd want to kill the process groups (in interactive shells), i.e. the whole jobs, not one process at random in the job.
You can kill the process group of id 29643 with kill -- -29643
, kill 29643
would only kill the process of id 29643 (which is already dead in our example above).
Here, it would make more sense to pass job numbers instead of pid or pgid (which wouldn't work in non-interactive shells) to kill. That's what the job numbers are for:
kill %$(k)^jobstates
Unfortunately, I don't think bash
has a reliable equivalent.
bash-4.4$ sleep $(: '
> [213] ...') 2134 &
[1] 29856
bash-4.4$ jobs
[1]+ Running sleep $(: '
[213] ...') 2134 &
It's difficult to extract the job numbers reliably from that. (I also find that even while kill %; do continue; done
doesn't work because of what looks like some race condition bug).
Note that when not running interactively, there's no job control, so when you do kill %1
to kill the job number 1, that job doesn't have a process group. So as a poor man's approximation, the shell (both bash
and zsh
) will kill each process it knows about individually instead. In our example above, instead of:
kill(-29643, SIGTERM);
it will do:
kill(29643, SIGTERM);
kill(29644, SIGTERM);
It will not kill the other processes (if any) that those 2 processes have spawned themselves, though it's still better than killing only 29643 like in your kill $(jobs -p)
approach.
add a comment |
jobs
reports about jobs, which can have more than one process.
When interactive, jobs are places in process groups, so they can be suspended/resumed/interrupted as a whole.
jobs -p
(in both zsh
and bash
) return the process group id of each job, not the process ids of all the processes in the job.
When the shell doesn't run interactively (where there's no job control), the shell reports the pid of the process that would have been the process group leader if there had been job control (which may not be the same as the one returned in $!
by the way).
$ sleep 1 | sleep 20 &
[1] 29643 29644
$ jobs -p
[1] + 29643 done sleep 1 |
running sleep 20
zsh reports that for job 2 of pgid 29643, zsh started 2 processes, one of which is already done, the other still running.
If you want to get the pgids only like in bash
, you can pipe that do:
awk '/^[/print $3'
If you want to get the pids in the job (only the ones started by the shell), you can look at the $jobstates
special associative array:
$ typeset jobstates
jobstates=( 1 'running:+:29643=done:29644=running' )
To extract the pids of the processes still running in job 1:
$ echo $$(M)$(s/:/)jobstates[1]:#*=running%=*
29644
Now if you want to kill those jobs, you'd want to kill the process groups (in interactive shells), i.e. the whole jobs, not one process at random in the job.
You can kill the process group of id 29643 with kill -- -29643
, kill 29643
would only kill the process of id 29643 (which is already dead in our example above).
Here, it would make more sense to pass job numbers instead of pid or pgid (which wouldn't work in non-interactive shells) to kill. That's what the job numbers are for:
kill %$(k)^jobstates
Unfortunately, I don't think bash
has a reliable equivalent.
bash-4.4$ sleep $(: '
> [213] ...') 2134 &
[1] 29856
bash-4.4$ jobs
[1]+ Running sleep $(: '
[213] ...') 2134 &
It's difficult to extract the job numbers reliably from that. (I also find that even while kill %; do continue; done
doesn't work because of what looks like some race condition bug).
Note that when not running interactively, there's no job control, so when you do kill %1
to kill the job number 1, that job doesn't have a process group. So as a poor man's approximation, the shell (both bash
and zsh
) will kill each process it knows about individually instead. In our example above, instead of:
kill(-29643, SIGTERM);
it will do:
kill(29643, SIGTERM);
kill(29644, SIGTERM);
It will not kill the other processes (if any) that those 2 processes have spawned themselves, though it's still better than killing only 29643 like in your kill $(jobs -p)
approach.
jobs
reports about jobs, which can have more than one process.
When interactive, jobs are places in process groups, so they can be suspended/resumed/interrupted as a whole.
jobs -p
(in both zsh
and bash
) return the process group id of each job, not the process ids of all the processes in the job.
When the shell doesn't run interactively (where there's no job control), the shell reports the pid of the process that would have been the process group leader if there had been job control (which may not be the same as the one returned in $!
by the way).
$ sleep 1 | sleep 20 &
[1] 29643 29644
$ jobs -p
[1] + 29643 done sleep 1 |
running sleep 20
zsh reports that for job 2 of pgid 29643, zsh started 2 processes, one of which is already done, the other still running.
If you want to get the pgids only like in bash
, you can pipe that do:
awk '/^[/print $3'
If you want to get the pids in the job (only the ones started by the shell), you can look at the $jobstates
special associative array:
$ typeset jobstates
jobstates=( 1 'running:+:29643=done:29644=running' )
To extract the pids of the processes still running in job 1:
$ echo $$(M)$(s/:/)jobstates[1]:#*=running%=*
29644
Now if you want to kill those jobs, you'd want to kill the process groups (in interactive shells), i.e. the whole jobs, not one process at random in the job.
You can kill the process group of id 29643 with kill -- -29643
, kill 29643
would only kill the process of id 29643 (which is already dead in our example above).
Here, it would make more sense to pass job numbers instead of pid or pgid (which wouldn't work in non-interactive shells) to kill. That's what the job numbers are for:
kill %$(k)^jobstates
Unfortunately, I don't think bash
has a reliable equivalent.
bash-4.4$ sleep $(: '
> [213] ...') 2134 &
[1] 29856
bash-4.4$ jobs
[1]+ Running sleep $(: '
[213] ...') 2134 &
It's difficult to extract the job numbers reliably from that. (I also find that even while kill %; do continue; done
doesn't work because of what looks like some race condition bug).
Note that when not running interactively, there's no job control, so when you do kill %1
to kill the job number 1, that job doesn't have a process group. So as a poor man's approximation, the shell (both bash
and zsh
) will kill each process it knows about individually instead. In our example above, instead of:
kill(-29643, SIGTERM);
it will do:
kill(29643, SIGTERM);
kill(29644, SIGTERM);
It will not kill the other processes (if any) that those 2 processes have spawned themselves, though it's still better than killing only 29643 like in your kill $(jobs -p)
approach.
edited Jan 9 at 0:23
answered Jan 8 at 23:46
Stéphane ChazelasStéphane Chazelas
302k55566919
302k55566919
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f493350%2fmaking-zsh-jobs-p-behave-as-in-bash%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
jobs -p
gives pgids, not pids. If you want pids, look at the$jobstates
special associative array.– Stéphane Chazelas
Jan 8 at 23:28
@StéphaneChazelas, see edit.
– Toothrot
Jan 8 at 23:45