web-dev-qa-db-ja.com

「killl」という名前のスクリプトが失敗するのはなぜですか?

問題のスクリプトは、ローカルホストのポート8080で最新のプロセスを終了します。

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

スクリプトに「killl」という名前が付けられている場合は、機能しませんでした(取得しますか?最新のものを削除しますか?)。それは私にcmdsubst>スクリプトの名前を「asdf」に変更すると、すべてが機能します。この動作の説明はありますか? MacOS ElCapitánを使用しています。

12
Zeick

_cmdsubst>_は、コマンド置換の終了が入力されるのを待っているときにzshシェルによって出力される2次プロンプトです。

_killl<Return>_を入力した後にそのプロンプトが表示される場合、唯一の妥当な説明は、killlのエイリアス(文字列マクロ展開の一種)があり、終了していないものに展開されていることです。 $(...)コマンド置換:

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

zshは、その$(...)コマンド置換を閉じるように求めています。

さらにいくつかのメモ:

  • lsofの出力はpidでソートされます。 pid番号はラップされます。pidが大きくても、プロセスが後で開始されたという保証はありません。
  • _-i:8080_は、リスニング、受け入れ、接続のいずれのソケットであっても、ソースポートまたは宛先ポートとして8080ポートを持つTCPまたはUDPソケットを報告します。
  • Pidのみを取得したい場合は、lsofの_-t_オプションを使用できます:_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-ngではコードを更新する必要があります))。

27