Multi-Threading / Forking in bash script


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.

Оскільки $inFile3500+ рядків триває, сценарій потребує 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
Ви протестували цю лінію shebang? Шебанги з декількома аргументами непредставні. У Linux #!a b cце призведе до ["b c"], а в деяких інших системах - до ["b", "c"].
nyuszika7h

1
Він переосмислює власні аргументи, коли використовується таким чином (інакше параметр не буде багато корисного).
Майкл Гомер

@MichaelHomer Мені потрібно використовувати GNU parallelдля скребки HTML-сторінок. Чи можете ви, будь ласка, перейти через цю тему unix.stackexchange.com/questions/277609/…
Swatesh Pakhare
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.