Obtención de PID del comando anteriormente en Pipeline

11

Estoy escribiendo un script bash para usar inotifywaitpara monitorear un directorio y comenzar acciones cuando se detectan cambios. Algo como:

inotifywait -m ... | while read f; do something; done

Como inotifywaitno termina por sí solo, este script no se detendrá.

Entonces, mi plan era obtener el PID del proceso inotifywait, guardarlo en un archivo y hacer que un proceso diferente lo elimine más tarde, digamos como:

inotifywait -m ... | { echo ??PID?? > pid-file; while ... }

Pero no sé cómo obtener el PID. ¿Hay una manera simple de lograr esto? Otra forma es simplemente guardar el PID del script de shell $$en el archivo y eliminar todo el script de shell, pero quería hacer un poco de limpieza después del ciclo while.

He intentado usar coprocy creo que funcionará, pero parece más complicación de la necesaria.

Adrian Pronk
fuente
Podrías usar algo como esto `ps -ef | grep processName | grep -v grep | awk '{print $ 2}' | xargs kill -9 `
Kiwy
@ Kiwy - en lugar de ese desastre, solo haz un pgrep inotifywait. Eso le dará el PID, para matar, pkill inotifwait.
slm
@slm dependiendo de su sistema, no tendrá pgrep y pkill mientras grep y ps estarán casi presentes. De
nada
@Kiwy: dudoso, esas herramientas son bastante ubicuas. Además, no necesita hacer un grep -v grep, en su lugar ps -ef | grep [p]rocessname...haría lo mismo.
slm
1
@DavidsonChua: sí, puede usar el -finterruptor si necesita hacer coincidir más nombres de ejecutables.
slm

Respuestas:

6

En una tubería, todos los procesos se inician simultáneamente , no hay uno que sea anterior a los demás.

Podrías hacerlo:

(echo "$BASHPID" > pid-file; exec inotifywait -m ...) | while IFS= read -r...

O portablemente:

sh -c 'echo "$$" > pid-file; exec inotifywait -m ...' | while IFS= read -r...

También tenga en cuenta que cuando la subshell que ejecuta el whileciclo termina, inotifywaitse eliminará automáticamente la próxima vez que escriba algo en stdout.

Stéphane Chazelas
fuente
3

Si necesita el ID del proceso en el bucle, imprímalo primero.

sh -c 'echo "$$"; exec inotifywait -m ...' | {
  read inotifywait_pid
  while IFS= read -r f; do
    
    if …; then kill "$inotifywait_pid"; break;
  done
}
Gilles 'SO- deja de ser malvado'
fuente
1

Esta respuesta SO parece aplicable:

inotifywait -m file > >(while read f; do echo f; done) &
Aryeh Leib Taurog
fuente