【问题标题】:flock permission denied bash群权限被拒绝bash
【发布时间】:2014-06-21 13:37:23
【问题描述】:

我写了一个小测试脚本来防止我的脚本与flock同时运行:

#!/bin/bash

scriptname=$(basename $0)
lock="/var/run/${scriptname}"
umask 0002

exec 200>$lock
flock -n 200 || exit 1

## The code:
sleep 60
echo "Hello world"

当我与我的用户一起运行脚本并尝试与另一个用户一起运行脚本时,我收到了锁定文件的以下错误消息。

/var/run/test.lock: Permission denied

有什么想法吗?

亲切的问候, 安德烈亚斯

【问题讨论】:

  • 您说:“当我与我的用户一起运行脚本并尝试与另一个用户一起运行脚本时”:问题,您是否同时运行两者?或者问题是即使在您的用户运行后执行完成后,以及其他一些尝试运行,也会出现此错误?
  • 文件的组是什么?第二个用户是否在该组中?
  • 脚本以 user1 身份运行,当我与 user2 同时运行时收到错误消息。
  • 其他用户在同一个组中。文件权限是 -rw-r--r--
  • 你不是在你的脚本中停下来,即让两个用户同时运行它吗?我猜你正在使用羊群?现在我要问你,当 user1 运行它时会发生什么,而 user2 在 60 秒后运行它,即 user1 的实例完成?>???????它运行没有问题>?

标签: bash permissions flock


【解决方案1】:

通过sudo /path/script.sh 而不是仅/path/script.sh 运行整个脚本

【讨论】:

  • 或通过sudo /path/script.sh运行整个脚本
  • sudo /path/script.sh 一起工作,但我会在脚本中更好地处理它,然后当我写lock="sudo /var/run/${scriptname}" 时出现以下错误:$lock: ambiguous redirect
  • 通过sudo /path/script.sh 命令运行您的脚本。不要更改脚本中的任何内容。
【解决方案2】:

在评论中,您提到了这一点

其他用户在同一组中。文件权限为-rw-r--r--

换句话说,只有第一个用户对锁文件有权限。

但是,您的脚本可以:

exec 200>$lock

试图打开锁文件以进行写入。因此出现“权限被拒绝”错误。

打开文件进行写入的好处是,如果文件不存在也不会失败,但这也意味着如果正在运行脚本,您将无法轻易预测文件的所有者是谁由多个用户同时进行。 [1]

在大多数 linux 发行版中,umask 将设置为0022,这会导致新创建的文件具有rw-r--r-- 权限,这意味着只有创建文件的用户才有写权限。这是合理的安全策略,但使用在两个或多个用户之间共享的锁定文件会变得复杂。如果用户在同一个组中,您可以调整您的 umask,以便创建具有组写入权限的新文件,记住之后将其设置回来。例如(未经测试):

OLD_UMASK=$(umask)
umask 002
exec 200>"$lock"
umask $OLD_UMASK

或者,您可以应用只有读取权限的锁 [2],注意确保首先创建文件:

touch "$lock" 2>/dev/null # Don't care if it fails.
exec 200<"$lock"          # Note: < instead of >

注意事项:

[1]:exec 200&gt;file 的另一个问题是如果文件确实 存在,它将截断文件,因此它只适用于空文件。一般来说,您应该使用&gt;&gt;,除非您确定该文件不包含任何有用信息。

[2]:flock 不关心文件以何种模式打开。有关详细信息,请参阅man 1 flock

【讨论】:

    【解决方案3】:

    我试图对具有系统帐户共享组权限的文件使用flock。由于更新了内核,Ubuntu 19.10 中的访问权限发生了变化。您必须以拥有文件的用户身份登录,而不是以组与文件权限匹配的用户身份登录。甚至 sudo -u 也会显示“权限被拒绝”或“此帐户当前不可用”。它会影响 fifo 文件,例如flock 命令使用的文件。

    The reason for the change 是由于安全漏洞造成的。

    There is a workaround 恢复旧行为:

    使用内容创建/etc/sysctl.d/protect-links.conf

    fs.protected_regular = 0

    然后重启procps:

    sudo systemctl restart procps.service

    【讨论】:

      猜你喜欢
      • 2016-01-15
      • 2011-08-20
      • 1970-01-01
      • 1970-01-01
      • 2022-11-22
      • 2015-04-15
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      相关资源
      最近更新 更多