Чому мій сценарій під назвою "killl" не працює, але після перейменування працює чудово?


12

Скрипт, про який йдеться, припиняє останній процес на моєму порталі localhost 8080.

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

Це не спрацювало, якщо сценарій був названий "killl" (отримаєте його? Вбити останнє?). Це дало мені запит на cmdsubst> перейменування сценарію на 'asdf', все працює. Чи є пояснення такої поведінки? Я використовую MacOS El Capitán.


5
Чи є у вас інша функція, псевдонім, утиліта чи інша команда, яка називається killl?
Kusalananda

9
Не робіть імена неоднозначними. killlможе неправильно трактуватися як неправильно написане kill. Краще бути явним і більш описовим: kill_latestабо kill_last.
cezar

6
Який вихід type killlв оболонці, де ви намагалися її запустити?
Хоуке Лагінг

Відповіді:


27

cmdsubst>- це вторинна підказка, надрукована zshоболонкою, коли вона чекає закінчення введення підстановки команди.

Якщо ви отримаєте це підказку після простого введення killl<Return>, то єдиним розумним поясненням є те, що у вас є псевдонім (який є деякою формою розширення макросу рядків), killlякий розширюється на те, що містить незакінчену $(...)заміну команди, наприклад:

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

Де zshпросять закрити цю $(...)заміну команди.

Ще кілька приміток:

  • вихід lsofсортується за pid. число підказок завершено, більший pid не є гарантією того, що процес було розпочато пізніше.
  • -i:8080 повідомить TCP або UDP-сокети, які мають порт 8080 як вихідний або цільовий порт, незалежно від того, чи це сокет прослуховування, прийняття або з'єднання.
  • Якщо ви хочете отримати лише pid, ви можете скористатися -tопцією lsof:lsof -ti:8080 | tail -n2
  • kill -9тобто kill -s KILLпередає сигнал, що програма не може діяти, щоб вийти граціозно. Його слід використовувати лише в крайньому випадку.

Для вбивства останнього запущеного процесу, який має порт (пов'язаний з сокетом) на порту 8080, ви можете зробити:

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

(Передбачається , що GNU sort(як знайти на MacOS) і psреалізація , яка підтримує lstartстовпець (наприклад , MacOS »і Procps-нг, хоча код повинен бути поновлений на Procps-нг , де місяць і день поля міняються місцями)).


1

Це дало мені підказку для cmdsubst>

Тому що, коли ви вводили команду, ви не вводили

вбивати
ви набрали

$ killl (
або подібне. Це не мало нічого спільного з назвою сценарію, або навіть з тим, що це сценарій в першу чергу. Такого ж ефекту можна було досягти і зовсім неіснуючою командою:

Zeick $ (
Аналізатор оболонки очікував більше введення для виконання єдиної частково завершеної команди. Ваше роздуми над ім'ям сценарію - це повна червона оселедець.


6
Це досить велике припущення сказати, що він набрав killl $(чомусь, і дуже малоймовірно, що він це зробив. Відповідь Стефана Шазеласа скоріше так.
Герохтар

1
Якщо це справді пов’язано з помилкою друку, то `це швидше, ніж $(.
Еміль Єржабек

2
Ні, Еміль Єржабек; `зовсім не вірогідний, оскільки він не дає того самого підказу . Спробуй це. Ні, Герхтар; це не припущення , коли типування , що або подібне є спосіб , щоб отримати це запрошення . Це відрахування.
JdeBP

1
Ви стверджуєте, що ОП "не killlнабрав", коли, як пояснює Стефан Шазелас, цілком можливо, що ОП дійсно набрав тип killl. Тому я визнав вашу відповідь неправильною.
Кевін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.