scripts script resueltos programas paso pasar parametros manejo hacer español ejercicios ejemplos como cadenas bash

bash - programas - scripts linux ejercicios resueltos



script bash para verificar el proceso en ejecución (15)

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