2015-02-06 3 views
36

У меня есть текущий скрипт.Выполнение параллельных программ с использованием xargs

#!/bin/bash 
# script.sh 

for i in {0..99}; do 
    script-to-run.sh input/ output/ $i 
done 

Я хочу запустить его параллельно с помощью xargs. Я пробовал

script.sh | xargs -P8 

Но выполнение вышеуказанного выполнено только один раз в то время. Не повезло и с -n8. Добавление & в конце строки, которая будет выполнена в цикле для цикла, попытается запустить скрипт 99 раз за раз. Как выполнить цикл только 8 в то время, до 100 всего.

+4

Использование GNU Parallel – Barmar

+0

Это то, что я изначально хотел сделать, но пришлось прибегнуть к xargs, потому что я нахожусь на Windows. Я не смог заставить GNU Parallel работать в Windows – Olivier

+0

Является ли этот сценарий само по себе или вы просто путаете имена, когда вы спрашиваете здесь? –

ответ

50

На странице xargs человек:

Эта страница руководства документы версии GNU из xargs. xargs считывает элементы со стандартного ввода, разделенные пробелами (которые могут быть защищены с двойными или одинарными кавычками или обратной косой чертой) или новыми символами, и выполняет команду (по умолчанию is/bin/echo) один или несколько раз с любым начальным - аргументы, за которыми следуют пункты, считанные со стандартного ввода. Пустые строки на стандартных вводах игнорируются.

Это означает, что для вашего примера xargs ждет и собирая все выходные данные из вашего сценария и затем запустить echo <that output>. Не совсем то, что полезно и что вам нужно.

Аргумент -n состоит в том, сколько элементов из ввода используется с каждой командой, которая запускается (ничего, собственно, о параллелизме здесь).

Чтобы сделать то, что вы хотите с xargs вы должны были бы сделать что-то больше, как это (непроверенные):

printf %s\\n {0..99} | xargs -n 1 -P 8 script-to-run.sh input/ output/ 

Что ломается, как это.

  • printf %s\\n {0..99} - печать один номер на линии от 0 до 99.
  • Run xargs
    • принимая в наиболее один аргумент в командной строке запуска
    • и запустить до восемь процессов в то время
+3

На самом деле вам не нужно вводить аргументы в отдельные строки; xargs word-split. Поэтому 'echo {0..99} |' будет работать так же хорошо. '<<< {0..99}', похоже, не работает; хотя '<<< word' документируется как расширяющее слово слово, он не делает этого с любой версией bash, которую я могу пригодиться. – rici

+1

@rici Похоже на ошибку в документации, тем более что документация для здесь Документы * не упоминают расширение брекетки (и этого не происходит в быстром тесте), хотя они также не упоминают расширение тильды (что doesn 't происходит для '<<', но для '<<<' so '* shrug *'). Расширения, которые выполняются и не выполняются здесь, являются документами, и здесь строки немного странны. –

+0

. Как вы можете отделить результаты от разных прогонов, например. строки? –

35

С GNU Parallel вы должны сделать следующее:

parallel script-to-run.sh input/ output/ {} ::: {0..99} 

Добавьте в -P8, если вы делаете не хотите выполнить одно задание на ядро ​​процессора.

Противоположный xargs он будет делать правильную вещь, даже если вход содержит пробел, 'или, (хотя здесь и не так). Он также гарантирует, что вывод с разных заданий не смешивается, поэтому, если вы используйте вывод, который вам гарантирован, что вы не получите половину строки из двух разных заданий.

GNU Parallel - это общий параллелизатор, который позволяет легко запускать задания параллельно на одном компьютере или на нескольких компьютерах, к которым у вас есть доступ к ssh.

Если у вас есть 32 различных заданий, которые вы хотите работать на 4-х процессоров, прямо вперед способ распараллеливания является выполнение 8 заданий на каждом CPU:

Simple scheduling

GNU Parallel вместо порождает новый процесс, когда один заканчивается - поддержание процессоров активным и тем самым экономя время:

GNU Parallel scheduling

Установка

Если GNU Parallel не упакован для вашего дистрибутива, вы можете выполнить личную установку, которая не требует доступа root. Это может быть сделано в течение 10 секунд, делая это:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash 

Для других вариантов установки см http://git.savannah.gnu.org/cgit/parallel.git/tree/README

Подробнее

Другие примеры: http://www.gnu.org/software/parallel/man.html

смотреть интро видео: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Прогулка по Учебник: http://www.gnu.org/software/parallel/parallel_tutorial.html

Подпишитесь на почтовую рассылку, чтобы получить поддержку: https://lists.gnu.org/mailman/listinfo/parallel

+8

Это не отвечает на вопрос и не указывает, почему xargs не могут достичь того же. –

+2

downvote, потому что xarg для меня делает точно так же, как второй показ изображения. – noonex

+0

@noonex Знаете ли вы, что не все используют версию xargs, которую вы используете, и что -P не во всех версиях xargs? –

Смежные вопросы