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 pgrep
así:
if ! pgrep -u $USER top >/dev/null 2>&1; then
exec top
fi
Explicación:
- La
pgrep
utilidad 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.$USER
es una variable de shell estándar. Si por alguna razón no está definido, intente usar$LOGNAME
en su lugar, y si falla, use$( id -n -u )
(pero en ese punto debe preguntarse qué está pasando, porque$LOGNAME
estambié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, exec
reemplace el Shell, según la pregunta del OP.
Esto debería funcionar en todos sh
los shells compatibles.
EDITAR: La pgrep
implementación en sistemas BSD (OS X, OpenBSD, ...) tiene una -q
opción que hace descartar cualquier salida, pero pgrep
en 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 lockfile
o flock
. Por ejemplo añadiendo
flock -n /tmp/top -c top
a .bashrc
/ .zshrc
se asegurará de que solo la primera instancia del shell ejecute el top
comando (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 mytop
cuando quieras.
Respuesta3
Si bien estamos de acuerdo en que ese pgrep
es el camino a seguir, existen algunos obstáculos. No necesitas usar la -q
opción, ya que puedes redirigir la salida de pgrep
para 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 USER
variable 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 USER
es 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 top
comotú mismo, por supuesto. Si eliges hacerlo funcionar comoraíz, entonces podrías cambiar $USER
a root
y luego ejecutar top
usando sudo
(preferido) o su
. Tampoco está en POSIX (ver lista). Este último ( su
) está disponible en todos los sistemas tipo Unix, pero sudo
generalmente es el preferido. Entonces tendrías
pgrep -U root top >/dev/null || exec sudo top
A menos que haya configurado sudo
para 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.