Рассмотрите следующий упрощенный пример:
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 '...'
помочь разъяснить то, в чем я нуждаюсь.
Я смог решить эту проблему с помощью явного именования трубы с помощью 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. Надеюсь, у кого-то есть более простое решение.
Добавьте обертку оболочки вокруг вашей команды и перехватите 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`
Это более элегантно?
Судя по вашему комментарию, я все еще не понимаю, почему вы ' Я предпочитаю убить 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
работает вечно. Все остальное здесь - это хитрость, позволяющая обойти это ограничение.