
異なるパスから同じファイル名を持つ 3 つのアプリを実行しています。
$ ~/app1/main
$ ~/app2/main
$ ~/app3/main
実行可能ファイルの完全な名前を受け入れてそのアプリを強制終了する bash スクリプトを作成したいと思います。
$ ./my_killer.sh /home/me/app2/main
どうすればそれができるのでしょうか、特にフルネームでアプリを強制終了するにはどうすればいいのでしょうか?
答え1
Linux のみをサポートする必要がある場合 (質問に linux タグが付いているのでそうだと思います)、/proc/%d/exe
シンボリック リンクを利用できます。
これを実行するためのスクリプトの例を次に示します。
#!/bin/bash
if [ "$#" != 1 ] || [ "$1" = "" ]
then
echo "Usage: $0 <full-exe-path>" 1>&2
exit 1
fi
shopt -s extglob
cd /proc
for PID in [1-9]*([0-9])
do
if [ "$(readlink "$PID"/exe)" = "$1" ]
then
kill "$PID"
fi
done
注意すべき 1 つの注意点は、プロセス ID がカーネル スレッドであるか、所有されていない場合はreadlink
失敗し、空の文字列として評価されることです。これらのプロセスをすべて強制終了しようとするのを避けるために、スクリプトは空の文字列の"$(readlink "$PID"/exe)"
場合は何も行いません。$1
また、このスクリプトでは、 という間隔内の文字の後に という間隔内の任意の数の文字が続くことを意味extglob
する というディレクトリの一致を可能にする を使用していることにも注意してください。[1-9]*([0-9])
1-9
0-9
答え2
私はこれをパイピングを使ったワンライナーで実行します ( と が必要ですgawk
) xargs
。
$>ps -ax | grep "/app2/main" | grep -v "grep" | gawk '{print $1}' | xargs kill
ここで何が起きてるの?
ps -ax # — list all processes in extended format
grep "/app2/main" # — show only processes that contain "/app2/main"
grep -v "grep" # — sort out the previous grep process with the mentioned string
gawk '{print $1}' # — use gawk to pick only the first column (process id)
xargs kill # — use xargs to pass pid to kill as an argument
これにより、必要なプロセスに強制終了信号が効果的に送信されます。引数付きの短いコマンドが必要な場合は、これを bash スクリプトでラップすることができます。