異なる場所に同じファイル名を持つ 3 つの異なるアプリがある場合、フルネームで 1 つを強制終了するにはどうすればよいでしょうか?

異なる場所に同じファイル名を持つ 3 つの異なるアプリがある場合、フルネームで 1 つを強制終了するにはどうすればよいでしょうか?

異なるパスから同じファイル名を持つ 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-90-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 スクリプトでラップすることができます。

関連情報