2012-01-26 2 views
0

Имея большой набор файлов, мне нужно Grep через, я делаю это в Баш скрипт так:Bash «PS» параллельные процессы и проверить, когда они сделаны

#! /usr/bin/env bash 

REX="word" 
grep -IP $REX A* >> result & 
grep -IP $REX B* >> result & 
grep -IP $REX C* >> result & 
grep -IP $REX D* >> result & 
[..] 

Как знать когда все процессы закончены?

+1

Почему бы не использовать 'find' и' xargs', чтобы найти все файлы, которые вам нужны, и обрабатывать их параллельно? –

+1

или GNU или BSD 'parallel' – mkb

ответ

4

Я бы идти о решении вашей проблемы по-другому. find может находить определенные файлы в вашей файловой системе, а xargs позволяет запускать команды по заданным входным файлам. Поэтому я хотел бы использовать команду:

find ./ -type f -print0 | xargs -0 -I{} -n1 -P4 grep -IP $REX '{}' >> result 

Это будет искать, начиная с текущего каталога (./) для всех обычных файлов (-type f), и передавать их xargs безопасно в случае, если есть какие-либо пробелы в имя файла (-print0). xargs, то для каждой команды запускается команда grep. -I{} сообщает xargs, что там, где он видит {}, он вставляет имя файла в команду. Здесь не обязательно, но хорошая практика. -0 идет рука об руку с -print0 от find и говорит ему ожидать ввода таким образом. -P4 сообщает xargs для одновременного запуска до 4 процессов, а -n1, как описано в справочной странице, указывает на xargs, чтобы использовать только один аргумент за один раз за команду.

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

+0

Параллельное выполнение grep может привести к смешению вывода в файле результатов и, следовательно, является неоптимальной идеей. Как только -P4 находится в стороне, вы можете просто использовать 'find. -type f -exec grep -IPh $ REX "{}" "+" >> result' без необходимости xargsing. (Я понимаю, что использование xargs с '-n1' приведет к тому, что имя файла не будет напечатано перед grep, в дальнейшем оно будет компенсировано опцией' -h' grep.) –

1

Попробуйте проверить, что выход jobs -p | wc -l имеет нулевую длину.

FYI: существуют более эффективные способы параллельной обработки, чем использование оболочки в качестве менеджера заданий. find -print0 до xargs -0 -P - мой личный фаворит.

+0

вы можете подробно остановиться на использовании find + xargs для grepping? спасибо – pistacchio

+0

@pistacchio 'find. -maxdepth 1 -name "[ABCD] *" -print0 | xargs -0 grep -IP $ REX >> result' – Borealid

0

использование ожидание. Я даже не думаю, что вам нужно сохранить и указать pids в этом случае, например.

#! /usr/bin/env bash 

REX="word" 
grep -IP $REX A* >> result & 
grep -IP $REX B* >> result & 
grep -IP $REX C* >> result & 
grep -IP $REX D* >> result & 
[..] 
wait 
echo "done" 

Обратите внимание на то, что есть способы улучшить это, чем перечислять все. Вы можете передать ls в xargs или использовать exec с find, например.

4

Используйте Баш встроенный 'ждать'

ждать [п ...]

Wait для каждого указанного процесса и возвращает статус завершения. Каждый n может быть идентификатором процесса или спецификацией задания; если задана спецификация задания, ожидаются все процессы в конвейере заданий. Если n не задано, все текущие активные дочерние процессы ждут, а статус возврата равен нулю. Если n указывает несуществующий процесс или задание, статус возврата равен 127. В противном случае статус возврата - это статус выхода для последнего процесса или ожидаемого задания.

В вашем случае оно должно быть достаточно просто:

REX="word" 
grep -IP $REX A* >> result & 
grep -IP $REX B* >> result & 
grep -IP $REX C* >> result & 
grep -IP $REX D* >> result & 

echo "Waiting..." 
wait 
echo "All child terminated" 
Смежные вопросы