¿Cómo puedo determinar si un programa se está ejecutando cuando inicio un shell e inicio ese programa si aún no se está ejecutando?

¿Cómo puedo determinar si un programa se está ejecutando cuando inicio un shell e inicio ese programa si aún no se está ejecutando?

Cuando inicio un shell, en mi caso bash y/o zsh, ¿qué líneas necesito agregar a .zshrc y/o .bashrc para verificar si un programa ya se está ejecutando y si el programa aún no se está ejecutando? ¿iniciarlo?

Ejemplo: estoy iniciando un nuevo shell zsh. Si top aún no se está ejecutando, me gustaría iniciar top y hacer que se haga cargo del shell. Si top ya se está ejecutando en otra ventana, me gustaría que .zshrc continúe cargándose y me proporcione una terminal abierta.

6-16 Actualización:

if ! pgrep -U $USER top >/dev/null; then
exec top
fi

El script anterior satisface mi solicitud. El indicador -q no funcionaría para mí porque -q no es una opción en mi sistema. Así que tuve que canalizar el PID a /dev/null. Gracias mveroone, Kusalananda y Thomas Dickey.

Tengo algunas características que están fuera del alcance de la pregunta original. Supongamos que estoy en un sistema de usuario único donde puedo convertirme en root sin necesidad de ingresar una contraseña. ¿Cómo ejecutaría automáticamente top como root si fuera necesario?

6-18 Ok, el problema de la función de pasar un comando como root está resuelto. Estoy usando esto para lanzar varios

Gracias por todas las reflexivas respuestas.

Respuesta1

Úselo pgrepasí:

if ! pgrep -u $USER top >/dev/null 2>&1; then
    exec top
fi

Explicación:

  • La pgreputilidad sale con un código de salida cero si el comando se encuentra ejecutándose. Por lo tanto, niega la prueba.
  • También restrinjalo al usuario actual con -u $USER, para que, por algún motivo, no retome los procesos de otra persona. $USERes una variable de shell estándar. Si por alguna razón no está definido, intente usar $LOGNAMEen su lugar, y si falla, use $( id -n -u )(pero en ese punto debe preguntarse qué está pasando, porque $LOGNAMEestambiénuna variable de shell estándar).
  • No necesitamos la salida de pgrep, así que redirija la salida estándar y los flujos de error a /dev/null.

Si top(o lo que sea) no se está ejecutando, execreemplace el Shell, según la pregunta del OP.

Esto debería funcionar en todos shlos shells compatibles.

EDITAR: La pgrepimplementación en sistemas BSD (OS X, OpenBSD, ...) tiene una -qopción que hace descartar cualquier salida, pero pgrepen Linux aparentemente no tiene este indicador. En sistemas BSD, utilice esto en lugar de la redirección ligeramente fea a /dev/null.

Respuesta2

Si el programa siempre se inicia desde el shell y usted tiene control total sobre él (es decir, no está codificado dentro de un programa de terceros), entonces puede usar algún mecanismo de bloqueo como lockfileo flock. Por ejemplo añadiendo

flock -n /tmp/top -c top

a .bashrc/ .zshrcse asegurará de que solo la primera instancia del shell ejecute el topcomando (a menos que lo elimine, luego se iniciará otra).

Es posible que desee crear una función para poder iniciar el comando también manualmente (no solo cuando se inicializa el shell):

mytop () { flock -n /tmp/$0 -c top; }

Y simplemente corre mytopcuando quieras.

Respuesta3

Si bien estamos de acuerdo en que ese pgrepes el camino a seguir, existen algunos obstáculos. No necesitas usar la -qopción, ya que puedes redirigir la salida de pgreppara eliminar eso:

pgrep -U $USER top >/dev/null || exec top

Los inconvenientes radican en el hecho de que no es una utilidad estándar, por lo que hay que tener en cuenta que puede que no sea portátil. Aquí hay algunos enlaces a páginas de manual para ayudar:

La USERvariable de entorno está mejor establecida, pero no parece estar en la lista de POSIX para el shell (consulte2.5.3 Variables del shell). Más bien, señala que USERes una de las muchas variables que se sabe que están en uso (ver nota en8.1 Definición de variable de entorno).

Esto se ejecuta topcomotú mismo, por supuesto. Si eliges hacerlo funcionar comoraíz, entonces podrías cambiar $USERa rooty luego ejecutar topusando sudo(preferido) o su. Tampoco está en POSIX (ver lista). Este último ( su) está disponible en todos los sistemas tipo Unix, pero sudogeneralmente es el preferido. Entonces tendrías

pgrep -U root top >/dev/null || exec sudo top

A menos que haya configurado sudopara no requerir una contraseña, se le solicitará una contraseña cuando se inicie su shell top.

Respuesta4

Yo agregaría un fragmento como este en mi .zshrc (u otro):

si pgrep -u $USUARIO nombre_programa
entonces
    nombre_programa ejecutivo
fi

Advertencia :No he probado este código. No lo use en root o en el único usuario que tiene en un servidor. Asegúrese de poder recuperarse si falla.

información relacionada