Блокировка файлов Bash, включая flock для подпроцессов

Я пытаюсь защитить свои скрипты от параллельного выполнения с помощью flock. Я прочитал несколько тем здесь и натолкнулся на ссылку на это: http://www.kfirlavi.com/blog/2012/11/06/elegant-locking-of-bash-program/ которая включает в себя множество примеров представлены в других темах.

Мои сценарии в конечном итоге будут работать в Ubuntu (>14), OS X 10.7 и 10.11.4. Я в основном тестирую на OS X 10.11.4 и установил flock через homebrew.

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

#!/bin/bash
#----------------------------------------------------------------

set -vx
set -euo pipefail
set -o errexit
IFS=$'\n\t'

readonly PROGNAME=$(basename "$0")
readonly LOCKFILE_DIR=/tmp
readonly LOCK_FD=200
subprocess1="/bash$/subprocess1.sh"
subprocess2="/bash$/subprocess2.sh"

lock() {
    local prefix=$1
    local fd=${2:-$LOCK_FD}
    local lock_file=$LOCKFILE_DIR/$prefix.lock

    # create lock file
    eval "exec $fd>$lock_file"

    # acquier the lock
    flock -n $fd \
        && return 0 \
        || return 1
}

eexit() {
    local error_str="$@"

    echo $error_str
    exit 1
}

main() {
    lock $PROGNAME \
        || eexit "Only one instance of $PROGNAME can run at one time."



    ##My child scripts
    sh "$subprocess1"  #wait for it to finish then run 

    sh "$subprocess2"

    }
main

$subprocess1 - это скрипт, который загружает ncftpget и регистрируется на удаленном сервере, чтобы получить некоторые файлы. После завершения соединение закрывается. Я хочу subprocess1 каждые 15 минут через cron. Я сделал это с успехом, но иногда есть много файлов, чтобы захватить, и работа занимает больше 15 минут. Это редко, но это случается. В таком случае я хочу убедиться, что второй экземпляр $subprocess1 не может быть запущен. Для ясности небольшой пример такого индекса:

#!/bin/bash
remoteftp="someftp.ftp"
ncftplog="somelog.log"
localdir="some/local/dir"
ncftpget -R -T -f "$remoteftp" -d "$ncftplog" "$localdir" "*.files"
EXIT_V="$?"
    case $EXIT_V in
        0) O="Success!";;
        1) O="Could not connect to remote host.";;
        2) O="Could not connect to remote host - timed out.";;
        3) O="Transfer failed.";;
        4) O="Transfer failed - timed out.";;
        5) O="Directory change failed.";;
        6) O="Directory change failed - timed out.";;
        7) O="Malformed URL.";;
        8) O="Usage error.";;
        9) O="Error in login configuration file.";;
        10) O="Library initialization failed.";;
        11) O="Session initialization failed.";;
    esac

if [ "$EXIT_V" = 0 ]; 
    then
        echo ""$O"
else
        echo "There has been an error: "$O""
        echo "Exiting now..."
        exit
fi
    echo "Goodbye"

и пример подпроцесса2:

   #!/bin/bash
   ...preamble script setup items etc and then:

   java -jar /some/javaprog.java

Когда я выполняю родительский скрипт с помощью "sh lock.sh", он проходит через скрипт без ошибок и завершается. Первая проблема, которую я имею, заключается в том, что, если я снова загружаю скрипт, я получаю сообщение об ошибке, указывающее, что может работать только один экземпляр lock.sh. Что я должен был добавить в сценарий, который бы указывал, что процессы еще не завершены (вместо того, чтобы просто выйти и вернуть подсказку).

Однако, если subprocess1 работал сам по себе, lock.sh загрузил бы второй экземпляр subprocess1, потому что он не был заблокирован. Как можно было бы заблокировать дочерние сценарии и в идеале обеспечить, чтобы о разветвленных процессах также заботились? Если кто-то запустил subprocess1 в терминале или был запущенный экземпляр, если cron загружает lock.sh, я бы хотел, чтобы он потерпел неудачу при попытке загрузить его экземпляр subprocess1 и subprocess2, а не просто завершился, если cron попытался загрузить два lock.sh экземпляров.

Моя главная задача заключается в загрузке нескольких экземпляров ncftpget, который вызывается subprocess1, а затем, далее, третьего сценария, который я надеюсь включить, "subprocess2", который запускает java-программу, которая работает с загруженными файлами, и ncftpget, и java-программа могут не иметь параллельных процессов, не ломая много вещей. Но я не знаю, как их контролировать.

Я думал, что мог бы использовать что-то похожее на это в функции main() lock.sh:

 #This is where I try to lock the subscript
    pidfile="${subprocess1}"
    # lock it
    exec 200>$pidfile
    flock -n 200 || exit 1
    pid=$$
    echo $pid 1>&200

но я не уверен, как это включить.

0 ответов

Другие вопросы по тегам