запустить скрипт в нескольких папках параллельно

запустить скрипт в нескольких папках параллельно

У меня есть несколько подкаталогов в каталоге высокого уровня. Каждый подкаталог содержит несколько файлов и скрипт оболочки цикла for. Один и тот же скрипт цикла for присутствует в каждом подкаталоге. Я хочу перейти в каждый подкаталог и запустить скрипт цикла for параллельно в нескольких терминалах. Я пробовал это, но, похоже, он делает это последовательно (один за другим), а я хочу запустить их все параллельно.

find dir_* -type f -execdir sh for_loop.sh {} \;

решение1

Если предположить, что это работает правильно - только последовательно:

find dir_* -type f -execdir sh for_loop.sh {} \;

Тогда вы сможете заменить это на:

find dir_* -type f | parallel 'cd {//} && sh for_loop.sh {}'

Для запуска на нескольких терминалах GNU Parallel поддерживает tmuxзапуск каждой команды в ее собственной tmuxпанели:

find dir_* -type f | parallel --tmuxpane 'cd {//} && sh for_loop.sh {}'

По умолчанию это одно задание на ядро ​​ЦП. В вашем случае вы можете захотеть запустить на одно задание больше, чем у вас ядер:

 find dir_* -type f | parallel -j+1 --tmuxpane 'cd {//} && sh for_loop.sh {}'

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

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

Простое планирование

Вместо этого GNU Parallel запускает новый процесс после завершения предыдущего, сохраняя при этом активными ЦП и, таким образом, экономя время:

Параллельное планирование GNU

Монтаж

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

$ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
   fetch -o - http://pi.dk/3 ) > install.sh
$ sha1sum install.sh | grep 883c667e01eed62f975ad28b6d50e22a
12345678 883c667e 01eed62f 975ad28b 6d50e22a
$ md5sum install.sh | grep cc21b4c943fd03e93ae1ae49e28573c0
cc21b4c9 43fd03e9 3ae1ae49 e28573c0
$ sha512sum install.sh | grep da012ec113b49a54e705f86d51e784ebced224fdf
79945d9d 250b42a4 2067bb00 99da012e c113b49a 54e705f8 6d51e784 ebced224
fdff3f52 ca588d64 e75f6033 61bd543f d631f592 2f87ceb2 ab034149 6df84a35
$ bash install.sh

Другие варианты установки см.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

решение2

Вероятно, идеальным инструментом для этого являетсяGNU-параллельный:

parallel ::: dir_*/for_loop.sh

GNU Parallel не только запускает каждое задание параллельно, но и демультиплексирует их выходные данные, чтобы они не мешали друг другу.

Из его страницы руководства:

GNU parallel — это оболочка для параллельного выполнения заданий с использованием одного или нескольких компьютеров. Задание может быть отдельной командой или небольшим скриптом, который должен быть запущен для каждой из строк во входных данных. Типичный входной файл — это список файлов, список хостов, список пользователей, список URL-адресов или список таблиц. Задание также может быть командой, которая считывает данные из конвейера. Затем GNU parallel может разбить входные данные на блоки и передать блок в каждую команду параллельно.

Если вы используете xargs и tee сегодня, вы обнаружите, что GNU parallel очень прост в использовании, поскольку GNU parallel написан с теми же опциями, что и xargs. Если вы пишете циклы в оболочке, вы обнаружите, что GNU parallel может заменить большинство циклов и ускорить их выполнение, выполняя несколько заданий параллельно.

GNU parallel гарантирует, что вывод от команд будет таким же, как если бы вы запускали команды последовательно. Это позволяет использовать вывод от GNU parallel в качестве ввода для других программ.

решение3

findне сделаю этого за вас.

создайте скрипт, найдите ваши скрипты for_loop.sh и выполните их, например так:

#!/bin/bash

for theScript in $(find dir_* -name for_loop.sh); do
  "$theScript" &
done

если скрипт должен быть запущен внутри подкаталога, попробуйте cdсделать это раньше, например, как cd $(dirname "$theScript") && . $(basename "$theScript").

мои примеры не тестировались подробно и не являются устойчивыми к ошибкам...

Редактировать 1:

КакСато КацураЕсли комментарий прокомментирован правильно, приведенный выше скрипт перестает работать, если в имени каталога есть пробелы.

Поэтому я изменил цикл на read:

#!/bin/bash
find dir_* -name for_loop.sh | while IFS= read -r theScript; do
  "$theScript" &
done

решение4

вы можете сделать это из вашего каталога верхнего уровня

for D in `find . -type d -maxdepth 1`
do 
     $D/<yourScriptName>.sh &
done

«&» — для запуска в фоновом режиме

Связанный контент