Obtendo o PID do comando anteriormente no Pipeline


11

Estou escrevendo um script bash inotifywaitpara monitorar um diretório e iniciar ações quando alterações são detectadas. Algo como:

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

Como inotifywaitnão termina sozinho, esse script não será interrompido.

Portanto, meu plano era obter o PID do processo inotifywait, salvá-lo em um arquivo e fazer com que um processo diferente o matasse posteriormente, digamos:

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

Mas não sei como obter o PID. Existe uma maneira simples de conseguir isso? Outra maneira é salvar o PID do script de shell $$no arquivo e matar o script de shell inteiro, mas eu queria fazer uma limpeza após o loop while.

Eu tentei usar coproce acho que vai funcionar, mas parece mais complicação do que o necessário.


Você pode usar algo parecido com isto `ps -ef | grep processName | grep -v grep | awk '{print $ 2}' | xargs kill -9 `
Kiwy

@ Kiwy - em vez dessa bagunça, basta fazer um pgrep inotifywait. Isso lhe dará o PID, para matar pkill inotifwait,.
slm

@ slm, dependendo do seu sistema, você não terá o pgrep e o pkill enquanto o grep e o ps estiverem quase presentes. Você é bem
Kiwy

@ Kiwy - duvidoso, essas ferramentas são bastante onipresentes. Além disso, você não precisa fazer a grep -v grep, mas ps -ef | grep [p]rocessname...faria o mesmo.
slm

1
@ DavididsonChua - sim, você pode usar a -fopção se precisar comparar com mais nomes dos executáveis.
slm

Respostas:


6

Em um pipeline, todos os processos são iniciados simultaneamente , não há um que seja anterior aos outros.

Você poderia fazer:

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

Ou portably:

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

Observe também que quando o subshell que executa o whileloop terminar, inotifywaitele será eliminado automaticamente na próxima vez em que gravar algo no stdout.


3

Se você precisar do ID do processo no loop, imprima-o primeiro.

sh -c 'echo "$$"; exec inotifywait -m ...' | {
  read inotifywait_pid
  while IFS= read -r f; do
    
    if …; then kill "$inotifywait_pid"; break;
  done
}

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.