Почему мой скрипт с именем «killl» не работает, но после переименования работает отлично?


12

Рассматриваемый скрипт завершает последний процесс на моем локальном порте 8080.

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

Это не сработало, если сценарий был назван «killl» (получите? Kill Latest?). Это дало мне подсказку для cmdsubst> переименования скрипта в «asdf», все работает. Есть ли объяснение этому поведению? Я использую MacOS El Capitán.


5
У вас есть другая функция, псевдоним, утилита или другая команда killl?
Кусалананда

9
Не делайте имена двусмысленными. killlможет быть неверно истолковано как неправильно написано kill. Лучше быть явным и более наглядным: kill_latestили kill_last.
Цезарь

6
Что выводится type killlв оболочке, где вы пытались его запустить?
Хауке Лагинг

Ответы:


27

cmdsubst>вторичная подсказка, напечатанная zshоболочкой, когда она ожидает окончания подстановки команды.

Если вы получаете это приглашение после простого ввода killl<Return>, то единственное разумное объяснение состоит в том, что у вас есть псевдоним (который является некоторой формой раскрытия строкового макроса), killlкоторый расширяется до чего-то, что содержит неопределенную $(...)подстановку команд, например:

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

Где zshпросит вас закрыть эту $(...)подстановку команд.

Еще несколько заметок:

  • вывод lsofсортируется по pid. Номера pid обернуты, больший pid не гарантирует, что процесс был запущен позже.
  • -i:8080 будет сообщать о сокетах TCP или UDP с портом 8080 в качестве порта источника или назначения, будь то прослушивающий, принимающий или соединительный сокет.
  • Если вы хотите получить только pid, вы можете использовать -tопцию lsof:lsof -ti:8080 | tail -n2
  • kill -9is 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-ng, хотя код должен был бы быть обновлен для procps-ng, где поменялись поля месяца и дня)).


1

Это дало мне подсказку для cmdsubst>

Потому что, когда вы набрали команду, вы не набрали

killl
ты напечатал

килл $ (
или похожие. Это не имело никакого отношения к названию сценария или даже к тому, что это был сценарий в первую очередь. Вы могли бы достичь того же эффекта с помощью совершенно несуществующей команды:

Zeick $ (
Парсер оболочки ожидал большего ввода для выполнения единственной частично завершенной команды. Вы думаете о названии сценария - полная красная сельдь.


6
Это довольно большое предположение, чтобы сказать, что он напечатал killl $(по какой-то причине, и очень маловероятно, что он сделал это. Ответ Стефана Шазеласа более вероятен.
Herohtar

1
Если это действительно из-за опечатки, то `более вероятно, чем $(.
Эмиль Йержабек 3.0

2
Нет, Эмиль Йержабек; `маловероятно, так как он не выдает такой же запрос . Попытайся. Нет, Херхтар; это не предположение , когда типирование , что или подобное есть способ , чтобы получить это приглашение . Это дедукция.
JdeBP

1
Вы утверждаете, что OP «не печатал killl», когда, как объясняет Стефан Шазелас, вполне возможно, что OP действительно печатал killl. Поэтому я отклонил ваш ответ как неправильный.
Кевин
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.