Как запустить сценарий оболочки Inotify как асинхронный процесс - PullRequest
2 голосов
/ 01 октября 2019

У меня есть сценарий оболочки inotify, который контролирует каталог и выполняет определенные команды, если поступает новый файл. Мне нужно превратить этот сценарий inotify в параллельный процесс, чтобы выполнение сценария не выполнялосьдождитесь завершения процесса всякий раз, когда в каталог попадает несколько файлов.

Я пытался использовать nohup, & и xargs для выполнения этой задачи. Но проблема была в том, что xargs запускает тот же сценарий, что и ряд процессов, всякий раз, когда появляется новый файл, все запущенные процессы n пытаются обработать сценарий. Но, по сути, я хочу, чтобы только один из процессов обрабатывал новый файл в зависимости от того, что находится в режиме ожидания. Что-то вроде рабочего пула, какой бы рабочий ни был свободен или бездействующий пытается выполнить задачу.

Это мой сценарий оболочки.

#!/bin/bash
# script.sh
inotifywait --monitor -r -e close_write --format '%w%f' ./ | while read FILE

do
  echo "started script";
  sleep $(( $RANDOM % 10 ))s;
  #some more process which takes time when a new file comes in
done

Я пытался выполнить сценарий следующим образом с помощью xargs => xargs -n1 -P3 bash sample.sh

Поэтому, когда появляется новый файл, он обрабатывается трижды из-за P3, но в идеале я хочу, чтобы один из процессов выбрал эту задачу, которая когда-либо простаивает.

Пожалуйста, пролите свет на то, как подойти к этой проблеме?

Ответы [ 2 ]

1 голос
/ 01 октября 2019

Нет причин иметь пул незанятых процессов. Просто запустите по одному на новый файл, когда увидите, что появляются новые файлы.

#!/bin/bash
inotifywait --monitor -r -e close_write --format '%w%f' ./ |
while read -r file
do
  echo "started script";
  ( sleep $(( $RANDOM % 10 ))s
  #some more process which takes time when a new "$file" comes in
  )  &
done

Обратите внимание на добавление & и скобок для группировки sleep и последующей обработки в единую подоболочку, которую мы затем можемbackground.

Также обратите внимание на то, что мы всегда предпочитаем read -r и Правильное использование заглавных букв в сценариях Bash и shell

0 голосов
/ 01 октября 2019

Может быть, это сработает:

https://www.gnu.org/software/parallel/man.html#EXAMPLE:-GNU-Parallel-as-dir-processor

Если у вас есть каталог, в который пользователи сбрасывают файлы, которые необходимо обработать, вы можете сделать это в GNU / Linux (Если вы знаете, как inotifywait вызывается на других платформах, подайте отчет об ошибке):

inotifywait -qmre MOVED_TO -e CLOSE_WRITE --format %w%f my_dir |
  parallel -u echo

Это будет запускать команду echo для каждого файла, помещенного в my_dir или его подкаталоги my_dir.

Для запуска максимум 5 процессов используйте -j5.

...