Bash:如何在执行外部脚本时也锁定

Bash:如何在执行外部脚本时也锁定,bash,flock,Bash,Flock,下面是我的bash代码: ( flock -n -e 200 || (echo "This script is currently being run" && exit 1) sleep 10 ...Call some functions which is written in another script... sleep 5 ) 200>/tmp/blah.lockfile 我从两个shell连续运行脚本,只要第一个处于“sleep 5”

下面是我的bash代码:

(
flock -n -e 200 || (echo "This script is currently being run" && exit 1)
    sleep 10

    ...Call some functions which is written in another script...

    sleep 5

) 200>/tmp/blah.lockfile
我从两个shell连续运行脚本,只要第一个处于“sleep 5”状态,所有都会正常运行,这意味着另一个不会启动。但是,当第一次从另一个脚本(其他文件)执行代码时,第二次运行开始执行

所以我这里有两个问题:

  • 当脚本或其“子脚本”仍在运行时,应如何防止此脚本及其所有“子脚本”运行。 (除了“child”之外,我没有找到更适合运行其他脚本的表达式,很抱歉:))

  • 根据手册页,-n导致进程在无法获得锁时退出,但据我所知,它只是等待它运行。我错过了什么


  • 你的问题可能很平常。即

    false || ( exit 1 )
    
    不会导致脚本退出。相反,出口指示子shell退出。因此,将第一行更改为:

    flock -n -e 200 || { echo "This script is currently being run"; exit 1; } >&2
    

    威廉的回答是正确的。但是,如果必须使用子shell,则需要使用
    kill
    命令杀死子shell的父级。要获取父shell的PID,可以使用
    ps-p$$-oppid=
    。然而,他的答案是更干净的解决方案。@anishsane无论是
    bash
    ksh
    还是
    dash
    都有一个
    $PPID
    变量。我不知道它是否真的是标准的,但似乎非常兼容,而且你不需要额外的过程。哦,我完全错过了这一点。但我没有意识到的是:您只更改了一行,所以您的实现也使用了一个子shell,那么如何克服您描述的问题呢。(我试过了,效果很好,我很好奇它是怎么回事)。事实上,我不完全理解为什么手册页建议使用sub-shell,为什么在没有创建sub-shell的情况下sub-shell对我不起作用(我得到一个错误,即“200是一个糟糕的文件描述符”)。谢谢。区别在于我使用的是
    {}
    而不是
    ()
    。括号中的命令在子shell中运行,但按括号分组的命令在当前shell中运行。您也不需要在子shell中运行整个进程,但可以使用括号来对命令进行分组,但是
    200>/tmp/lockfile
    必须应用于对flock的调用,如果您只是放弃分组,您将得到一个
    错误的文件描述符。