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-linuxpackage (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.