
У меня есть фрагмент сценария:
MyCoolCommand 2>&1 | tail -n 256 > "report.out" &
cool_pid=$! # FIXME
В нем есть ошибка - cool_pid
это PID tail
. Конвейер работает в фоновом режиме. Как сохранить в cool_pid
PID MyCoolCommand
? Оболочка - /bin/sh. Если это невозможно со старым простым /bin/sh, я готов перейти на Bash, если есть способ этого добиться.
решение1
В Bash можно использовать замену процессов:
MyCoolCommand > >(tail -n 256 > report.out) 2>&1 &
cool_pid=$!
Данные будут перетекать из MyCoolCommand
в, tail
как в вашей исходной команде, но $!
будут такими, какими вы хотите.
Примечания:
2>&1
должно быть после>
.- Оболочка будет считать работу выполненной сразу после
MyCoolCommand
выхода, в то время какtail
возможно, все еще работает. Если ваш скрипт в какой-то моментwait
s для работы и затем обрабатываетreport.out
дальше, имейте в виду, что файл может быть еще не готов. Для сравнения: вашMyCoolCommand | tail … &
считается выполненным послеобапроцессы завершаются.
Решить проблему можно простым способом sh
, но для этого потребуется ручная сантехника:
mkfifo myfifo
<myfifo tail -n 256 >report.out &
MyCoolCommand >myfifo 2>&1 &
cool_pid=$!
rm myfifo
Примечания:
Удаление fifo, когда он все еще используется, безопасно. Программы будут продолжать его использовать, несмотря на то, что он отсоединен от каталога. ОС действительно уничтожит fifo только тогда, когда он больше не будет использоваться. Новый файл с именем
myfifo
(если он когда-либо будет создан) не будет иметь ничего общего со старым (кроме имени), даже если старый все еще используется.Если файл с именем
myfifo
уже находится в текущем рабочем каталоге (потому что параллельно работает другой экземпляр скрипта или по какой-либо другой причине) и, возможно, используется, то скрипт может вести себя неправильно. Правильным решением будет создать временный каталог сmktemp -d
и поместить туда fifo.mktemp
непереносимо.В этом методе вы можете сохранить PID
MyCoolCommand
инезависимо PIDtail
.