2012-10-31 14 views

Antwort

9
alias killbg='kill ${${(v)jobstates##*:*:}%=*}' 

. Es ist zsh, keine Notwendigkeit in externen Tools.

Wenn Sie Auftragsnummer N töten wollen:

function killjob() 
{ 
    emulate -L zsh 
    for jobnum in [email protected] ; do 
     kill ${${jobstates[$jobnum]##*:*:}%=*} 
    done 
} 
killjob N 
+0

Als ein 'zsh' noob, Verstand, der diese erste Linie erklärt? –

+1

@ZachRiggle Es ist in 'man zshexpn' und' man zshmodules': '$ jobstates' ist ein assoziativer Array-Parameter,' (v) 'wählt nur Werte aus diesem Array aus,' # 'bewirkt, dass zsh gegebenes Muster vom Start entfernt von string, wählt am wenigsten langes Muster zum Entfernen aus, '*: *:': Muster, das zsh die ersten zwei doppelpunktgetrennten Felder jedes Wertes entfernt ('#' auf Array-Parameter wird auf jeden Wert angewendet), '%' ist wie '#', aber für das Ende von Strings und '= *' macht zsh alles nach dem letzten eq-Zeichen einschließlich des Zeichens selbst entfernen.Jeder '$ jobstates' Wert sieht wie folgt aus: 'job-state: mark: pid = state ...'. – ZyX

+0

Es scheint, ich habe hier einen Fehler: Es funktioniert nicht, wenn das ganze Rohr suspendiert war. – ZyX

0
alias killbg='for job in \`jobs -l | egrep -o "([0-9][0-9]+)"`; 
+0

Super! Versuchen Sie nun, 'echo 123 | weniger und überprüfe, was es töten wird. Hinweis: Wenn Sie 'kill'' echo 123' ausführen, ist der Prozess bereits tot und die PID wurde möglicherweise schon vergeben. Also mit einer solchen suspendierten Pipe mit Ihrem 'killbg' können Sie 2 unschuldige Prozesse beenden: Prozess' 123' ('echo' Argument) und Prozess, der passierte, um' echo' PID zu wiederholen. – ZyX

+0

Meine Lösung wird in diesem Fall jedoch fehlschlagen (es wird versuchen, '{echoPID} = done: {lessPID}') zu töten. – ZyX

0

Diese beiden Werke für ZSH und 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 `[email protected]` 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 [email protected] $(sed --regexp-extended --quiet 's/\[([[:digit:]]+)\].*/%\1/gp' <<< "$kill_list" | tr '\n' ' ') 
    else 
     return 0 
    fi 

} 

@zyx Antwort nicht für mich arbeiten.

Mehr zu ihm hier: https://gist.github.com/CMCDragonkai/6084a504b6a7fee270670fc8f5887eb4

0

Minor Anpassung an @ Zxy Antwort ...

Auf meinem System, fand ich, dass suspendierten Aufträge nicht ordnungsgemäß mit dem Standard-Kill-Signal getötet wurden. Ich musste es tatsächlich zu kill -KILL ändern, um suspended Hintergrundjobs zu erhalten, um richtig zu sterben.

alias killbg='kill -KILL ${${(v)jobstates##*:*:}%=*}' 

Achten Sie besonders auf die EINZIGEN QUOTEN um diese. Wenn Sie zu doppelten Anführungszeichen wechseln würden, müssten Sie jedes "$" umgehen. Beachten Sie, dass Sie function NICHT verwenden können, um diesen Befehl zu umbrechen, da die Funktion das Array $jobstates inkrementiert, wodurch die Funktion versucht, sich selbst zu töten ... Muss einen Alias ​​verwenden.

Das killjob Skript oben ist ein bisschen überflüssig, da Sie gerade tun:

kill %1 

weniger Tastenanschläge und es baut bereits in zsh.

0

es ist builtin kill %1 für auf

als kill ist ein binäres von util-linux Paket befindet sich in /usr/bin/kill

, die keine Arbeitsplätze unterstützt (kill: cannot find procses "%1")

Verwendung Stichwort builtin Namenskonflikt

zu vermeiden