次に、このスクリプトを使用してプロセスを再起動します。
PID=`ps -ef|grep -w ${APP_NAME}|grep -v grep|cut -c 9-15`
if [[ ${PID} -gt 1 ]]; then
kill -9 ${PID}
else
echo "Process not found"
fi
ただし、GitHub Actionsのリモートサーバーでこのスクリプトを実行すると、次のエラーが表示されます。
======CMD======
cd /opt/apps/dolphin-acientbay/libs
. /opt/apps/dolphin-acientbay/libs/upgrade.sh
======END======
err: +/opt/apps/dolphin-acientbay/libs/upgrade.sh:13> JAVA_HOME=/***/.sdkman/candidates/java/11.0.11.hs-adpt
err: +/opt/apps/dolphin-acientbay/libs/upgrade.sh:14> APP_HOME=/opt/apps/dolphin-acientbay/libs
err: +/opt/apps/dolphin-acientbay/libs/upgrade.sh:15> APP_NAME=dolphin-acientbay-service-1.0.0-SNAPSHOT.jar
err: +/opt/apps/dolphin-acientbay/libs/upgrade.sh:17> PID=+/opt/apps/dolphin-acientbay/libs/upgrade.sh:17> ps -ef
err: +/opt/apps/dolphin-acientbay/libs/upgrade.sh:17> PID=+/opt/apps/dolphin-acientbay/libs/upgrade.sh:17> grep -w dolphin-acientbay-service-1.0.0-SNAPSHOT.jar
err: +/opt/apps/dolphin-acientbay/libs/upgrade.sh:17> PID=+/opt/apps/dolphin-acientbay/libs/upgrade.sh:17> grep -v grep
err: +/opt/apps/dolphin-acientbay/libs/upgrade.sh:17> PID=+/opt/apps/dolphin-acientbay/libs/upgrade.sh:17> cut -c 9-15
err: +/opt/apps/dolphin-acientbay/libs/upgrade.sh:17> PID=' 19882 '
2021/05/30 11:46:21 Process exited with status 1
err: +/opt/apps/dolphin-acientbay/libs/upgrade.sh:18> [[ ' 19882 ' -gt 1 ]]
err: +/opt/apps/dolphin-acientbay/libs/upgrade.sh:19> kill -9 ' 19882 '
err: /opt/apps/dolphin-acientbay/libs/upgrade.sh:kill:19: illegal pid: 19882
完全なスクリプトは次のとおりですupgrade.sh
。
#!/usr/bin/env bash
set -u
set -e
set -x
JAVA_HOME="/root/.sdkman/candidates/java/11.0.11.hs-adpt"
APP_HOME="/opt/apps/dolphin-acientbay/libs"
APP_NAME="dolphin-acientbay-service-1.0.0-SNAPSHOT.jar"
PID=`ps -ef|grep -w ${APP_NAME}|grep -v grep|cut -c 9-15`
if [[ ${PID} -gt 1 ]]; then
kill -9 ${PID}
else
echo "Process not found"
fi
sleep 5
count=`ps -ef | grep ${APP_NAME} | grep -v "grep" | wc -l`
if [[ ${count} -lt 1 ]]; then
nohup ${JAVA_HOME}/bin/java -Xmx128M -Xms128M -jar \
-Xdebug -Xrunjdwp:transport=dt_socket,suspend=n,server=y,address=0.0.0.0:5021 \
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/apps/dolphin-acientbay/ \
${APP_HOME}/${APP_NAME} >> ./acientbay.log &
sleep 5
else
echo "process aready exists!"
exit 1
fi
pidの空白を削除するために、次のようにkill processコマンドを調整してみました(xargsはpidの空白を切り捨てます)。
echo "${PID}" | xargs | kill -9
それは私に言う:
err: /opt/apps/dolphin-acientbay/libs/upgrade.sh:kill:19: not enough arguments
答え1
これが問題の原因です。
PID=`ps -ef|grep -w ${APP_NAME}|grep -v grep|cut -c 9-15`
変数を使用するときは二重引用符を使用してください。たとえば、「$APP_NAME」や「${APP_NAME}」などです。
ただし、中括弧は、文字列の他のテキストと変数を区別する必要がある場合にのみ必要です。たとえば、変数が実際にあるが
$APP
文字列で使用する必要がある場合に_NAME
使用できます。"${APP}_NAME"
これにより、_NAME
シェルがその変数を変数名の一部として解釈できなくなります。代わりにバックティックを使用しています
$()
。これは長年使用されなくなり、その理由があります。それは問題の原因ではなく、捨てるべき悪い習慣です。cut
1つ以上の文字で区切ることができるフィールドを抽出するのに最適なツールではありません。フィールド間に区切り文字が1つしかない場合にのみ有効です。多くのテキストファイルは、フィールド区切り文字として1つ以上のスペース(および/またはタブおよび/または他のスペース文字)を使用するため、または代わりに簡単に使用できませんcut
。awk
perl
これを使用すると、
cut -c 9-15
$ PIDに少なくとも1つの追加の空白文字がキャプチャされます。 PIDを抽出するには代わりにをps -ef
使用してください。awk '{print $2}'
cut -c 9-15
pgrep "$APP_NAME"
名前でプロセスのPIDを取得するために使用されます。または、pgrep -f "$APP_NAME"
検索中の文字列が引数の場合(たとえば、スクリプト名がインタプリタに引数として渡されるなど)貨物崇拝は
ps | grep ... | grep -v grep
何十年もの間、流行に劣ってきました。常により良いアプローチがありましたが(ps -ef | awk '/[p]rocess_name/ {print $2}'
パターンの最初の文字の周りを配置すると、awk、grep、または他の項目がps出力で一致するのを防ぐことができます)、今やそのアプローチも。[]
pgrep
ps
それ自体には、-C
プロセス名一致オプション、h
ヘッダー抑制オプション、-o
必要な出力指定オプションがありますps
。例えばps h -o pid -C "$APP_NAME"
要約すると、次のようになります。
PID=$(pgrep "$APP_NAME")
or
PID=$(pgrep -f "$APP_NAME")
or
PID=$(ps h -o pid -C "$APP_NAME")
しかし、もしあればどのpgrep
複数のPIDを返す可能性があるため、ps
出力をスカラー変数ではなく配列としてキャプチャする必要があります。たとえば、次のコマンドは、表示されるすべてのbashプロセスのPIDを配列としてキャプチャします$BASHPIDS
。
$ BASHPIDS=( $(ps h -o pid -C bash) )
$ typeset -p BASHPIDS
declare -a BASHPIDS=([0]="68910" [1]="71059" [2]="71634" [3]="71641" [4]="71643"
[5]="71680" [6]="71683" [7]="71684" [8]="71687" [9]="71693" [10]="71712" [11]="72394"
[12]="72568" [13]="72589" [14]="970222" [15]="974740" [16]="1078757" [17]="1278073"
[18]="1365082" [19]="1405642" [20]="1458889" [21]="2278763" [22]="2466442" [23]="2876831"
[24]="2955565" [25]="3260896" [26]="3261235" [27]="3269020" [28]="3281961" [29]="3702104"
[30]="4038149")
何らかの理由でそれらをすべて殺したい場合は、次のようにすることができます。
kill "${BASHPIDS[@]}"
答え2
このコマンドで問題を解決しました。
echo "${PID}" | xargs kill -9