こんにちは、長い歴史短い:特定のプロセスを強制終了するためにCIサーバーを介して実行するスクリプトを作成しようとしています。
インターネットで検索すると、次のコマンドが見つかりました。
myuser@server:/home/myuser# ps -ef | grep someUniqueText | grep -v grep | awk '{print $2}'
5263
コンソールで実行すると、必要なもの(5263
)が返されるため、このbashを作成しました。
#!/bin/bash
PROCESSNAME=$1
PID=$(ps -ef | grep $PROCESSNAME | grep -v grep | awk '{print $2}');
echo $PID;
次のように実行すると:
myuser@server:/home/myuser# ./killProcess.sh somename
5263 4587 1236
Bashスクリプトは、最初に必要なプロセスである3つの数字を返します。他の2つが何であるかはわかりませんなぜ? o.O
PS .:最初にテストするためにecho
を使用していますが、kill -9
に変更します
./killProcess.sh somename
を実行すると、次のようなプロセス
/bin/bash ./killProcess.sh somename
が存在し、ps | grep | grep | awk
-行もテキストsomename
を含むため、これを見つけます。なぜ1つだけではなく2つの追加のPIDを取得するのか正確にはわかりませんが、bash
とkillProcess.sh
の間に親子関係があると思います。 1行ではPIDがPIDとして表示され、もう1行ではPPIDとして表示されます。
これらのPIDは、スクリプト名に基づいてgrepすることで回避できます。 $0
に保存されるため、
PID=$(ps -ef | grep $PROCESSNAME | grep -v grep | grep -v $0 | awk '{print $2}');
または(プログラム呼び出しが少ない場合):
PID=$(ps -ef | grep $PROCESSNAME | grep -v -e grep -e $0 | awk '{print $2}');
別の(より安全な)方法は、スクリプトのPIDを削除することです。 $$
に保存されます:
PID=$(ps -ef | grep $PROCESSNAME | grep -v -e grep -e $$ | awk '{print $2}');
または、awk
ですべて実行します。
PID=$(ps -ef | awk "/$PROCESSNAME/ && !/awk/ && !/$$/ {print \$2}");
ここでは\$2
をエスケープする必要があるため、シェルではなくawk
で解釈されます。このコマンドの意味は次のとおりです。
行に$PROCESSNAME
が含まれ、awk
が含まれておらず、独自のPIDが含まれていない場合、2番目の列を印刷します。
利点は(理論上)、3 grepsとawkではなく、追加のコマンド(awk
)が1つだけ必要なため、これが高速に実行されることです。
これらすべてgrepsおよびawksは完全ではなく、常にここで考えていない状況を見つけてください(部分一致など)。そのため、すでに作成されているツールのいずれかを使用することをお勧めします。
killall somename
#プレビューするには、最初にkillall -v -s 0 somename
を実行しますpgrep somename
#PIDをリストするpkill somename
#killall
と同様シェル関数として、psg
( "ps | grep")を呼び出す同様のアイデアを実装したことがあります
psg() {
local -a patterns=()
(( $# == 0 )) && set -- $USER
for arg do
patterns+=( "-e" "[${arg:0:1}]${arg:1}" )
done
ps -ef | grep "${patterns[@]}"
}
これは、パターンの最初の文字を括弧で囲むトリックを使用するため、次のようになります
ps -ef | grep "[s]omename"
これにより、grep -v grep
パイプラインの一部。
引数を渡さない場合、ユーザー名を使用してプロセスを検索します。