Perché la mia sceneggiatura chiamata "killl" fallisce, ma dopo aver rinominato funziona perfettamente?


12

Lo script in questione termina l'ultimo processo sulla mia porta 8080 localhost.

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

Non ha funzionato se lo script è stato chiamato "killl" (capito? Kill Latest?). Mi ha dato un prompt per cmdsubst> rinominare lo script in 'asdf', tutto funziona. C'è una spiegazione per questo comportamento? Sto usando MacOS El Capitán.


5
Hai un'altra funzione, un alias, un'utilità o un altro comando chiamato killl?
Kusalananda

9
Non rendere ambigui i nomi. killlpuò essere interpretato erroneamente come erroneamente scritto kill. È meglio essere espliciti e più descrittivi: kill_latesto kill_last.
Cezar,

6
Qual è l'output di type killlnella shell in cui hai provato ad avviarlo?
Hauke ​​Laging,

Risposte:


27

cmdsubst>è il prompt secondario stampato dalla zshshell quando è in attesa che venga immessa la fine di una sostituzione di comando.

Se ricevi quel prompt dopo aver appena inserito killl<Return>, l'unica spiegazione ragionevole è che hai un alias (che è una forma di espansione di macro di stringhe) killlche si espande in qualcosa che contiene una $(...)sostituzione di comando non terminata , come:

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

Dove ti zshsta chiedendo di chiudere quella $(...)sostituzione di comando.

Qualche nota in più:

  • l'output di lsofè ordinato per pid. i numeri di pid sono racchiusi, un pid più grande non è garanzia che il processo sia stato avviato in seguito.
  • -i:8080 segnalerà i socket TCP o UDP che hanno la porta 8080 come porta di origine o di destinazione, sia che si tratti di un socket in ascolto, di accettazione o di connessione.
  • Se vuoi ottenere solo il pid, puoi usare l' -topzione di lsof:lsof -ti:8080 | tail -n2
  • kill -9è kill -s KILL, che invia un segnale sul quale l'applicazione non può agire per uscire con grazia. Dovrebbe essere usato solo come ultima risorsa.

Per terminare il processo avviato più di recente che ha un socket associato (una delle estremità) sulla porta 8080, è possibile eseguire:

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

(presuppone GNU sort(come si trova su macOS) e psun'implementazione che supporti la lstartcolonna (come macOS 'e procps-ng's, anche se il codice dovrebbe essere aggiornato per procps-ng dove i campi del mese e del giorno vengono scambiati)).


1

Mi ha dato una richiesta cmdsubst>

Perché quando hai digitato il comando non hai digitato

killl
hai digitato

killl $ (
o simili. Questo non aveva nulla a che fare con il nome della sceneggiatura, o addirittura che si trattava in primo luogo di una sceneggiatura. Avresti potuto ottenere lo stesso effetto con un comando totalmente inesistente:

Zeick $ (
Il parser della shell si aspettava più input per completare il comando solo parzialmente completo. Il tuo pensiero sul nome dello script è un'aringa rossa completa.


6
È un presupposto piuttosto grande da dire che ha digitato killl $(per qualche motivo, e molto improbabile che lo abbia fatto. La risposta di Stéphane Chazelas è più probabile il caso.
Herohtar,

1
Se è effettivamente dovuto a un refuso, allora `è più probabile che $(.
Emil Jeřábek 3.0

2
No, Emil Jeřábek; `non è affatto probabile poiché non fornisce lo stesso prompt . Provalo. No, Herhtar; non è un presupposto quando si digita quello o simile è il modo per ottenere quel prompt . È una deduzione.
JdeBP,

1
Affermate che OP "non ha digitato killl", quando come spiega Stéphane Chazelas, è del tutto possibile che OP abbia effettivamente digitato killl. Pertanto, ho valutato la tua risposta come errata.
Kevin,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.