Pourquoi mon script nommé "killl" échoue, mais après avoir renommé fonctionne parfaitement?

12

Le script en question termine le dernier processus sur mon port localhost 8080.

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

Cela n'a pas fonctionné, si le script s'appelait 'killl' (l'obtenir? Kill Latest?). Cela m'a donné une invite pour cmdsubst> renommer le script en 'asdf', tout fonctionne. Y a-t-il une explication à ce comportement? J'utilise MacOS El Capitán.

Zeick
la source
5
Avez-vous une autre fonction, alias, utilitaire ou autre commande appelée killl?
Kusalananda
9
Ne rendez pas les noms ambigus. killlpeut être mal interprété comme mal orthographié kill. Il vaut mieux être explicite et plus descriptif: kill_latestou kill_last.
cezar
6
Quelle est la sortie de type killldans le shell où vous avez essayé de le démarrer?
Hauke ​​Laging du

Réponses:

27

cmdsubst>est l'invite secondaire imprimée par le zshshell lorsqu'il attend la fin d'une substitution de commande en cours de saisie.

Si vous obtenez cette invite après avoir simplement entré killl<Return>, la seule explication raisonnable est que vous avez un alias (qui est une forme d'extension de macro de chaîne) pour killlqu'il se développe en quelque chose qui contient une $(...)substitution de commande non terminée , comme:

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

zshvous demande de fermer cette $(...)substitution de commande.

Quelques notes supplémentaires:

  • la sortie de lsofest triée par pid. les numéros pid sont encapsulés, un pid plus grand ne garantit pas que le processus a été démarré plus tard.
  • -i:8080 signalera les sockets TCP ou UDP dont le port 8080 est le port source ou de destination, qu'il s'agisse d'un socket d'écoute, d'acceptation ou de connexion.
  • Si vous souhaitez obtenir le pid uniquement, vous pouvez utiliser l' -toption de lsof:lsof -ti:8080 | tail -n2
  • kill -9est kill -s KILL, ce qui envoie un signal que l'application ne peut pas agir pour se terminer normalement. Il ne doit être utilisé qu'en dernier recours.

Pour tuer le processus démarré le plus récemment qui a un socket lié (l'une ou l'autre extrémité) sur le port 8080, vous pouvez faire:

#! /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)}'

(suppose GNU sort(comme on le trouve sur macOS) et une psimplémentation qui prend en charge la lstartcolonne (comme macOS et procps-ng, bien que le code devrait être mis à jour pour procps-ng où les champs mois et jour sont échangés)).

Stéphane Chazelas
la source
1

Cela m'a donné une invite pour cmdsubst>

Parce que lorsque vous avez tapé la commande, vous n'avez pas tapé

killl
tu as tapé

killl $ (
ou similaire. Cela n'avait rien à voir avec le nom du script, ni même que c'était un script en premier lieu. Vous auriez pu obtenir le même effet avec une commande totalement inexistante:

Zeick $ (
L'analyseur du shell attendait plus de données pour terminer la seule commande partiellement terminée. Votre réflexion sur le nom du script est un hareng rouge complet.

JdeBP
la source
6
C'est une hypothèse assez grande pour dire qu'il a tapé killl $(pour une raison quelconque, et très peu probable qu'il l'ait fait. La réponse de Stéphane Chazelas est probablement le cas.
Herohtar
1
Si c'est effectivement dû à une faute de frappe, alors `c'est plus probable que $(.
Emil Jeřábek 3.0
2
Non, Emil Jeřábek; `est peu probable car il ne donne pas la même invite . Essayez-le. Non, Herhtar; ce n'est pas une hypothèse lors de la frappe ou similaire est le moyen d'obtenir cette invite . C'est une déduction.
JdeBP
1
Vous affirmez que OP "n'a pas tapé killl", alors que comme l'explique Stéphane Chazelas, il est tout à fait possible que OP ait bien tapé killl. Par conséquent, j'ai rejeté votre réponse comme étant incorrecte.
Kevin