シェルスクリプトのプロセス名を設定する方法はありますか?これは、killallコマンドでこのスクリプトを強制終了するために必要です。
ここにそれを行う方法があります、それはハック/回避策ですが、それはかなりうまくいきます。必要に応じて自由に調整してください。競合状態を回避するために、シンボリックリンクの作成やtmpフォルダーの使用を確認する必要があります(問題がある場合)。
ラッパー
#!/bin/bash
script="./dummy"
newname="./killme"
rm -iv "$newname"
ln -s "$script" "$newname"
exec "$newname" "$@"
ダミー
#!/bin/bash
echo "I am $0"
echo "my params: $@"
ps aux | grep bash
echo "sleeping 10s... Kill me!"
sleep 10
以下を使用してテストします。
chmod +x dummy wrapper
./wrapper some params
別の端末で、次のコマンドを使用して終了します。
killall killme
現在のフォルダー(現在の作業ディレクトリ)に書き込みできることを確認してください。
現在のコマンドが:
/path/to/file -q --params somefile1 somefile2
script変数をwrapperに/ path/to/file(代わりに./ dummy)を呼び出して、次のようにwrapperを呼び出します。
./wrapper -q --params somefile1 somefile2
私が知る限り、これを確実かつ移植性のある方法で行うことはできません。 Unixのいくつかのフレーバーでは、argv [0]の内容を変更するとうまくいきます。しかし、ほとんどのシェルでそれを行う方法があるとは思えません。
このトピックに関する参考資料をいくつか紹介します。
それは実際には本当にシンプルで非常に柔軟性があります。
次のコマンドは、カスタムプロセス名CUSTOM-NAME
を持つプロセスを使用して、スクリプトをバックグラウンドでフォークします。
( exec -a "CUSTOM-NAME" /bin/bash ) </path/to/script.sh &
いくつかのメモ:
ps
はプロセスをCUSTOM-NAMEとして参照できません-プロセスはCUSTOM-NAMEとして表示されますが、内部ではbash
として表示されます。したがって、コマンド
ps h -C "CUSTOM-NAME" -o pid=
そのプロセスのPIDを返しません。名前でPIDを取得するには、以下が必要です(grep
のバージョンに注意してください-これが機能するにはPCREをサポートしている必要があります!):
ps h -C bash -o pid= -o cmd= | grep -m1 -oP "[0-9]+(?=\s+CUSTOM-NAME)"
起動時に標準入力からスクリプト全体を読み取るようにbashに強制することが重要です。これにより、スクリプト内の0のファイル記述子リダイレクトがスクリプトの読み取りに影響を与えません。それを行うには、次のようにスクリプト全体を{}
で囲みます。
( exec -a "CUSTOM-NAME" /bin/bash ) <<EOF &
{
$(cat /path/to/script.sh)
}
EOF
PIDでkillコマンドを使用すると、バックグラウンドで何かを実行し、そのIDを取得してkillできます。
バックグラウンドで実行された最後のジョブのPIDは、$!
を使用して取得できます。
echo test & echo $!
%1、%2 ...も適切な仕事をします:
#!/bin/bash
# set -ex
sleep 101 &
FIRSTPID=$!
sleep 102 &
SECONDPID=$!
echo $(ps ax|grep "^\(${FIRSTPID}\|${SECONDPID}\) ")
kill %2
echo $(ps ax|grep "^\(${FIRSTPID}\|${SECONDPID}\) ")
sleep 1
kill %1
echo $(ps ax|grep "^\(${FIRSTPID}\|${SECONDPID}\) ")
少なくともLinuxでは、dvb
はkillall dvb
のラベルが付いたシェルスクリプトですが、#!
は機能します。唯一のトリックは、スクリプトを実行可能にして名前で呼び出すことです。たとえば、
dvb watch abc write game7 from 9pm for 3:30
ps
を実行すると、次の名前のプロセスが表示されます
/usr/bin/lua5.1 dvb watch ...
しかしkillall dvb
はそれを削除します。