确保在给定时间只运行一个shell脚本实例的快速而简单的方法是什么?
我想阻止我的脚本一次运行多次.
我目前的做法是
为了防止进程挂起,我设置了一个cron作业,定期检查文件是否超过了最大允许的运行时间,如果文件仍然在运行,则会终止该进程.
是否存在我正在杀死错误进程的风险?
有没有更好的方法来执行这个整体?
我正在将flock()用于进程间命名的互斥锁(即某些进程可以决定对"some_name"进行锁定,这是通过在temp目录中锁定名为"some_name"的文件来实现的:
lockfile = "/tmp/some_name.lock";
fd = open(lockfile, O_CREAT);
flock(fd, LOCK_EX);
do_something();
unlink(lockfile);
flock(fd, LOCK_UN);
Run Code Online (Sandbox Code Playgroud)
应该在某个时候删除锁定文件,以避免使用数百个文件填充临时目录.
但是,此代码中存在明显的竞争条件; 进程A,B和C的示例:
A opens file
A locks file
B opens file
A unlinks file
A unlocks file
B locks file (B holds a lock on the deleted file)
C opens file (a new file one is created)
C locks file (two processes hold the same named mutex !)
Run Code Online (Sandbox Code Playgroud)
有没有办法在某些时候删除锁定文件而不引入这种竞争条件?
以下锁定机制用于防止cron作业并发运行:
#!/bin/bash
echo "Before critical section"
(
flock -e 200
echo "In critical section"
sleep 5
) 200>/tmp/blah.lockfile
echo "After critical section"
Run Code Online (Sandbox Code Playgroud)
当一起运行两个实例时,后者一直等到第一个完成,然后运行.这可能导致等待运行的脚本积压.
如何更改此脚本以便在flock无法获取锁定时终止脚本?我试过-n没有成功.
这是使用文件系统创建锁的标准方法.例如,visudo使用它:
[ -f ".lock" ] && exit 1
touch .lock
# do something
rm .lock
Run Code Online (Sandbox Code Playgroud)
1)我很困惑,因为有竞争条件,但Linux使用它
2)有没有更好的方法来锁定shell中的文件?
3)或者我必须使用目录吗?
找到解决方案:man lockfile.
我有一个bash脚本我想从cron每5分钟运行一次...但是有可能前一次运行的脚本还没有完成......在这种情况下,我希望新的运行只是退出.我不想只依赖/ tmp中的锁文件..我想确保在我尊重锁文件(或其他)之前该进程实际上正在运行...
这是我到目前为止从互联网上窃取的内容......我如何让它变得有点聪明?还是有一种完全不同的方式更好?
if [ -f /tmp/mylockFile ] ; then
echo 'Script is still running'
else
echo 1 > /tmp/mylockFile
/* Do some stuff */
rm -f /tmp/mylockFile
fi
Run Code Online (Sandbox Code Playgroud) 我已经实现了一个文件锁定机制,沿着linux手册页中"open"的建议,其中指出:
想要使用lockfile执行原子文件锁定的可移植程序,并且需要避免依赖对O_EXCL的NFS支持,可以在同一文件系统上创建一个唯一的文件(例如,合并主机名和PID),并使用link(2)来建立一个锁定文件的链接.如果link(2)返回0,则锁定成功.否则,在唯一文件上使用stat(2)来检查其链接计数是否已增加到2,在这种情况下锁定也是成功的.
这似乎完美无缺,但是为了在我的测试中获得100%的代码覆盖率,我需要覆盖链接数增加到2的情况.
我已经尝试使用谷歌搜索,但我似乎能够找到的所有内容都是上面反复引用的"它完成的方式".
任何人都可以向我解释一下哪些情况会导致链接失败(返回-1),但链接数增加到2?