Как получить PID процесса в конвейере

Рассмотрите следующий упрощенный пример:


my_prog|awk '...' > output.csv &
my_pid="$!" #Gives the PID for awk instead of for my_prog
sleep 10
kill $my_pid #my_prog still has data in its buffer that awk never saw. Data is lost!

В ударе, $my_pid точки к PID для awk. Однако мне нужен PID для my_prog. Если я уничтожаю awk, my_prog не знает для сбрасывания, это - буфер вывода, и данные потеряны. Так, как можно было бы получить PID для my_prog? Отметьте это ps aux|grep my_prog не будет работать, так как могут быть несколько my_progдвижение.

Примечание: измененный cat кому: awk '...' помочь разъяснить то, в чем я нуждаюсь.

14
задан User1 27 July 2010 в 17:01
поделиться

3 ответа

Я смог решить эту проблему с помощью явного именования трубы с помощью mkfifo.

Шаг 1: mkfifo capture.

Шаг 2: Запустите этот скрипт


my_prog > capture &
my_pid="$!" #Now, I have the PID for my_prog!
awk '...' capture > out.csv & 
sleep 10
kill $my_pid #kill my_prog
wait #wait for awk to finish.

Мне не нравится управление с помощью mkfifo. Надеюсь, у кого-то есть более простое решение.

6
ответ дан 1 December 2019 в 09:00
поделиться

Добавьте обертку оболочки вокруг вашей команды и перехватите pid. В моем примере я использую iostat.

#!/bin/sh
echo $$ > /tmp/my.pid
exec iostat 1

Exec заменяет оболочку на новый процесс, сохраняя pid.

test.sh | grep avg

Пока это выполняется:

$ cat my.pid 
22754
$ ps -ef | grep iostat
userid  22754  4058  0 12:33 pts/12   00:00:00 iostat 1

Так вы можете:

sleep 10
kill `cat my.pid`

Это более элегантно?

4
ответ дан 1 December 2019 в 09:00
поделиться

Судя по вашему комментарию, я все еще не понимаю, почему вы ' Я предпочитаю убить my_prog , чем завершить его упорядоченным образом. Десять секунд - довольно произвольное измерение для многопроцессорной системы, при этом my_prog может генерировать 10 тыс. Строк или 0 строк вывода в зависимости от загрузки системы.

Если вы хотите ограничить вывод my_prog чем-то более определенным, попробуйте

my_prog | head -1000 | awk

без отсоединения от оболочки. В худшем случае head закроет свой ввод, и my_prog получит SIGPIPE. В лучшем случае измените my_prog , чтобы он давал желаемый объем вывода.

добавлено в ответ на комментарий :

Если у вас есть контроль над my_prog , укажите ему необязательный аргумент -s duration . Затем где-нибудь в вашем основном цикле вы можете поместить предикат:

if (duration_exceeded()) {
    exit(0);
}

, где exit, в свою очередь, правильно сбрасывает выходные файлы. В случае отчаяния и некуда поставить предикат, это можно реализовать с помощью alarm (3), которого я намеренно не показываю, потому что это плохо.

Суть вашей проблемы в том, что my_prog работает вечно. Все остальное здесь - это хитрость, позволяющая обойти это ограничение.

2
ответ дан 1 December 2019 в 09:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: