Многопоточность / Форкинг в скрипте bash

9

Я написал скрипт bash в следующем формате:

#!/bin/bash
start=$(date +%s)
inFile="input.txt"
outFile="output.csv"

rm -f $inFile $outFile

while read line
do

    -- Block of Commands

done < "$inFile"

end=$(date +%s)

runtime=$((end-start))

echo "Program has finished execution in $runtime seconds."

whileЦикл будет читать $inFile, выполнять некоторые действия на линии и сбросить результат $outFile.

Поскольку $inFileдлина строки составляет более 3500 строк, выполнение сценария займет 6-7 часов. Чтобы минимизировать это время, я планирую использовать многопоточность или разветвление в этом скрипте. Если я создам 8 дочерних процессов, 8 строк из $inFileних будут обрабатываться одновременно.

Как это может быть сделано?

Мандар Шинде
источник
Будьте осторожны: разные сценарии нужно будет писать в разные файлы. Также ваш сценарий как написано удаляет входной файл как первое действие!
pjc50

Ответы:

10

GNUparallel создан именно для такого рода вещей. Вы можете запускать свой сценарий много раз одновременно, используя разные данные из вашего ввода для каждого:

cat input.txt | parallel --pipe your-script.sh

По умолчанию он порождает процессы в соответствии с количеством процессоров в вашей системе, но вы можете настроить его с помощью -j N.

Особенно изящный трюк - это особенность упаковки. Если вы измените первую строку вашего Bash-скрипта на:

#!/usr/bin/parallel --shebang-wrap --pipe /bin/bash

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

Есть пара вещей, на которые стоит обратить внимание. Во-первых, он разделит ваш вход на последовательные блоки и будет использовать их по одному - он не чередует строки. Другая причина в том, что эти фрагменты разделены по размеру, независимо от количества записей. Вы можете использовать, --block Nчтобы установить другой размер блока в байтах. В вашем случае, размер файла должен составлять не более одной восьмой. Ваш файл звучит так, как будто он может быть достаточно маленьким, чтобы в конечном итоге все это оказалось в одном блоке, что не соответствовало бы цели

Есть много вариантов для конкретных случаев использования, но учебное пособие описывает все очень хорошо. Опции, которые могут вас заинтересовать, включают --round-robinи --group.

Майкл Гомер
источник
1
Вы проверяли эту линию Шебанга? Шебанги с несколькими аргументами непереносимы. В Linux #!a b cэто приведет к ["b c"], в то время как в некоторых других системах это приведет к ["b", "c"].
nyuszika7h
1
Он использует свои собственные аргументы при использовании таким способом (в противном случае опция будет не слишком полезной).
Майкл Гомер
@MichaelHomer Мне нужно использовать GNU parallelдля очистки страниц HTML. Не могли бы вы пройти через эту ветку unix.stackexchange.com/questions/277609/…
Swatesh Pakhare