Отримання PID команди раніше в Pipeline


11

Я пишу bash-скрипт, який слід використовувати inotifywaitдля моніторингу каталогу та запуску дій, коли виявляються зміни. Щось на зразок:

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

Оскільки inotifywaitцей сценарій не закінчується сам по собі, цей сценарій не зупиниться.

Тож мій план полягав у тому, щоб отримати PID процесу inotifywait, зберегти його у файл та іншим процесом вбити його пізніше, скажімо так:

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

Але я не знаю, як отримати PID. Чи є простий спосіб цього досягти? Інший спосіб просто зберегти PID оболонки-скрипта $$в файл і вбити всю оболонку-скрипт , але я хотів би зробити деякі очищення після циклу While.

Я намагався використовувати, coprocі я думаю, що це спрацює, але це здається більш складним, ніж необхідним.


Ви можете використовувати щось подібне `ps -ef | grep processName | grep -v grep | awk '{print $ 2}' | xargs kill -9 `
Kiwy

@Kiwy - замість цього безладу просто роби pgrep inotifywait. Це дасть вам PID, щоб убити pkill inotifwait.
slm

@slm залежно від вашої системи у вас не буде pgrep і pkill, поки grep і ps поки майже не буде присутній. Ласкаво просимо
Kiwy

@Kiwy - сумнівно, ці інструменти досить всюдисущі. Також вам не потрібно робити це grep -v grep, замість ps -ef | grep [p]rocessname...цього зробите те саме.
slm

1
@DavidsonChua - так, ви можете використовувати -fкомутатор, якщо вам потрібно відповідати більшості імен виконуваних файлів.
slm

Відповіді:


6

У трубопроводі всі процеси запускаються одночасно , не існує жодного, який є раніше, ніж інші.

Ви можете зробити:

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

Або портативно:

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

Також зауважте, що коли підзарядка, яка виконує whileцикл, припиняється, inotifywaitбуде автоматично вбита наступного разу, коли вона пише щось для stdout.


3

Якщо вам потрібен ідентифікатор процесу в циклі, спочатку надрукуйте його.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.