我想确保系统的任何常规用户一次只能运行一个脚本。可以有多个用户登录,每个用户只能在其他用户运行的命令完成后才能运行命令。
很久以前,在 UNIX 上,我使用batch
具有正确的“仅一个任务”队列定义的命令来序列化脚本执行。它解决了很多锁管理问题(只需要在脚本中设置一个简单的超时)。
现在,在 Linux 上,该batch
命令的执行方式有所不同,每分钟运行一个任务,任务并行运行,直到达到 1.5 的平均负载。
我制作了自己的锁管理 shell 库来序列化执行,但我想知道是否有一个标准命令可以做到这一点。
答案1
flock
对此确实非常出色。您可以flock
在 shell 脚本的包装器中使用它,在命令行上使用它,或者将其合并到您的脚本本身中。
最好的一点flock
是,当它等待时,它不会在繁忙的循环中等待。
它也是总是当您的进程退出/退出时清除锁flock
。
如果进程在没有清理的情况下退出(或者如果出现内核恐慌或电源故障......),基于原子文件/目录创建的方法可能会被锁定。
flock
Linux 内核使用 进行清理工作。
从手册来看,
(
flock -s 200
# ... commands executed under lock ...
) 200>/var/lock/mylockfile
在这种形式中,您可以将特定的代码块包装在 shell 脚本中。
或者你可以像这样运行它,
/usr/bin/flock /tmp/lockfile command
如果你不想无限期地阻塞/等待,你可以指定一个超时:
-w --timeout <secs> wait for a limited amount of time
或者只使用非阻塞参数:
-n --nonblock fail rather than wait
答案2
也许您想要的是对用户可以运行的进程数量进行硬性限制?确保包含他们的 shell 进程以及任何其他必要的内容需要在他们的会议期间运行。
这可以在 /etc/security/limits.conf 中设置,添加一行:
testuser hard nproc 2
请注意,如果有太多东西试图同时运行,这将引发无法分叉的错误。将 2 更改为适合您的需要,并将 'testuser' 更改为您想要限制的用户。
答案3
使用mkdir
这是一个原子进程来锁定其他进程。当时只有一个人可以创建一个目录:
#!/bin/bash
if ! mkdir /tmp/TheLock 2> /dev/null ; then
echo Error, user \'$(stat -c %U /tmp/TheLock)\' has the task
else
echo Yes, I got it\!
sleep 1 # do stuff
rmdir /tmp/TheLock
fi
如果你首先运行脚本,它会读出:
Yes, I got it!
如果有人尝试同时运行它,输出将是:
Error, user 'Emmanuel' has the task