Bash文件锁定包括子进程的flock

时间:2016-05-12 20:31:06

标签: bash cron 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。

当我运行下面的脚本时,正在创建锁,但我认为我正在分配下标,而我正在尝试确保这些脚本不会运行多个实例。

#!/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并登录到远程服务器以获取一些文件。完成后,连接关闭。我想通过cron每15分钟进行一次subprocess1。我已经成功完成了这项工作,但有时会抓住很多文件并且工作时间超过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"

和subprocess2的一个例子是:

   #!/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时退出实例

我主要担心的是加载由subprocess1调用的ncftpget的多个实例,然后是第三个我希望合并的脚本“subprocess2”,它启动一个处理下载文件的java程序,ncftpget和java程序不能没有破坏很多东西的并行进程。但我对如何充分控制它们感到茫然。

我以为我可以在lock.sh的main()函数中使用类似的东西:

 #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 个答案:

没有答案