¿Por qué mi script llamado "killl" falla, pero después de cambiar el nombre funciona perfectamente?

12

El script en cuestión finaliza el último proceso en mi puerto local 8080.

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

No funcionó, si el script se llamaba 'killl' (¿entiendes? ¿Matar más reciente?). Me dio un mensaje para cmdsubst> cambiar el nombre del script a 'asdf', todo funciona. ¿Hay alguna explicación para este comportamiento? Estoy usando MacOS El Capitán.

Zeick
fuente
55
¿Tiene otra función, alias, utilidad u otro comando llamado killl?
Kusalananda
99
No hagas que los nombres sean ambiguos. killlpuede malinterpretarse como incorrectamente deletreado kill. Es mejor ser explícito y más descriptivo: kill_latesto kill_last.
cezar
66
¿Cuál es la salida del type killlshell donde intentaste iniciarlo?
Hauke ​​Laging

Respuestas:

27

cmdsubst>es la solicitud secundaria impresa por el zshshell cuando está esperando que se ingrese el final de una sustitución de comando.

Si obtiene ese mensaje después de ingresar killl<Return>, la única explicación razonable es que tiene un alias (que es una forma de expansión de macro de cadena) killlque se expande a algo que contiene una $(...)sustitución de comando no terminada , como:

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

¿Dónde le zshestá pidiendo que cierre esa $(...)sustitución de comando?

Algunas notas más:

  • la salida de lsofse ordena por pid. los números pid están envueltos, un pid más grande no es garantía de que el proceso se inició más tarde.
  • -i:8080 informará los sockets TCP o UDP que tienen el puerto 8080 como puerto de origen o destino, ya sea un socket de escucha, de aceptación o de conexión.
  • Si solo quieres obtener el pid, puedes usar la -topción de lsof:lsof -ti:8080 | tail -n2
  • kill -9es decir kill -s KILL, que envía una señal de que la aplicación no puede actuar para salir con gracia. Solo debe usarse como último recurso.

Para eliminar el proceso iniciado más recientemente que tiene un socket vinculado (cualquier extremo) en el puerto 8080, puede hacer:

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

(asume GNU sort(como se encuentra en macOS) y una psimplementación que admite la lstartcolumna (como macOS 'y procps-ng, aunque el código tendría que actualizarse para procps-ng donde se intercambian los campos de mes y día)).

Stéphane Chazelas
fuente
1

Me dio un aviso para cmdsubst>

Porque cuando escribiste el comando no escribiste

killl
escribiste

killl $ (
o similar. Esto no tenía nada que ver con el nombre del guión, o incluso que era un guión en primer lugar. Podría haber logrado el mismo efecto con un comando totalmente inexistente:

Zeick $ (
El analizador del shell esperaba más entrada para completar el único comando parcialmente completo. Su pensamiento sobre el nombre del guión es una pista falsa completa.

JdeBP
fuente
66
Es una suposición bastante grande decir que escribió killl $(por alguna razón, y es muy poco probable que lo haya hecho. La respuesta de Stéphane Chazelas es más probable.
Herohtar
1
Si de hecho se debe a un error tipográfico, entonces `es más probable que $(.
Emil Jeřábek 3.0
2
No, Emil Jeřábek; `no es probable en absoluto ya que no da el mismo aviso . Intentalo. No, Herhtar; No es una suposición cuando escribir eso o similar es la forma de obtener ese aviso . Es una deducción.
JdeBP
1
Usted afirma que OP "no killlescribió" cuando, como explica Stéphane Chazelas, es completamente posible que OP sí lo haya hecho killl. Por lo tanto, he rechazado su respuesta como incorrecta.
Kevin