Как обработать несколько файлов через программу в bash, используя заранее определенное количество процессов? - PullRequest
2 голосов
/ 21 июня 2019

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

В качестве минимального примера, вот некоторый установочный код для репликации моей ситуации:

$ mkdir test
$ cd test

$for i in {1..1000}
>do
>   echo "$i" >> $i.txt
> done

Как бы я использовал (скажем) 2 процесса только для обработки этого списка файлов, чтобы выводв каждом файле выполняется произвольная операция с числом $i (может быть, добавляется два или что-то еще), а затем выводится done by process 1 or 2, в зависимости от того, выполнял ли процесс 1 или 2 операцию?

Ответы [ 2 ]

2 голосов
/ 21 июня 2019

Ваш пример не очень разумный, поэтому его трудно советовать лучше, но вы можете использовать для этого GNU Parallel .

Скажем, вы хотите запустить HeavyProcessing для всех файловначиная с SeriousData с использованием двух процессорных ядер параллельно:

parallel -j 2 HeavyProcessing ::: SeriousData*

Немного другой пример, скажем, имена файлов, которые вы хотите обработать, находятся в файле с именем FileList.txt, и вы хотите запустить один процесс на ядро, котороеваш процессор имеет, а также получить индикатор выполнения:

parallel -a FileList.txt --bar HeavyProcessing
1 голос
/ 21 июня 2019

Одним из решений может быть xargs -P, но для его работы требуется дополнительный шум. Вот решение, которое соответствует вашему примеру:

printf '%s\0' {1..1000} | xargs -0 -rn1 -P2 bash -c 'echo "$1" >> "$1".txt' --

Объяснение:

  • -0: отдельные входные параметры на \0 байт (потому что это то, что printf '%s\0' … отправляет)
  • -r: ничего не запускать, если нет ввода
  • -n1: использовать только один входной параметр для процесса
  • -P2: использовать не более 2 параллельных процессов
  • bash -c '…' --: программа для запуска; запуск оболочки из xargs требует -- для правильного связывания позиционных параметров
  • 'echo "$1" >> "$1".txt': фактический фрагмент кода оболочки

Последние части становятся намного проще, если массовый код, который вы хотите запустить, не требует специальных функций оболочки, таких как перенаправление. Вы можете запустить вашу программу явно из xargs без указания bash -c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...