Я использую оболочку AIX Korn для выполнения сценария Perl, который принимает числовой аргумент от 1 до 50 и одновременно запускает их в фоновом режиме. Есть ли способ ограничить фоновый процесс, например, 5? Если один закончит, выполните следующий. Мой текущий код просто выполняет их все в фоновом режиме.
i=1; while [[ $i -le 50 ]]; do perl some_script.pl $i &; ((i+=1)); done;
Например, если 2 завершается, выполните следующий, который равен 6 и так далее.
@CharlesDuffy. Извини. Я понятия не имел, что существуют разные версии ksh для AIX. Я использую AIX 7.2.0.0 и искал в Google, как получить версию оболочки Korn. Я нажал CTRL + ALT + V и получил версию M-11/16 / 88f. Было бы так? Спасибо
Если вы запустите оболочку по умолчанию, у вас будет ksh88. Что такое шебанг вашего скрипта, и если вы не запускаете его в скрипте, каков вывод $SHELL --version
--version не является флагом текущего ksh
Существуют различные версии KSH. Исходная оболочка Korn Shell, ksh88
, является оболочкой по умолчанию в IBM AIX, начиная с версии 4 (/usr/bin/ksh
). Но они также поддерживают Enhanced Korn Shell, ksh93
(/usr/bin/ksh93
), в которой больше наворотов. Именно те навороты, которые облегчают жизнь в данном случае:
КШ93: В KSH93 у вас есть переменная оболочки JOBMAX
, которая делает это за вас:
JOBMAX
: This variable defines the maximum number of running background jobs that can run at a time. When this limit is reached, the shell will wait for a job to complete before starting a new job.
JOBMAX=5
i=1; while [[ $i -le 50 ]]; do perl some_script.pl $i &; ((i+=1)); done;
Кстати. вместо этого вам может быть интересно использовать цикл for.
JOBMAX=5
for i in $(seq 1 50); do perl some_script.pl "$i" &; done
KSH: Если вы не можете использовать KSH93 и должны придерживаться POSIX 2-совместимого KSH, вы можете рассмотреть возможность использования xarg
, но только если он разрешает флаг --max-procs
.
seq 1 50 | xargs -I{} --max-procs=5 perl some_script.pl {}
К сожалению, AIX не поддерживает флаг --max-procs
.
Значит, надо что-то построить самому:
procmax=5
for i in $(seq 1 50); do
perl some_script.pl "$i" &;
(( i%procmax == 0 )) && wait
done
К сожалению, на самом деле это не настоящая параллельная версия, поскольку она будет ждать завершения первых 5 процессов, прежде чем запускать следующий пакет из 5.
Итак, вы можете взглянуть на jobs
и что-нибудь с этим сделать:
procmax=5
checkinterval=1
for i in $(seq 1 50); do
perl some_script.pl "$i" &;
while [[ $(jobs -l | wc -l) -ge "$procmax" ]]; do
sleep "$checkinterval";
done
done
Это все еще не совсем параллелизм из-за sleep
, но это необходимо.
Я попробовал JOBMAX, но, похоже, это не сработало. Все процессы выполнялись в фоновом режиме одновременно. Я изменил код на JOBMAX = 3 i = 1; а [[$ i -le 6]]; сделать perl some_script.pl $ i &; ((я + = 1)); Выполнено;. Связано ли это с версией ksh, о которой ранее спрашивали? Также цикл for не работал, так как не мог найти seq.
Да, я так думаю, вы можете проверить, работает ли он с ksh93? Я изучаю это, но из руководства IBM кажется, что ваш ksh
не поддерживает это? Ни ваш xarg
, который допускает распараллеливание. Установлен ли у вас инструментарий GNU? (проверьте наличие gxarg
и gawk
)
@criz Я имею в виду это: ibm.com/support/knowledgecenter/en/ssw_aix_72/…
Забавно, я на самом деле работал над тем же, но спал 2 секунды, прежде чем перейти к следующему. Но, к сожалению, я все еще не могу использовать seq. Также вместо этого я использовал условие ps -fu $USER | grep some_script.pl | wc -l
-ge $ JOBMAX внутри цикла while.
Извините, я не думаю, что gxarg и gawk доступны.
Спасибо @kvantour, это мне очень помогло.
Пожалуйста. Один комментарий: не используйте ps
, так как это дает все some_scipt.pl, а не те, которые в цикле вы хотите распараллелить. Кроме того, если вы хотите использовать ps
, вы можете сделать s -fu $USER | grep [s]ome_script.pl | wc -l
, чтобы исключить grep
из списка.
Позвольте нам продолжить обсуждение в чате.
Кстати, знаете ли вы какая версия ksh ваших пакетов выпуска AIX? Это будет полезно не только для людей, добавляющих ответы, но и для тех, кто хочет знать, к каким другим операционным системам относится ответ.