почему мне говорят недопустимый pid когда убиваешь процесс

почему мне говорят недопустимый pid когда убиваешь процесс

Теперь я использую этот скрипт для перезапуска моего процесса:

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

Я попытался настроить команду kill process следующим образом (xargs обрезает пробелы pid), чтобы удалить пробелы 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`
  1. При использовании переменных заключайте их в двойные кавычки, например, «$APP_NAME» или «${APP_NAME}».

    Кстати, фигурные скобки нужны только тогда, когда вам нужно отделить переменную от другого текста в строке. Например, если бы переменная на самом деле была, $APPно вам нужно было бы использовать ее в строке с _NAME, вы бы использовали "${APP}_NAME"- , что предотвратило бы _NAMEинтерпретацию оболочкой как части имени переменной.

  2. Вы используете обратные кавычки вместо $(). Они уже много лет устарели, и на то есть веская причина. Они не являются причиной проблемы, просто это плохая привычка, от которой нужно избавиться.

  3. cutне является хорошим инструментом для извлечения полей, которые могут быть разделены 1 или более символами. Он хорош только в том случае, если между полями есть один (и ровно один) разделитель. Многие текстовые файлы используют 1 или более пробелов (и/или табуляций и/или других пробельных символов) в качестве разделителей полей и не могут быть легко обработаны с помощью cut. Вместо этого используйте awkили perl.

    Ваше использование cut -c 9-15приводит к тому, что в $PID захватывается как минимум один дополнительный символ пробела. Чтобы извлечь PID из ps -ef, используйте awk '{print $2}'вместо cut -c 9-15.

  4. Используйте pgrep "$APP_NAME"для получения PID процесса по имени. Или pgrep -f "$APP_NAME"если искомая строка является аргументом (например, когда имя скрипта передается интерпретатору как аргумент).

    Культ карго ps | grep ... | grep -v grepустарел уже несколько десятилетий назад и никогда не был хорошим способом сделать это, в любом случае. ps -ef | awk '/[p]rocess_name/ {print $2}'всегда был лучшим способом (помещение a []вокруг первого символа шаблона не позволяет 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")

Кстати, если естьлюбойвероятность возврата нескольких PID с помощью pgrepили ps, вам следует захватить вывод в массив, а не в скалярную переменную. Например, следующий код захватит PID всех видимых процессов bash в массив $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

Связанный контент