web-dev-qa-db-ja.com

プロセスを確認し、実行中の場合は強制終了します

プロセスが実行中かどうかを確認しようとしています。実行中の場合は、スクリプトを呼び出すか、何かを印刷します。以下のいくつかの方法を試してみましたが、構文エラーまたはコマンドが見つからないというエラーが表示されます。

APP_ID = ps -eaf | grep -i `whoami` | grep -i <process_name> | grep -i Java | awk '{print$2}'

if[''!= '${APP_ID}'] then
    echo "Stopping instance $APP_ID"

次のような結果が得られます。

test.sh: line 15: APP_ID: command not found
test.sh: line 17: if[!= ${APP_ID}]: command not found
Stopping instance 

上記のスクリプトの何が問題になっていますか?エラーがある場合、なぜechoif状態で出力するのですか?

また、以下のスクリプトはtest.sh: line 3: [ps: command not foundと言って失敗します

if [ps -eaf | grep -i `whoami` | grep -i <process_name> | grep -i Java]; then
    echo 'stop'
fi
3
user179309

構文には多くの問題があります:

  • 変数を設定するときに「=」の前後のスペースを削除する

    違う:

    _APP_ID = value
    _

    正しい:

    _APP_ID=value
    _
  • プログラムを実行してその出力を変数に入れるには、$(...)(bashでは推奨、shでは使用不可)またはバッククォート_`command`_(bashおよびshでサポート)が必要です。 (そして、変数を割り当てるとき、引用符は必要ありませんが、他の場合には引用符が重要であることを覚えておいてください:command "$(command)"

    違う:

    _APP_ID=command
    _

    正しい:

    _APP_ID=$(command)
    _
  • 「[」を使用する場合は、すべての周りにスペースを追加してください。「]」の後にはセミコロンまたは改行が必要です。これは、 "["がbash組み込みコマンドであり、非組み込みコマンドが "test"としても知られているため(_man test_を参照)、他のコマンドと同様に、スペースで区切られた引数を取ります。

    違う:

    _if[x!= y] then echo hello world fi
    _

    正しい:

    _if [ x != y ]; then echo hello world; fi
    _
  • 変数を展開する場合は、一重引用符ではなく二重引用符を使用します

    違う:

    _if [ '' != '${APP_ID}' ]; then
    _

    正しい:

    _if [ '' != "${APP_ID}" ]; then
    _
  • また、上記の例では、空の文字列と比較する代わりに-n(空ではない)を使用できます

    _if [ -n "${APP_ID}" ]; then
    _
  • そして、psの例では、grepやawkは必要ありません。

    _APP_ID=$(ps -C whoami --no-header --format 'pid')
    _

そしてここに修正されたスクリプトがあります:

_APP_ID=$(ps -C whoami --no-header --format 'pid')

if [ -n "${APP_ID}" ]; then
    echo "Stopping instance $APP_ID"
fi
_
10
Peter

これは、pgreppkillを使用すると最も簡単です。

if pgrep process_name 2>/dev/null; then
  echo "Terminating process_name"
  pkill process_name
fi

ユーザー@OrangeDogがコメントで指摘しているように、このシェルコードがプロセスを終了できないという理論的な可能性がありますprocess_nameプロセスがpgreppkillの呼び出しの間に生成された場合。この場合、pgrepはプロセスを検出せず、pkillは実行されません。これがどれほどの問題か、わかりません。プロセスがafterステートメントだけを生成する場合、何ができますか?

するだけ

echo "terminating process_name (if it is running)"
pkill process_name

どんな場合でも厄介な競争状態を取り除くために。

3
Kusalananda

理由はわかりませんが、上記のスクリプトでは構文の問題は発生しませんでしたが、プロセスが実行されていてもプロセスIDが表示されませんでした。

私は最終的にそれを以下のように変更し、うまくいきました-

APP_ID=$(ps -ef | grep <app_name> | grep Java | awk '{print $2}')

echo "Instance $APP_ID"
if [ -n "${APP_ID}" ]; then
    echo "Stopping instance $APP_ID"
fi

説明とポインタをもう一度ありがとう。

@ピーター私はあなたが投稿したスクリプトがなぜ私にとってうまくいかないのかをもう一度チェックします。

1
user179309