プロセスを確認し、実行中のプロセスを終了します。

プロセスを確認し、実行中のプロセスを終了します。

プロセスが実行中かどうかを知りたいです。実行している場合は、スクリプトを呼び出すか、何かを印刷したいと思います。以下を試しましたが、構文エラーまたはコマンドが見つかりませんエラーが発生します。

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 

上記のスクリプトにはどのような問題がありますか?エラーがある場合はecho条件付きで印刷するのはなぜですかif

以下のスクリプトも失敗します。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

答え1

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

  • 変数を設定するときは、「=」の周囲のスペースを削除してください。

    無効:

    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

答え2

pgrepこれは以下を使用して最も簡単に行うことができますpkill

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

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

ただ

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

とにかく不快な競争条件を取り除きます。

答え3

理由はわかりませんが、上記のスクリプトは構文の問題を提供せず、プロセスは実行中ですが、プロセス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

あなたの説明と地図にもう一度感謝します。

@Peter、投稿したスクリプトをもう一度確認して、なぜ機能しないのかを確認します。

答え4

上記のコマンドはgrep自体もキャプチャするため、Javaプロセスの場合、コマンドは次のようになります。

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

echo "Instance $APP_ID"
if [ -n "${APP_ID}" ]; then
    echo "Stopping instance $APP_ID"
    kill $APP_ID   (or kill -9 $APP_ID)
fi

お役に立てば幸いです。

関連情報