Ahora estoy usando este script para reiniciar mi proceso:
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
pero cuando ejecuto este script en un servidor remoto desde GitHub Actions, muestra este error:
======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
este es el guión completo de 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
Intenté modificar el comando del proceso de eliminación de esta manera (los xargs recortan el espacio en blanco de pid) para eliminar los espacios de pid:
echo "${PID}" | xargs | kill -9
me dice:
err: /opt/apps/dolphin-acientbay/libs/upgrade.sh:kill:19: not enough arguments
Respuesta1
Aquí está la fuente de su problema:
PID=`ps -ef|grep -w ${APP_NAME}|grep -v grep|cut -c 9-15`
Entrecomilla dos veces tus variables cuando las uses. por ejemplo, "$APP_NAME" o "${APP_NAME}".
Por cierto, las llaves solo son necesarias cuando necesita eliminar la ambigüedad de una variable de otro texto en una cadena. por ejemplo, si la variable fuera realmente
$APP
pero necesitara usarla en una cadena con_NAME
, usaría"${APP}_NAME"
- eso evitaría_NAME
que el shell la interprete como parte del nombre de la variable.Estás usando comillas invertidas en lugar de
$()
. Han estado en desuso durante años y por una buena razón. No son la causa del problema aquí, sólo un mal hábito que debes dejar.cut
no es una buena herramienta para extraer campos que puedan estar delimitados por 1 o más caracteres. Sólo es bueno cuando hay un (y exactamente uno) delimitador entre campos. Muchos archivos de texto utilizan 1 o más espacios (y/o tabulaciones y/u otros caracteres de espacios en blanco) como delimitadores de campo y no se pueden procesar fácilmente concut
. Utiliceawk
operl
en su lugar.Su uso de
cut -c 9-15
está provocando que se capture al menos un carácter de espacio adicional en $PID. Para extraer un PID deps -ef
, utiliceawk '{print $2}'
en lugar decut -c 9-15
.Úselo
pgrep "$APP_NAME"
para obtener el PID de un proceso por nombre. Opgrep -f "$APP_NAME"
si la cadena que está buscando es un argumento (por ejemplo, cuando el nombre del script se pasa como argumento a un intérprete).El culto a la carga
ps | grep ... | grep -v grep
ha quedado obsoleto desde hace décadas y, de todos modos, nunca fue una buena forma de hacerlo.ps -ef | awk '/[p]rocess_name/ {print $2}'
Siempre fue una mejor manera (poner un[]
alrededor del primer carácter del patrón evita que awk, grep o lo que sea coincida en la salida de ps), pero incluso eso ahora está obsoleto conpgrep
.ps
en sí mismo tiene una-C
opción para hacer coincidir nombres de procesos y unah
opción para suprimir encabezados y-o
especificar de qué salida deseaps
. p.ejps h -o pid -C "$APP_NAME"
Para resumir todo eso, use:
PID=$(pgrep "$APP_NAME")
or
PID=$(pgrep -f "$APP_NAME")
or
PID=$(ps h -o pid -C "$APP_NAME")
Por cierto, si haycualquierpgrep
posibilidad de que o devuelva múltiples PID ps
, debe capturar la salida en una matriz, no en una variable escalar. Por ejemplo, lo siguiente capturará los PID de todos los procesos bash visibles en la matriz $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")
Si, por alguna razón, quisieras matarlos a todos, podrías hacerlo con:
kill "${BASHPIDS[@]}"
Respuesta2
este comando soluciona el problema:
echo "${PID}" | xargs kill -9