为什么我的脚本“ killl”失败了,但是重命名后却能正常工作?


12

有问题的脚本终止了我的本地主机端口8080上的最新进程。

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

如果脚本被命名为“ killl”(得到它吗?杀死最新消息?),那是行不通的。它提示我cmdsubst> 将脚本重命名为“ asdf”,一切正常。有这种行为的解释吗?我正在使用MacOS ElCapitán。


5
您是否还有另一个名为的函数,别名,实用程序或其他命令killl
库萨兰达

9
不要使名称含糊不清。killl可能被误解为拼写错误kill。最好是明确且更具描述性:kill_latestkill_last
cezar

6
type killl您尝试启动它的shell中的输出是什么?
Hauke Laging,

Answers:


27

cmdsubst>zshshell在等待输入命令替换结束时打印的辅助提示符。

如果在刚输入时得到提示killl<Return>,则唯一合理的解释是您有一个别名(这是字符串宏扩展的某种形式),killl该别名扩展为包含无终止$(...)命令替换的内容,例如:

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

在哪里zsh要求您关闭该$(...)命令替换。

一些注意事项:

  • 的输出lsof按pid排序。pid号是自动换行的,较大的pid不能保证以后启动进程。
  • -i:8080 将报告以8080端口作为源端口或目标端口的TCP或UDP套接字,无论是侦听,接受还是连接套接字。
  • 如果只想获取pid,则可以使用以下-t选项lsoflsof -ti:8080 | tail -n2
  • kill -9kill -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的代码进行更新,而procps-ng需要交换月份和日期字段))。


1

它给了我一个提示 cmdsubst>

因为当您键入命令时,您没有键入

基尔
你打过

杀手$(
或类似。这脚本的名称无关,甚至根本就不是一个脚本。使用完全不存在的命令,您可能已经达到了相同的效果:

蔡克$(
Shell的解析器期望更多输入来完成唯一部分完成的命令。您对脚本名称的思考是完全的红色鲱鱼。


6
这是一个很大的假设,可以说他killl $(由于某种原因打字,而且不太可能这样做。斯蒂芬·查泽拉斯(StéphaneChazelas)的回答更可能是这种情况。
Herohtar '17

1
如果确实是由于打字错误,则`比的可能性更大$(
EmilJeřábek'17 October

2
不,EmilJeřábek;`根本不可能,因为它没有给出相同的提示。尝试一下。不,赫塔尔;这不是一个假设,当输入的是或类似的,以获取提示的方式。这是一个推论。
JdeBP

1
您断言OP“没有键入killl”,正如StéphaneChazelas解释的那样,OP确实有可能确实键入了killl。因此,我认为您的回答是错误的。
凯文(Kevin)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.