bash - programas - scripts linux ejercicios resueltos
script bash para verificar el proceso en ejecución (15)
Esta pregunta ya tiene una respuesta aquí:
Escribí un script bash para verificar si un proceso se está ejecutando. No funciona, ya que el comando ps siempre devuelve el código de salida 1. Cuando ejecuto el comando ps desde la línea de comandos, el $? está configurado correctamente, pero dentro del script siempre es 1. ¿Alguna idea?
#!/bin/bash
SERVICE=$1
ps -a | grep -v grep | grep $1 > /dev/null
result=$?
echo "exit code: ${result}"
if [ "${result}" -eq "0" ] ; then
echo "`date`: $SERVICE service running, everything is fine"
else
echo "`date`: $SERVICE is not running"
fi
Versión Bash: GNU bash, versión 3.2.25 (1) - liberación (x86_64-redhat-linux-gnu)
A pesar de cierto éxito con el enfoque / dev / null en bash. Cuando presioné la solución para cron, falló. Sin embargo, comprobar el tamaño de un comando devuelto funcionó perfectamente. El ampersrand permite a bash salir.
#!/bin/bash
SERVICE=/path/to/my/service
result=$(ps ax|grep -v grep|grep $SERVICE)
echo ${#result}
if ${#result}> 0
then
echo " Working!"
else
echo "Not Working.....Restarting"
/usr/bin/xvfb-run -a /opt/python27/bin/python2.7 SERVICE &
fi
Debo hacer esto de vez en cuando y terminar pirateando la línea de comandos hasta que funcione.
Por ejemplo, aquí quiero ver si tengo alguna conexión SSH, (la octava columna devuelta por "ps" es la "ruta-a-nombre-de-proceso" en ejecución y está filtrada por "awk":
ps | awk -e ''{ print $8 }'' | grep ssh | sed -e ''s/.*////g''
Luego lo puse en un script de shell, ("eval" -ing la línea de comando dentro de los backticks), así:
#!/bin/bash
VNC_STRING=`ps | awk -e ''{ print $8 }'' | grep vnc | sed -e ''s/.*////g''`
if [ ! -z "$VNC_STRING" ]; then
echo "The VNC STRING is not empty, therefore your process is running."
fi
La parte "sed" recorta el camino al token exacto y puede que no sea necesario para sus necesidades.
Aquí está mi ejemplo. Solía obtener su respuesta. Lo escribí para crear automáticamente 2 túneles SSH y lanzar un cliente VNC para cada uno.
Lo ejecuto desde mi shell Cygwin para hacer el administrador en mi backend desde mi estación de trabajo de windows, así que puedo saltar a UNIX / LINUX-land con un comando, (esto también asume que las claves rsa del cliente ya han sido "ssh-copy-id" -ed y son conocidos por el host remoto).
Es idempotente en que cada comando / proceso solo se dispara cuando sus $ VAR eval a una cadena vacía.
Agrega "| wc -l" para almacenar el número de procs en ejecución que coinciden, (es decir, el número de líneas encontradas), en lugar de proc-name para cada $ VAR para satisfacer mis necesidades. Guardo las declaraciones de "eco" para poder volver a ejecutar y diagnosticar el estado de ambas conexiones.
#!/bin/bash
SSH_COUNT=`eval ps | awk -e ''{ print $8 }'' | grep ssh | sed -e ''s/.*////g'' | wc -l`
VNC_COUNT=`eval ps | awk -e ''{ print $8 }'' | grep vnc | sed -e ''s/.*////g'' | wc -l`
if [ $SSH_COUNT = "2" ]; then
echo "There are already 2 SSH tunnels."
elif [ $SSH_COUNT = "1" ]; then
echo "There is only 1 SSH tunnel."
elif [ $SSH_COUNT = "0" ]; then
echo "connecting 2 SSH tunnels."
ssh -L 5901:localhost:5901 -f -l USER1 HOST1 sleep 10;
ssh -L 5904:localhost:5904 -f -l USER2 HOST2 sleep 10;
fi
if [ $VNC_COUNT = "2" ]; then
echo "There are already 2 VNC sessions."
elif [ $VNC_COUNT = "1" ]; then
echo "There is only 1 VNC session."
elif [ $VNC_COUNT = "0" ]; then
echo "launching 2 vnc sessions."
vncviewer.exe localhost:1 &
vncviewer.exe localhost:4 &
fi
Esto es muy similar a mí y posiblemente más utilidades de Unix que el verdadero script de shell. Sé que hay muchos números "MAGIC" y cheezy hard-coded values pero funciona, (creo que también soy de mal gusto para usar tanto UPPERCASE). Se puede agregar flexibilidad con algunos args de línea de cmd para hacer esto más versátil, pero quería compartir lo que funcionó para mí. Por favor, mejora y comparte. Aclamaciones.
Encontré el problema. ps -ae en cambio ps-funciona.
Supongo que tiene que ver con mis derechos en el entorno de alojamiento compartido. Aparentemente hay una diferencia entre ejecutar "ps -a" desde la línea de comando y ejecutarlo desde dentro de un bash-script.
Esas son sugerencias útiles. Solo necesitaba saber si un servicio se estaba ejecutando cuando comencé el script, para poder dejar el servicio en el mismo estado cuando me fui. Terminé usando esto:
HTTPDSERVICE=$(ps -A | grep httpd | head -1)
[ -z "$HTTPDSERVICE" ] && echo "No apache service running."
Este truco funciona para mí. Espero que esto pueda ayudarte. Guardemos los siguientes como checkRunningProcess.sh
#!/bin/bash
ps_out=`ps -ef | grep $1 | grep -v ''grep'' | grep -v $0`
result=$(echo $ps_out | grep "$1")
if [[ "$result" != "" ]];then
echo "Running"
else
echo "Not Running"
fi
Haga el ejecutable checkRunningProcess.sh.Y luego úselo.
Ejemplo de uso.
20:10 $ checkRunningProcess.sh proxy.py
Running
20:12 $ checkRunningProcess.sh abcdef
Not Running
Hay algunos métodos realmente simples:
pgrep procname && echo Running
pgrep procname || echo Not running
killall -q -0 procname && echo Running
pidof procname && echo Running
Intenté su versión en BASH versión 3.2.29, funcionó bien. Sin embargo, puedes hacer algo como lo sugerido anteriormente, un ejemplo aquí:
#!/bin/sh
SERVICE="$1"
RESULT=`ps -a | sed -n /${SERVICE}/p`
if [ "${RESULT:-null}" = null ]; then
echo "not running"
else
echo "running"
fi
La comprobación más simple por nombre de proceso:
bash -c ''checkproc ssh.exe ; while [ $? -eq 0 ] ; do echo "proc running";sleep 10; checkproc ssh.exe; done''
Me preguntaba si sería una buena idea tener intentos progresivos en un proceso, por lo que le pasas a esta función un nombre de proceso func_terminate_process "firefox" y primero calienta las cosas más bien, luego pasa a matar.
# -- NICE: try to use killall to stop process(s)
killall ${1} > /dev/null 2>&1 ;sleep 10
# -- if we do not see the process, just end the function
pgrep ${1} > /dev/null 2>&1 || return
# -- UGLY: Step trough every pid and use kill -9 on them individually
for PID in $(pidof ${1}) ;do
echo "Terminating Process: [${1}], PID [${PID}]"
kill -9 ${PID} ;sleep 10
# -- NASTY: If kill -9 fails, try SIGTERM on PID
if ps -p ${PID} > /dev/null ;then
echo "${PID} is still running, forcefully terminating with SIGTERM"
kill -SIGTERM ${PID} ;sleep 10
fi
done
# -- If after all that, we still see the process, report that to the screen.
pgrep ${1} > /dev/null 2>&1 && echo "Error, unable to terminate all or any of [${1}]" || echo "Terminate process [${1}] : SUCCESSFUL"
Trabajando uno.
!/bin/bash CHECK=$0 SERVICE=$1 DATE=`date` OUTPUT=$(ps aux | grep -v grep | grep -v $CHECK |grep $1) echo $OUTPUT if [ "${#OUTPUT}" -gt 0 ] ; then echo "$DATE: $SERVICE service running, everything is fine" else echo "$DATE: $SERVICE is not running" fi
Una solución con service
y awk
que service
una lista de nombres de servicio delimitada por comas.
Primero, probablemente sea una buena apuesta que necesitarás privilegios de root para hacer lo que quieras. Si no necesita verificar, puede eliminar esa parte.
#!/usr/bin/env bash
# First parameter is a comma-delimited string of service names i.e. service1,service2,service3
SERVICES=$1
ALL_SERVICES_STARTED=true
if [ $EUID -ne 0 ]; then
if [ "$(id -u)" != "0" ]; then
echo "root privileges are required" 1>&2
exit 1
fi
exit 1
fi
for service in ${SERVICES//,/ }
do
STATUS=$(service ${service} status | awk ''{print $2}'')
if [ "${STATUS}" != "started" ]; then
echo "${service} not started"
ALL_SERVICES_STARTED=false
fi
done
if ${ALL_SERVICES_STARTED} ; then
echo "All services started"
exit 0
else
echo "Check Failed"
exit 1
fi
Una versión de script simple de una de las sugerencias anteriores de Andor:
!/bin/bash
pgrep $1 && echo Running
Si el script anterior se llama test.sh, entonces, para probar, escriba: test.sh NameOfProcessToCheck
por ejemplo test.sh php
Utilizo este para verificar que cada 10 segundos el proceso se esté ejecutando y comience si no y permite múltiples argumentos:
#!/bin/sh
PROCESS="$1"
PROCANDARGS=$*
while :
do
RESULT=`pgrep ${PROCESS}`
if [ "${RESULT:-null}" = null ]; then
echo "${PROCESS} not running, starting "$PROCANDARGS
$PROCANDARGS &
else
echo "running"
fi
sleep 10
done
Verifica si el nombre de tus scripts no contiene $ SERVICE. Si lo hace, se mostrará en los resultados de ps, haciendo que el script siempre piense que el servicio se está ejecutando. Puedes grep contra el nombre de archivo actual de esta manera:
#!/bin/sh
SERVICE=$1
if ps ax | grep -v grep | grep -v $0 | grep $SERVICE > /dev/null
then
echo "$SERVICE service running, everything is fine"
else
echo "$SERVICE is not running"
fi
#!/bin/bash ps axho comm| grep $1 > /dev/null result=$? echo "exit code: ${result}" if [ "${result}" -eq "0" ] ; then echo "`date`: $SERVICE service running, everything is fine" else echo "`date`: $SERVICE is not running" /etc/init.d/$1 restart fi
Algo como esto