How to kill all background processes in zsh?
This works for both ZSH and Bash:
: '
killjobs - Run kill on all jobs in a Bash or ZSH shell, allowing one to optionally pass in kill parameters
Usage: killjobs [zsh-kill-options | bash-kill-options]
With no options, it sends `SIGTERM` to all jobs.
'
killjobs () {
local kill_list="$(jobs)"
if [ -n "$kill_list" ]; then
# this runs the shell builtin kill, not unix kill, otherwise jobspecs cannot be killed
# the `$@` list must not be quoted to allow one to pass any number parameters into the kill
# the kill list must not be quoted to allow the shell builtin kill to recognise them as jobspec parameters
kill $@ $(sed --regexp-extended --quiet 's/\[([[:digit:]]+)\].*/%\1/gp' <<< "$kill_list" | tr '\n' ' ')
else
return 0
fi
}
@zyx answer didn't work for me.
More on it here: https://gist.github.com/CMCDragonkai/6084a504b6a7fee270670fc8f5887eb4
one should use the builtin
zsh built-in command alongside with the other kill
zsh built-in command as:
builtin kill %1
as kill
is also a separate binary file from util-linux
package (upstream, mirror) located in /usr/bin/kill
which does not support jobs (kill: cannot find process "%1"
).
use keyword builtin
to avoid name conflict or enable
the kill
built-in if it is disabled.
there is a concept of disabling and enabling built-in commands (ie. shell's own commands such as cd
and kill
) in shells, and in zsh you can enable (a disabled) kill
builtin as:
enable kill
issue disable
to check if the builtin is disabled (and enable
to see the enabled ones).
alias killbg='kill ${${(v)jobstates##*:*:}%=*}'
. It is zsh, no need in external tools.
If you want to kill job number N:
function killjob()
{
emulate -L zsh
for jobnum in $@ ; do
kill ${${jobstates[$jobnum]##*:*:}%=*}
done
}
killjob N
Minor adjustment to @Zxy's response...
On my system, I found that suspended jobs weren't killed properly with the default kill signal. I had to actually change it to kill -KILL
to get suspended
background jobs to die properly.
alias killbg='kill -KILL ${${(v)jobstates##*:*:}%=*}'
Pay special attention to the SINGLE QUOTES around this. If you switched to double quotes, you would need to escape the each "$". Note that you can NOT use a function
to wrap this command since the function will increment the $jobstates
array causing the function to try killing itself... Must use an alias.
The killjob
script above is a bit redundant since you can just do:
kill %1
Less keystrokes and it's already build into zsh
.