He escrito un script de shell para monitorear un directorio usando la utilidad inotifywait de inotifyt-tools. Quiero que ese script se ejecute continuamente en segundo plano, pero también quiero poder detenerlo cuando lo desee.
Para hacerlo funcionar continuamente, solía while true
; Me gusta esto:
while true;
do #a set of commands that use the inotifywait utility
end
Lo guardé en un archivo /bin
y lo hice ejecutable. Para que se ejecute en segundo plano, utilicé nohup <script-name> &
y cerré el terminal.
No sé cómo detengo este script. He visto las respuestas aquí y una pregunta muy relacionada aquí .
ACTUALIZACIÓN 1: Sobre la base de la respuesta de @InfectedRoot a continuación, he podido resolver mi problema utilizando la siguiente estrategia. Primer uso
ps -aux | grep script_name
y usar sudo kill -9 <pid>
para matar los procesos. Luego tuve que pgrep inotifywait
usarlo sudo kill -9 <pid>
nuevamente para la identificación devuelta.
Esto funciona, pero creo que este es un enfoque desordenado, estoy buscando una mejor respuesta.
ACTUALIZACIÓN 2: La respuesta consiste en matar 2 procesos . Esto es importante porque al ejecutar el script en la línea de comando se inician 2 procesos, 1 el script en sí y 2, el proceso de inotificación .
-9
opciónkill
y usarla solokill
eliminará el desorden.-9
opción sería totalkill
aquí. : Pkill
que el prefijo de la pgid con un signo menos:kill -- -<pgid>
,kill -9 -<pgid>
, etc.Respuestas:
Para mejorar, usar
killall
y también combinar los comandos:O haga todo en una línea:
fuente
Error: no process
debería significar que ya lo has matado. Puede probarlo abriendo otros dos programas, como VLC y Geany , y probándolo con ellos.grep -v grep
convirtiéndosegrep script_name
engrep -e "[s]cript_name"
.Enumerar los trabajos en segundo plano utilizando
# jobs
Luego elija el número de trabajo anterior y ejecute
ejemplo
traerá a primer plano.
Luego mátelo usando CTRL + C o una forma más fácil de encontrar el PID del script usando
Luego mata usando pid
fuente
jobs
comando realmente solo mostraba los trabajos en ejecución mientras estaba en el shell. Una vez que cerré una cierta ventana de terminal, la única forma de acceder a ellos fue a través deps
(ver más arriba para eso). Entonces es seguro que no estás inventando esto.Puede usar
ps
+grep
opgrep
para obtener el nombre del proceso / pid ; luego usekillall
/pkill
para matar el nombre del proceso o usekill
para matar pid. Todos los siguientes deberían funcionar.Lo más importante es que debe asegurarse de matar solo los procesos exactos que espera matar.
pkill
/pgrep
coincide con un patrón en lugar del nombre exacto , por lo que es más peligroso; aquí-x
se agrega para que coincida con el nombre exacto.Además, cuando use
pgrep
/pkill
puede necesitar-f
para que coincida con la línea de comando completa (como lops aux
hace)-a
para imprimir también el nombre del proceso.fuente
pgrep
/pkill
. Si eso sigue mal, puede intentarpgrep
sin -x. Básicamente, no creo que sea bueno matar el proceso dentro de un comando de línea sin verificar si otros procesos coinciden.Como probablemente pueda ver, hay muchas maneras de hacer esto.
Con respecto a su "ACTUALIZACIÓN # 2" - en términos generales, la terminación de cualquier proceso en una jerarquía padre-hijo generalmente terminará todos los procesos asociados. Pero hay muchas excepciones a esto. Idealmente, desea terminar el 'hijo' final en un árbol de procesos, luego los padres de este hijo deberían salir si no tienen otras tareas para ejecutar. Pero si matas a un padre, la señal debe transmitirse a los niños cuando el padre muere y los niños también deben salir, pero hay casos en los que los procesos hijos pueden ignorar la señal (a través de trampas o mecanismos similares) y pueden continuar ejecutar un proceso será heredado por el proceso 'init' (o similar). Pero este tema del comportamiento del proceso puede volverse complejo y lo dejaré allí ...
Un método que me gusta si no quiero usar un script de control (descrito a continuación) es usar la utilidad 'pantalla' para iniciar y administrar el proceso. El comando 'pantalla' está lleno de funciones y puede tomar algún tiempo dominarlo. Te animo a leer la página de manual de 'pantalla' para obtener una explicación completa. Un ejemplo rápido para iniciar un proceso en segundo plano sería el comando:
pantalla -d -m / ruta / a / programa
Esto iniciará "/ ruta / a / programa" dentro de una sesión de 'pantalla'.
Puedes ver tu sesión de carrera con el comando:
pantalla -ls
Y en cualquier momento puede volver a conectarse a su programa en ejecución con el comando:
pantalla -r
Y luego simplemente termine con un ^ C o lo que sea.
Además de la belleza de poder reconectarse y desconectarse de su proceso a voluntad, esa 'pantalla' capturará cualquier stdout () que su programa pueda producir.
Pero mi preferencia personal en estos asuntos es tener un programa de control que gestione el inicio y la detención de un proceso. Esto puede ser algo complicado y requiere algunas secuencias de comandos posiblemente complicadas. Y como cualquier guión, hay docenas de buenas maneras de hacerlo. He incluido un ejemplo bash de un método que uso habitualmente para iniciar y detener aplicaciones. Si su tarea es simple, puede insertarla directamente en el script de control, o puede hacer que este script de control llame a otro programa externo. Tenga en cuenta que este ejemplo no es exhaustivo en términos de gestión del proceso. He omitido la posibilidad de escenarios como: Asegurarse de que el script no se esté ejecutando cuando usa la opción "inicio", validar que el PID en ejecución es en realidad el proceso que inició (por ejemplo, su script no t murió y se inició otro proceso usando el mismo PID), y validando que el script realmente respondió (salió) en la primera solicitud 'kill'. Hacer todas estas comprobaciones puede ser complicado y no quería que el ejemplo fuera demasiado largo y complejo. Es posible que desee modificar el ejemplo para practicar sus scripts de shell.
Guarde el siguiente código en un archivo llamado "programctl", hágalo ejecutable con el comando:
chmod 755 programctl
Luego edite el archivo y agregue su código / script en la sección de caso que comienza con "myscript".
Una vez que todo esté en su lugar, suponiendo que "programctl" esté en el directorio actual, puede comenzar su programa con:
./programctl start
Y para con:
./programctl stop
Salud.
fuente