Как получить PID процесса, который передается другому процессу в Bash? - PullRequest
47 голосов
/ 31 октября 2009

Я пытаюсь реализовать простой сервер журналов в Bash. Он должен принимать файл в качестве параметра и передавать его через порт с помощью netcat.

( tail -f $1 & ) | nc -l -p 9977

Но проблема в том, что когда netcat завершает работу, tail остается позади. (Уточнение: если я не разветвляюсь, процесс хвоста будет продолжаться вечно, даже если netcat завершит работу.)

Если бы я как-то знал PID хвоста, я мог бы потом его убить.
Очевидно, используя $! вернет PID netcat.

Как я могу получить PID хвостового процесса?

Ответы [ 13 ]

0 голосов
/ 13 ноября 2018

Вы можете использовать команду coproc дважды.

Данный пример переводится как:

coproc TAIL { tail -f $1; }; exec {TAIL[1]}<&-
coproc NC { nc -v -l -p 9977; } <&"${TAIL[0]}" >&1
wait $NC_PID; echo "nc exit code: $!"
kill $TAIL_PID; echo "done"

(Я добавил туда -v и пару echo для устранения неполадок.)

Использование coproc похоже на использование Popen () в различных других языках сценариев.

0 голосов
/ 09 января 2015

Опция --pid tail - ваш лучший друг здесь. Это позволит вам полностью контролировать работу трубопровода в фоновом режиме. Прочитайте параметры команды tail для большей устойчивости в случае, если ваш файл активно вращается другим процессом, что может привести к тому, что вы перестанете отслеживать неактивный inode. Приведенный ниже пример, хотя и не используется для обработки данных, демонстрирует «наложенное» ограничение на хвост и способность указывать ему выход в любое время. Используется для измерения сервисного давления на httpd.

  # Set the tail to die in 100 second even if we die unexpectedlly.
sleep 100 & ;  ctlpid=$!
tail -q -n 0 --follow=name --retry --max-unchanged-stats=1 --pid=$ctlpid -f  /var/log/httpd/access_log 2>/dev/null | wc –l > /tmp/thisSampleRate &
…. Do some other work
….  Can kill the pipe at any time by killing $ctlpid 
…. Calculate preassure if /tmp/thisSampleRate is ready
0 голосов
/ 24 июля 2012

Не идеальный ответ, но я нашел обходной путь для демона регистратора, над которым я работал:

#!/bin/sh
tail -f /etc/service/rt4/log/main/current --pid=$$ | grep error

от $ info tail:

--pid=PID
          with -f, terminate after process ID, PID dies
...