Параллельные процессы: Присоединение выходов на массив в сценарии Bash

- это регулярное выражение метасимвол который соответствует любому одиночному символу.

\ также является регулярным выражением метасимвола, которое может быть использовано для экранирования любого метасимвола так, что он будет буквально сопоставлен.

и так . соответствует любому символу, но \. соответствует только . .

printf %c900983\\n a . | grep -n ".900983"

1:a900983
2:.900983

... потому что . регулярное выражение метахарактер соответствует литералу . или a или любому другому одиночному символу, но...

printf %c900983\\n a . | grep -n "\.900983"

2:.900983

4
26.07.2018, 22:44
2 ответа

Немного наивный, но надежный способ сделать это, переносимый в Bourne -подобно оболочкам:

#!/bin/sh

task () {
    tid="$1"
    printf 'tid %d: Running...\n' "$tid"
    sleep "$(( RANDOM % 5 ))"
    printf 'tid %d: Done.\n' "$tid"
}

ntasks=10

tid=0
while [ "$tid" -ne "$ntasks" ]; do
    tid=$(( tid + 1 ))
    printf 'main: Starting task with tid=%d\n' "$tid"
    task "$tid" >"output.$tid" 2>&1 &
done

wait

tid=0
while [ "$tid" -ne "$ntasks" ]; do
    tid=$(( tid + 1 ))
    printf 'main: Processing output from task with tid=%d\n' "$tid"
    # do something with "output.$tid"
done

Это порождает задачи в первом цикле, затем ожидает их завершения перед обработкой вывода во втором цикле. Это подходит, если задачи производят много данных.

Чтобы ограничить количество запущенных задач максимум 4, начальный цикл можно изменить на

tid=0
while [ "$tid" -ne "$ntasks" ]; do
    tid=$(( tid + 1 ))
    printf 'main: Starting task with tid=%d\n' "$tid"
    task "$tid" >"output.$tid" 2>&1 &

    if [ "$(( tid % 4 ))" -eq 0 ]; then
        wait
    fi
done
0
27.01.2020, 20:54

Вы ищетеparset(часть GNU Parallel с 2017 г. 0422 )илиenv_parset(доступна с 2017 г. 1222):

# If you have not run:
#    env_parallel --install
# and logged in again, then you can instead run this to activate (env_)parset:
. `which env_parallel.bash`

task (){
  echo "hello $1"
  sleep 1.$1
  perl -e 'print "binary\001\002\n"'
  sleep 1.$1
  echo output of parallel jobs do not mix
}
env_parset arr task ::: {1..3}
env_parset a,b,c task ::: {1..3}

echo "${arr[1]}" | xxd
echo "$b" | xxd

parsetподдерживается в Bash/Ksh/Zsh (, включая массивы ), ash/dash (без массивов ).

0
27.01.2020, 20:54

Теги

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