web-dev-qa-db-ja.com

シェルスクリプトのプロセス名を設定する方法

シェルスクリプトのプロセス名を設定する方法はありますか?これは、killallコマンドでこのスクリプトを強制終了するために必要です。

28
dan

ここにそれを行う方法があります、それはハック/回避策ですが、それはかなりうまくいきます。必要に応じて自由に調整してください。競合状態を回避するために、シンボリックリンクの作成や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
22
Weboide

私が知る限り、これを確実かつ移植性のある方法で行うことはできません。 Unixのいくつかのフレーバーでは、argv [0]の内容を変更するとうまくいきます。しかし、ほとんどのシェルでそれを行う方法があるとは思えません。

このトピックに関する参考資料をいくつか紹介します。

2
Brian Clapper

それは実際には本当にシンプルで非常に柔軟性があります。

次のコマンドは、カスタムプロセス名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
    
1
ExtraT

PIDでkillコマンドを使用すると、バックグラウンドで何かを実行し、そのIDを取得してkillできます。

バックグラウンドで実行された最後のジョブのPIDは、$!を使用して取得できます。

echo test & echo $!

1
Abs

%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}\) ")
0
slaxor

少なくともLinuxでは、dvbkillall dvbのラベルが付いたシェルスクリプトですが、#!は機能します。唯一のトリックは、スクリプトを実行可能にして名前で呼び出すことです。たとえば、

dvb watch abc write game7 from 9pm for 3:30

psを実行すると、次の名前のプロセスが表示されます

/usr/bin/lua5.1 dvb watch ...

しかしkillall dvbはそれを削除します。

0
Norman Ramsey