Warum schlägt mein Skript mit dem Namen "killl" fehl, aber nach dem Umbenennen funktioniert es einwandfrei?

12

Das betreffende Skript beendet den neuesten Prozess auf meinem Localhost-Port 8080.

#!/bin/bash
x=$(lsof -i:8080 | tail -1 | awk '{print $2}')
kill -9 $x

Es hat nicht funktioniert, wenn das Skript den Namen 'killl' hat (bekommen? Kill Latest?). Es gab mir eine Aufforderung, cmdsubst> das Skript in 'asdf' umzubenennen, alles funktioniert. Gibt es eine Erklärung für dieses Verhalten? Ich benutze MacOS El Capitán.

Zeick
quelle
5
Haben Sie eine andere Funktion, einen Alias, ein Dienstprogramm oder einen anderen Befehl killl?
Kusalananda
9
Machen Sie die Namen nicht mehrdeutig. killlkann als falsch geschrieben interpretiert werden kill. Es ist besser, explizit und beschreibend zu sein: kill_latestoder kill_last.
Cezar
6
Was ist die Ausgabe von type killlin der Shell, wo Sie versucht haben, es zu starten?
Hauke ​​Laging

Antworten:

27

cmdsubst>ist die sekundäre Eingabeaufforderung, die von der zshShell ausgegeben wird, wenn sie auf das Ende einer eingegebenen Befehlsersetzung wartet.

Wenn Sie diese Eingabeaufforderung erst nach der Eingabe erhalten killl<Return>, ist die einzige vernünftige Erklärung, dass Sie einen Alias ​​(eine Art Zeichenfolgenmakroerweiterung) haben killl, der sich zu etwas erweitert, das eine nicht abgeschlossene $(...)Befehlsersetzung enthält , wie:

$ alias 'killl=echo $(lsof -ti'
$ killl :22
cmdsubst>

Wo werden zshSie aufgefordert, diese $(...)Befehlsersetzung zu schließen ?

Noch ein paar Anmerkungen:

  • Die Ausgabe von lsofwird nach pid sortiert. PID-Nummern werden umgebrochen, eine größere PID ist keine Garantie dafür, dass der Prozess später gestartet wurde.
  • -i:8080 meldet TCP- oder UDP-Sockets, die den 8080-Port als Quell- oder Zielport haben, unabhängig davon, ob es sich um einen empfangsbereiten, akzeptierenden oder verbindenden Socket handelt.
  • Wenn Sie nur die PID erhalten möchten, können Sie die folgenden -tOptionen verwenden lsof:lsof -ti:8080 | tail -n2
  • kill -9ist kill -s KILL, was ein Signal sendet, dass die Anwendung nicht ordnungsgemäß beenden kann. Es sollte nur als letztes Mittel verwendet werden.

Um den zuletzt gestarteten Prozess abzubrechen, der eine Socket-Bindung (eines der Enden) an Port 8080 aufweist, können Sie Folgendes ausführen:

#! /bin/sh -
unset IFS
pids=$(lsof -ti:8080) &&
  LC_ALL=C ps -o pid=,lstart= -p $pids |
  LC_ALL=C sort -k6,6n -k4,4M -k3,3n -k5,5 -k1,1n |
  awk 'END{system("kill " $1)}'

(setzt GNU sort(wie unter macOS) und eine psImplementierung voraus , die die lstartSpalte unterstützt (wie bei macOS und procps-ng, obwohl der Code für procps-ng, bei dem die Felder month und day ausgetauscht werden, aktualisiert werden müsste)).

Stéphane Chazelas
quelle
1

Es gab mir eine Aufforderung zu cmdsubst>

Denn als Sie den Befehl eingegeben haben, haben Sie ihn nicht eingegeben

killl
du hast getippt

killl $ (
o.ä. Dies hatte nichts mit dem Namen des Skripts zu tun , oder auch nur damit, dass es sich überhaupt um ein Skript handelte. Sie hätten den gleichen Effekt mit einem völlig nicht existierenden Befehl erzielen können:

Zeick $ (
Der Parser der Shell erwartete, dass mehr Eingaben den nur teilweise vollständigen Befehl vervollständigen würden. Ihr Denken an den Skriptnamen ist ein kompletter roter Hering.

JdeBP
quelle
6
Das ist eine ziemlich große Annahme, die besagt, dass er killl $(aus irgendeinem Grund getippt hat , und es ist sehr unwahrscheinlich, dass er das getan hat. Die Antwort von Stéphane Chazelas ist wahrscheinlicher.
Herohtar
1
Wenn es sich tatsächlich um einen Tippfehler handelt, dann `ist das wahrscheinlicher als $(.
Emil Jeřábek unterstützt Monica
2
Nein, Emil Jeřábek; `ist überhaupt nicht wahrscheinlich, da es nicht die gleiche Eingabeaufforderung gibt . Versuch es. Nein, Herhtar; es ist nicht eine Annahme bei der Eingabe , dass oder ähnlich ist die Art und Weise , dass die Eingabeaufforderung zu erhalten . Es ist ein Abzug.
JdeBP
1
Sie behaupten, dass OP "nicht getippt" hat killl, als, wie Stéphane Chazelas erklärt, es durchaus möglich ist, dass OP tatsächlich getippt hat killl. Daher habe ich Ihre Antwort als falsch eingestuft.
Kevin