Jetzt verwende ich dieses Skript, um meinen Prozess neu zu starten:
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
aber wenn ich dieses Skript von GitHub Actions auf einem Remote-Server ausführe, wird dieser Fehler angezeigt:
======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
Dies ist das vollständige Skript von 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
Ich habe versucht, den Befehl „Kill Process“ wie folgt zu optimieren (die Xargs entfernen die Leerzeichen aus der PID):
echo "${PID}" | xargs | kill -9
es sagt mir:
err: /opt/apps/dolphin-acientbay/libs/upgrade.sh:kill:19: not enough arguments
Antwort1
Hier ist die Ursache Ihres Problems:
PID=`ps -ef|grep -w ${APP_NAME}|grep -v grep|cut -c 9-15`
Setzen Sie Ihre Variablen in doppelte Anführungszeichen, wenn Sie sie verwenden, z. B. „$APP_NAME“ oder „${APP_NAME}“.
Übrigens werden die geschweiften Klammern nur benötigt, wenn Sie eine Variable von anderem Text in einem String unterscheiden müssen. Wenn die Variable z. B. tatsächlich wäre,
$APP
Sie sie aber in einem String mit verwenden müssten_NAME
, würden Sie"${APP}_NAME"
- verwenden. Dadurch würde verhindert, dass_NAME
die Shell sie als Teil des Variablennamens interpretiert.Sie verwenden Backticks anstelle von
$()
. Sie sind seit Jahren veraltet und das aus gutem Grund. Sie sind hier nicht die Ursache des Problems, sondern nur eine schlechte Angewohnheit, die Sie aufgeben müssen.cut
ist kein gutes Tool zum Extrahieren von Feldern, die durch 1 oder mehr Zeichen getrennt werden können. Es ist nur dann gut, wenn es ein (und genau ein) Trennzeichen zwischen den Feldern gibt. Viele Textdateien verwenden 1 oder mehr Leerzeichen (und/oder Tabulatoren und/oder andere Leerzeichen) als Feldtrennzeichen und können nicht einfach mit verarbeitet werdencut
. Verwenden Sie stattdessenawk
oderperl
.Ihre Verwendung von
cut -c 9-15
führt dazu, dass mindestens ein zusätzliches Leerzeichen in $PID erfasst wird. Um eine PID aus zu extrahierenps -ef
, verwenden Sieawk '{print $2}'
anstelle voncut -c 9-15
.Verwenden Sie diese Option
pgrep "$APP_NAME"
, um die PID eines Prozesses nach Namen abzurufen. Oderpgrep -f "$APP_NAME"
wenn die gesuchte Zeichenfolge ein Argument ist (z. B. wenn der Name des Skripts als Argument an einen Interpreter übergeben wird).Cargo-Kult
ps | grep ... | grep -v grep
ist seit Jahrzehnten überholt – und war ohnehin nie eine gute Methode dafür.ps -ef | awk '/[p]rocess_name/ {print $2}'
war immer eine bessere Methode (das Setzen eines[]
um das erste Zeichen des Musters verhindert, dass awk, grep oder was auch immer sich selbst in der ps-Ausgabe zuordnet), aber selbst das ist mittlerweile mit überholtpgrep
.ps
selbst verfügt über eine-C
Option zum Abgleichen von Prozessnamen und eineh
Option zum Unterdrücken von Headern sowie-o
zum Angeben der gewünschten Ausgabeps
. zBps h -o pid -C "$APP_NAME"
Um das alles zusammenzufassen, verwenden Sie:
PID=$(pgrep "$APP_NAME")
or
PID=$(pgrep -f "$APP_NAME")
or
PID=$(ps h -o pid -C "$APP_NAME")
Übrigens, wenn esbeliebigpgrep
Die Wahrscheinlichkeit, dass mehrere PIDs von oder zurückgegeben werden ps
, sollten Sie die Ausgabe in einem Array erfassen, nicht in einer Skalarvariable. Im Folgenden werden beispielsweise die PIDs aller sichtbaren Bash-Prozesse in dem Array erfasst $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")
Wenn Sie sie aus irgendeinem Grund alle töten möchten, können Sie dies folgendermaßen tun:
kill "${BASHPIDS[@]}"
Antwort2
dieser Befehl behebt das Problem:
echo "${PID}" | xargs kill -9