Параллельный или блокированный доступ в функции bash-скрипта - PullRequest
1 голос
/ 08 февраля 2011

Кто-нибудь знает, как заблокировать функцию в скрипте bash? Я хотел сделать что-то наподобие java (например, синхронизировать), чтобы каждый файл, сохраненный в контролируемой папке, был в ожидании, когда-либо пытается использовать функцию отправки.

выдержка из моего сценария:

<code>(...)</p>

<p>ON_EVENT () {
   local date = $1
   local time = $2
   local file = $3
   sleep 5
   echo "$date $time New file created: $file"
   submit $file
}</p>

<p><strong>submit () {
   local file = $1 
   python avsubmit.py -f $file -v
   python dbmgr.py -a $file 
}</strong></p>

<p>if [ ! -e "$FIFO" ]; then 
  mkfifo "$FIFO"
fi</p>

<p>inotifywait -m -e "$EVENTS" --timefmt '%Y-%m-%d %H:%M:%S' --format '%T %f' "$DIR" > "$FIFO" &
INOTIFY_PID=$!</p>

<p>trap "on_exit" 2 3 15</p>

<p>while read date time file
do
  on_event $date $time $file &
done < "$FIFO"</p>

<p>on_exit

Я использую inotify, чтобы отслеживать папку при сохранении нового файла. Для каждого сохраненного (полученного) файла отправьте его в службу VirusTotal (avsubmit.py) и TreathExpert (dbmgr.py). Параллельный доступ был бы идеальным, чтобы избежать блокировки каждого нового файла, созданного в отслеживаемой папке, но функции блокировки отправки должно быть достаточно.

Спасибо, ребята!

Ответы [ 6 ]

4 голосов
/ 08 февраля 2011

Примерно так должно работать:

if (set -o noclobber; echo "$$" > "$lockfile") 2> /dev/null; then
   trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT
   # Your code here
   rm -f "$lockfile"
   trap - INT TERM EXIT
else
   echo "Failed to acquire $lockfile. Held by $(cat $lockfile)"
then
3 голосов
/ 23 июня 2013

Любой код, использующий rm в сочетании с trap или подобным средством, по своей сути ошибочен против излишних убийств, паники, системных сбоев, системных администраторов-новичков и т. Д. Недостаток заключается в том, что замок должен быть очищен вручную после такого катастрофического события чтобы скрипт запускался снова. Это может или не может быть проблемой для вас. Это проблема для тех, кто управляет многими машинами или хочет время от времени отключаться от электросети.

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

1 голос
/ 08 февраля 2011

Вы можете использовать файл блокировки , чтобы определить, следует ли отправлять файл.

Внутри функции ON_EVENT вы должны проверить, существует ли соответствующий файл блокировки, прежде чем вызывать функцию submit. Если оно существует, вернитесь или спите и проверьте снова, чтобы проверить, прошло ли оно. Если он не существует, создайте блокировку и позвоните submit. После завершения функции submit удалите файл блокировки.

См. этот поток для деталей реализации.

0 голосов
/ 19 мая 2012

Если у вас установлен GNU Parallel http://www.gnu.org/software/parallel/, вы можете сделать это:

inotifywait -q -m -r -e CLOSE_WRITE --format %w%f $DIR | 
parallel -u python avsubmit.py -f {}\; python dbmgr.py -a {}

Он будет работать не более одного питона на процессор, когда файл будет записан (и закрыт).Таким образом, вы можете обойти всю блокировку, и вы получите дополнительное преимущество, заключающееся в том, что вы избежите возможного состояния гонки, когда файл будет немедленно перезаписан (как вы убедитесь, что и первая, и вторая версии были проверены?).

Вы можете установить GNU Parallel просто:

wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel
cp parallel sem

Посмотрите вводные видеоролики по GNU Parallel, чтобы узнать больше: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

0 голосов
/ 05 марта 2012

У меня были проблемы с этим подходом, и я нашел лучшее решение:

Procmail поставляется с командой lockfile , которая делает то, что я хотел:

lockfile -5 -r10 /tmp/lock.file
do something very important
rm -f /tmp/lock.file

lockfile попытается создать указанный файл блокировки. Если он существует, он будет повторяться через 5 секунд, это будет повторяться максимум 10 раз. Если вы можете создать файл, он продолжает работу со сценарием.

Другое решение - это lockfile-progs в Debian, пример прямо со страницы руководства:

Locking a file during a lengthy process:

     lockfile-create /some/file
     lockfile-touch /some/file &
     # Save the PID of the lockfile-touch process
     BADGER="$!"
     do-something-important-with /some/file
     kill "${BADGER}"
     lockfile-remove /some/file
0 голосов
/ 09 февраля 2011

Но мне понравилось, что файлы не могут остаться заблокированными в списке ожидания (кеше), который будет отправлен тогда или позже.

У меня сейчас есть что-то вроде этого:

<code>lockfile="./lock"</p>

<p>on_event() {
  local date=$1
  local time=$2
  local file=$3
  sleep 5
  echo "$date $time New file created: $file"
  if (set -o noclobber; echo "$$" > "$lockfile") 2> /dev/null; then 
     trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT
     <strong>submit_samples $file</strong> 
     rm -f "$lockfile"
     trap - INT TERM EXIT
  else<br>
     echo "Failed to acquire lockfile: $lockfile." 
     echo "Held by $(cat $lockfile)"
  fi
}</p>

<p><strong>submit_samples() {</strong>
  <strong>local file=$1
  python avsubmit.py -f $file -v 
  python dbmgr.py -a $file</strong> 
<strong>}</strong>

Еще раз спасибо ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...