在Linux下如何为一个目录下新创建的文件和子目录设置默认权限?

107
我有很多长时间运行的脚本和应用程序,它们将输出结果存储在几个用户共享的目录中。我想找到一种方法,确保在这个共享目录下创建的每个文件和目录都自动具有=rwxg=rwxo=r权限。
我知道我可以在各个脚本的开头使用umask 006,但我不喜欢这种方法,因为许多用户编写自己的脚本,可能会忘记设置umask。
我真正想要的是,如果在某个文件夹中,则文件系统能够在新创建的文件和目录上设置特定的权限。这个是否可能?
更新:我认为可以通过 POSIX ACLs 实现,使用默认ACL功能,但这有点超出了我的水平。如果有人能解释如何使用默认ACL,则可能会很好地回答这个问题。

1
POSIX ACL(Access Control List)很好用,但你会发现有60%的机器在某些文件系统上没有打开ACL,这取决于其Linux发行版本。这里有一个非常好的介绍和示例链接:http://www.suse.de/~agruen/acl/linux-acls/online/ - Tim Post
1
你是指我提供的那份文档吗?我还没有时间阅读,但感谢你提醒可用性问题。 - David Dean
1
Tim Post的评论中的链接似乎已经失效,但是由于互联网档案馆的存在,我可以查看它并验证http://www.vanemery.com/Linux/ACL/POSIX_ACL_on_Linux.html包含完全相同的文档。我将编辑问题以更新链接。 - rmunn
@rmunn 新的链接现在也是404错误。 - Borea Deitz
互联网档案馆(archive.org)的链接版本在此处(2012年12月4日)。 - Andrew Richards
5个回答

81
为了获得正确的所有权,您可以在目录上设置组setuid位。
chmod g+rwxs dirname
这将确保目录中创建的文件由组所有。 然后,您应确保每个人都使用umask 002或007或类似的内容运行-这就是为什么Debian和许多其他Linux系统默认配置为每个用户组的原因。如果用户的umask太强,则我不知道如何强制所需权限。

28
这并没有提供解决方案——他问的是权限而不是所有权,而唯一的方法是使用ACL(访问控制列表) - Yarin
3
“确保每个人都使用umask 002或007或类似的设置”- 这有点牵强。如何让Postfix、Dovecot、Clam和Spam Assassin都执行这个操作? - jww
3
+s 部分是什么作用?谢谢。 - tommy.carstensen
1
在这种情况下,它意味着设置组ID。也就是说,我们使用g+s来设置SGID位。 我之所以说“在这种情况下”,是因为+s与g结合用于组。+s也可用于设置SUID位(setuid)。 - Bastion

60

以下是如何在Linux下使用默认ACL进行操作:

首先,您可能需要在文件系统上启用ACL支持。如果您正在使用ext4,则已经启用。其他文件系统(例如ext3)需要使用acl选项挂载。在这种情况下,请将该选项添加到/etc/fstab中。例如,如果目录位于根文件系统上:

/dev/mapper/qz-root   /    ext3    errors=remount-ro,acl   0  1

然后重新挂载它:

mount -oremount /

现在,使用以下命令设置默认 ACL:

setfacl -dm u::rwx,g::rwx,o::r /shared/directory

现在位于 /shared/directory 目录下的所有新文件都应该具有所需的权限。当然,这也取决于创建文件的应用程序。例如,大多数文件一开始不会被任何人执行(取决于打开(2)或创建(2)调用的模式参数),就像使用umask时一样。一些实用程序,如 cptarrsync,将尝试保留源文件的权限,这可能会掩盖您的默认ACL,如果源文件没有组可写权限。

希望这可以帮到你!


似乎这仍需要所有用户的适当umask。 = / http://unix.stackexchange.com/questions/71743/using-setfacl-to-allow-group-members-to-write-to-any-file-in-a-directory - anatoly techtonik
2
@techtonik 正如我所写的那样,这取决于创建文件的应用程序。例如,如果您使用 cp,它将尝试复制源文件的权限。即使使用 umask 也无济于事。我曾经在 tar 中看到过同样的问题。请参见此问题 - pelle
1
是的,看起来问题在于应用程序强制将权限设置为 644,而我的 ACL 和 POSIX 权限设置都是 664。如果能够澄清这种回退机制,以帮助那些排除问题的人就好了,因为很多人甚至不知道 umask 的存在。 - anatoly techtonik
@techtonik 我的回答已经说了,在ext4上你不需要这个选项。无论如何,我现在已经编辑过了,使其更加清晰明了。关于umask,问题明确要求在没有使用umask的情况下如何实现。 - pelle
对于600,请使用以下命令:mkdir ~/.env && sed -i 's/defaults\t/defaults,acl\t/' /etc/fstab && mount -o,remount / && setfacl -dm u::rw,g::x,o::x .env - alchemy
显示剩余6条评论

5
在你的Shell脚本(或.bashrc)中,你可以使用以下命令:umask 022umask是一个控制如何设置新建文件的文件权限的掩码的命令。

1
这是不正确的,因为umask限制了权限,它无法添加权限。 - ACV
@ACV 你能详细说明一下吗?我尝试了这个方法,现在新创建的文件在我在.bashrc中使用"umask 002"时允许组成员拥有rw权限。 - Arthur Dent
3
umask 002 限制其他人的访问权限,但群组权限不变。请记住,这里的 ugo 表示用户、组和其他人。同时,要知道 umask 实际上是从默认权限中减去的意思。对于文件而言,666 - 002 意味着 664,也就是说群组权限没有受到影响。 - ACV

4

虽然有些不美观,但是您可以使用setfacl命令来实现您想要的功能。

在Solaris机器上,我有一个包含用户和组acl的文件。不幸的是,您必须列出所有用户(至少我没有找到其他方法使其工作):

user::rwx
user:user_a:rwx
user:user_b:rwx
...
group::rwx
mask:rwx
other:r-x
default:user:user_a:rwx
default:user:user_b:rwx
....
default:group::rwx
default:user::rwx
default:mask:rwx
default:other:r-x

将文件命名为acl.lst,并用真实的用户名替换user_X。

现在,您可以通过下面的命令在目录上设置这些ACL:

setfacl -f acl.lst /your/dir/here

如果所有用户都是同一组的成员,您可以不使用用户列表,而只使用组权限吗? - David Dean
我也曾经问过自己同样的问题。自从我设置这个以来已经有一段时间了。但是每次我得到一个新用户(与其他人在同一组),我都会忘记更新列表,然后就会收到关于新用户无法编写/删除文件的投诉。所以答案是:不行。 - innaM

0

我不认为这会完全满足你的需求,但我想提出来,因为我在其他答案中没有看到过。

我知道你可以使用-m选项在一行命令中创建带有权限的目录:

mkdir -m755 mydir

你也可以使用install命令:

sudo install -C -m 755 -o owner -g group /src_dir/src_file /dst_file

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接