Альтернатива ждать -N (потому что сервер имеет старую версию Bash)

Встроенная команда bash trap позволяет использовать ключевое слово RETURN . Поэтому измените:

trap mytrap EXIT

на:

trap mytrap RETURN

См. Обсуждение ловушки в встроенных команд оболочки

4
11.12.2018, 15:09
6 ответов

Как насчет того, чтобы вообще не использовать ожидание в цикле while?

while [ "$SGE_TASK_ID" -le "$J" ]; do

    # grep count of matlab processes out of list of user processes
    n = $(ps ux | grep -c "matlab")

    ##  if [ "$n" -le "$N" ]; then
    if [ "$n" -eq "$N" ]; then
        # sleep 1 sec if already max processes started
        sleep 1
        ##  wait -n  # as soon as one task is done, refill it with another
        ##  n=$(( n - 1 ))
    else
        # start another process
        printf 'Task ID is %d\n' "$SGE_TASK_ID"

        /share/.../matlab -nodisplay -nodesktop -nojvm -nosplash -r "main; ID=$SGE_TASK_ID; f; exit" &

        SGE_TASK_ID=$(( SGE_TASK_ID + 1 ))

    fi
    ##  n=$(( n + 1 ))
done

Строка для grep может, конечно, отличаться, в зависимости от того, что у вас запущено (, например. дайте f.mкакое-нибудь более специальное имя и используйте grep для этого.)

1
27.01.2020, 20:59

Вы можете установить его самостоятельно:

Для большинства программ единственной частью процесса установки, требующей привилегий суперпользователя, является копирование файлов в стандартные места. (неверно для драйверов -устройств, ядер, виртуальных машин и т. д.)

Я советую установить Bash в ваш домашний каталог(~/bin)и заставить ваш скрипт использовать его.

0
27.01.2020, 20:59

Этот скрипт, который вы написали, лучше сделать с помощью gnu parallel или сделать с опцией -j. В качестве альтернативы вы можете повторно -написать его на python (или другом языке ).

Посмотрите на

  • parallel:Инструмент для использования в bash (самый простой из трех для изучения, делает только одну вещь ).
  • make:Немного более продвинутый, и у него есть собственный язык. Он используется для создания файлов. например. чтобы сделать A.b, вам понадобятся A.aи g.f, когда они у вас есть, сделайте z;y;z. Вы также можете добавить правила создания A.aи g.f. Будет отрабатывать, что от чего зависит, и строить вещи в правильном порядке. Если это возможно, он будет делать что-то параллельно (, если его попросят ).
  • python:Язык программирования, он может делать то, что пытается сделать ваш скрипт, он может делать то, что делает Matlab.

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

type parallel
type make
type python

Заметка:typeвам не инструкция, печатать. Это команда, которую вы вводите. Он сообщает вам тип каждой команды (, где он ).

2
27.01.2020, 20:59

Цитирую свой ответ на другой вопрос .

Вот мое решение для параллельных заданий, которые обрабатывают до Nзаданий одновременно, как настроено _jobs_set_max_parallelбез необходимостиwait -n:

_библиотека _jobs.sh:

function _jobs_get_count_e {
   jobs -r | wc -l | tr -d " "
}

function _jobs_set_max_parallel {
   g_jobs_max_jobs=$1
}

function _jobs_get_max_parallel_e {
   [[ $g_jobs_max_jobs ]] && {
      echo $g_jobs_max_jobs

      echo 0
   }

   echo 1
}

function _jobs_is_parallel_available_r() {
   (( $(_jobs_get_count_e) < $g_jobs_max_jobs )) &&
      return 0

   return 1
}

function _jobs_wait_parallel() {
   # Sleep between available jobs
   while true; do
      _jobs_is_parallel_available_r &&
         break

      sleep 0.1s
   done
}

function _jobs_wait() {
   wait
}

Пример использования:

#!/bin/bash

source "_lib_jobs.sh"

_jobs_set_max_parallel 3

# Run 10 jobs in parallel with varying amounts of work
for a in {1..10}; do
   _jobs_wait_parallel

   # Sleep between 1-2 seconds to simulate busy work
   sleep_delay=$(echo "scale=1; $(shuf -i 10-20 -n 1)/10" | bc -l)

   ( ### ASYNC
   echo $a
   sleep ${sleep_delay}s
   ) &
done

# Visualize jobs
while true; do
   n_jobs=$(_jobs_get_count_e)

   [[ $n_jobs = 0 ]] &&
      break

   sleep 0.1s
done
-1
27.01.2020, 20:59

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

qsub -t 1-4./script.sh

затем удалите все строки, которые изменяют значение SGE _TASK _ID --gridengine установит это за вас.

(вы также можете установить эту опцию в скрипте, используя строку типа #$-t 1-4, если хотите, конечно...)

1
27.01.2020, 20:59

Используйте GNU Parallel.

Более новые версии имеют --embed, которые встраивают GNU Parallel в сценарий оболочки. Таким образом, вам не нужно устанавливать GNU Parallel в кластере.

Итак, установите на свой ноутбук новейшую версию GNU Parallel и выполните:

$ parallel --embed > myscript.sh

Теперь отредактируйтеmyscript.sh:

#!/bin/bash -l
#$ -S /bin/bash
#$ -l h_vmem=5G
#$ -l tmem=5G
#$ -l h_rt=480:0:0
#$ -cwd
#$ -j y


#$ -N try

# Here starts the original content of myscript.sh
# Embedded GNU Parallel created with --embed
parallel() {
   «This bit removed for brevity (around 13000 lines, generated by gnu parallel)»
   return `cat "$_exit_FILE"; rm "$_exit_FILE"`
}
# Here ends the original content of myscript.sh

date
hostname

J=4 #number tasks
N=2 #number tasks executed in parallel

doit() {
    SGE_TASK_ID="$1"
    printf 'Task ID is %d\n' "$SGE_TASK_ID"

    /share/.../matlab -nodisplay -nodesktop -nojvm -nosplash -r "main; ID=$SGE_TASK_ID; f; exit"
}
export -f doit

seq $J | parallel -j $N doit

Наконец, скопируйте myscript.shна сервер в то же место, что и td.sh, и запустите его так же, как запускаете td.sh.

1
27.01.2020, 20:59

Теги

Похожие вопросы