warum wird mir beim Beenden des Prozesses eine illegale PID angezeigt?

warum wird mir beim Beenden des Prozesses eine illegale PID angezeigt?

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`
  1. 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, $APPSie sie aber in einem String mit verwenden müssten _NAME, würden Sie "${APP}_NAME"- verwenden. Dadurch würde verhindert, dass _NAMEdie Shell sie als Teil des Variablennamens interpretiert.

  2. 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.

  3. cutist 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 werden cut. Verwenden Sie stattdessen awkoder perl.

    Ihre Verwendung von cut -c 9-15führt dazu, dass mindestens ein zusätzliches Leerzeichen in $PID erfasst wird. Um eine PID aus zu extrahieren ps -ef, verwenden Sie awk '{print $2}'anstelle von cut -c 9-15.

  4. Verwenden Sie diese Option pgrep "$APP_NAME", um die PID eines Prozesses nach Namen abzurufen. Oder pgrep -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 grepist 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 überholt pgrep.

    psselbst verfügt über eine -COption zum Abgleichen von Prozessnamen und eine hOption zum Unterdrücken von Headern sowie -ozum Angeben der gewünschten Ausgabe ps. 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 esbeliebigpgrepDie 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

verwandte Informationen