LINUX.ORG.RU

Параллельное выполнение bash-скриптов

 , , ,


0

1

Добрый день, подскажите, пожалуйста. Вот есть такая проблема: необходимо из консоли запустить скрипт1 у которого внутри еще 2 скрипта(скрипт2 и скрипт3), причем скрипт2 и 3 сами в себе содержат еще по 100 скриптов на выполнение, т.е. :

script1: #!/bin/bash ./script2 ./script3

а скрипты 2 и 3:

./script2 #!/bin/bash ./scr1& ./scr2& ./scr3& ./scr4& …

./script3 #!/bin/bash ./scrt1& ./scrt2& ./scrt3& ./scrt4& …

Нужно так запустить скрипт1, чтобы скрипт2 выполнился, освободил оперативную память и дальше пошел на выполнение скрипт3 ,т.е. нужна последовательность выполнения скриптов 2 и 3, иначе оперативки не хватает и всё виснет. Подскажите как это сделать, плиз! З.Ы. я пробовать через команду wait, использовал разные скобки () или {} , но не получилось - все скрипты подгружаются одновременно и комп виснет.

З.Ы. Ребята, не знаю как поставить новую строку, поэтому безусловно /scr /scrt начинаются с новой строки ,также как и #!/bin/bash



Последнее исправление: ya-andkon (всего исправлений: 3)
Ответ на: комментарий от PRN

Это я понял. То что он хочет, решается так: ему надо script2 и script3 переписать без &, а с parallel. Тогда сперва выполнится script2 (все эти scr в нём), и только потом script3.

Ну или вообще без кучи такой кучи скриптов вот так:

#!/bin/sh
# Выполняем скрипты с scr1 по scr15 параллельно:
seq 15 | parallel ./scr{}
# Когда они завершатся, выполняем скрипты с scr16 по scr32 параллельно:
seq 16 32 | parallel ./scr{}
# Когда и они завершатся, выполняем скрипты с scrt1 по scrt22 параллельно:
seq 1 22 | parallel ./scrt{}
# Ну и так далее

Ну или если не требуется вручную задавать, а можно все по маске, то без seq:

#!/bin/sh
parallel ::: ./scr[0-9]*
parallel ::: ./scrt*

Так сначала запустятся все scr, затем (только когда они завершатся), все scrt.

Но вообще если дело именно в памяти, то можно переписать не через жопу, а нормально и просто в самом parallel ограничить количество одновременно исполняемых скриптов подходящим для задачи числом. То если, если не важно, в каком порядке их выполнять, лишь бы память всю не выжрали

parallel -j100 ::: ./scr[0-9t]*

Запустит все скрипты scr и scrt, из них всегда 100 будет работать параллельно. Как только один завершается, на его место запускается следующий в очереди.

CrX ★★★★★
()
Последнее исправление: CrX (всего исправлений: 7)

Сам не догадался, но нашëл на stackoverflow.

Можно использовать source script2. А дальше уже wait.

Способ предполагает, что вы можете править script1. Без правки script1 скорее всего никак.

unDEFER ★★★★★
()

Добрый день. Рекомендую ознакомиться с Искусством программирования на языке сценариев командной оболочки. Потратите время на чтение, но потом сможете такие задачи решать нормальным образом, а не «пробовать через команду wait, использовал разные скобки () или {}», в надежде, что какое-то из заклинаний сделает магию.

ugoday ★★★★★
()
Ответ на: комментарий от CrX

Большое спасибо за ответ. Действительно, очередность неважна, критична только проблема с оператив.памятью. Тогда можно ли сделать так прям из консоли: parallel ::: cat myscript где myscript - это файл из 1500 строк для запуска параллельных команд
./scr1 ./scr2 …

ya-andkon
() автор топика
Ответ на: комментарий от ya-andkon

Так нельзя, нужно содержимое myscript отправить в parallel, если одна строка myscript - это одна команда, то как-то так:

cat myscript | parallel --bar -j5 {}

Будет параллельно выполняться пять джоб с прогрессбаром.

PRN
()

Есть отличное решение из POSIX: xargs -P <nproc>. Не требует страданий с GNU parallel, авторы которого натолько странные, что заставляют тебя передавать ключи «да, я дал денег проекту» чтобы не показывать рекламу на каждомвызове.

gaylord
()
Ответ на: комментарий от gaylord

Не требует страданий с GNU parallel, авторы которого натолько странные, что заставляют тебя передавать ключи «да, я дал денег проекту» чтобы не показывать рекламу на каждомвызове.

Достаточно один раз запустить parallel --citation и никакой рекламы больше никогда не будет.

annulen ★★★★★
()
Последнее исправление: annulen (всего исправлений: 1)
Ответ на: комментарий от ya-andkon

Как я понял у тебя такой вариант заработал. Просто запихни все команды в myscrypt должно выглядеть так:

s2_1
s2_2
...
s2_N
s3_1
s3_2
...
s3_M

И вызови cat myscript | parallel --bar -j1 {}. Вместо 1 подбери нужное число джоб чтобы не падало.

PRN
()
Ответ на: комментарий от ya-andkon

Можно так:

parallel -j50 ::: ./scr1 ./scr2 ./eto_script ./a_etot_ya_pjanym_pisal_poetomu_nazvanie_duratskoe ./script666

Можано написать по команде на строчку в файлик и

cat filename | parallel -j50

Выполняться будет параллельно, 50 одновременно. Один завершается, другой из очереди запускается. Одновременно при этом в каждый момент не больше чем 50. С этим параметром играйся, пока не поймёшь, сколько тебе надо одновременно.

CrX ★★★★★
()
Ответ на: комментарий от anonymous

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

ya-andkon
() автор топика

Нужно так запустить скрипт1, чтобы скрипт2 выполнился, освободил оперативную память и дальше пошел на выполнение скрипт3 ,т.е. нужна последовательность выполнения скриптов 2 и 3

Для этого в конце скриптов 2 и 3 нужно добавить строку

wait $(jobs -p)

что означает «подождать завершения всех фоновых процессов, запущенных ранее в этом же скрипте с & в конце»

annulen ★★★★★
()
Ответ на: комментарий от CrX

ребята, большое вам спасибо за отзывчивость, но если честно, из всех возможных вариантов мне больше всего нравится parallel, возможно там можно не только ограничивать джобы, но и число ядер на которых будет осуществляться обработка скриптов(к примеру, когда запускаешь на инсталляцию cmake то можно через параметр выставлять нужно число ядре процессора) - вот тогда это была бы песня, но, к сожалению parallel она не работает даже при -j5 , всё равно грузит весь оператив(16Гб).

ya-andkon
() автор топика
Ответ на: комментарий от ya-andkon

но, к сожалению parallel она не работает даже при -j5 , всё равно грузит весь оператив(16Гб).

Значит скрипты у вас такие, раз даже 5 из них грузят 16 ГБ.

Подробности нужны. Полностью конкретно скрипт и как запускается (может & где-нибудь опять остался, он нигде не нужен, или ещё чего), тогда можно будет что-то сказать. Дело уже явно не в самом parallel, а в содержимом скриптов.

CrX ★★★★★
()
Последнее исправление: CrX (всего исправлений: 1)
Ответ на: комментарий от annulen

xargs есть везде, включая busybox и BSD. Ну и бороться с рекламой еще и в консоли выглядит совсем странно. Я знаю что есть случаи когда parallel удобнее, но чаще всего хватает xargs.

gaylord
()