如何通过目录名称更改目录的所有者和组?

如何通过目录名称更改目录的所有者和组?

我有一个 Ubuntu 16.04 Nginx 服务器环境,文档根目录下有几个 CMS (WordPress) 网站。

所有站点目录www-data都递归地具有所有者和组。


根据我得到的一些安全咨询,这是有问题的,因为来自一个站点的数据可能会更改任何其他相邻站点(例如,安装在其中一个站点的 CMS 中的恶意模块)。

我认为解决方案是更改此命令,我总是在添加新站点后运行该命令(以及在更改所有者和组的更新后在 cron 中运行):

chown -R www-data:www-data /var/www/html/*

某些条件命令不仅将这些特征更改为www-data站点目录的实际名称。

为了澄清,每个站点目录的所有者应该是domain.tld并且组也应该是domain.tld(我总是根据站点的domain.tld命名站点目录)。

这样的条件命令是什么?


注意:Nginx 用户和目录/var/www/html/都将保留为www-data:www-data.

G-Man 更新:

我还没有测试,但我认为如果你${domain}作为变量的第一个参数传递($1),这是很好的:

chown -R ${domain}:${domain} ${domain}/*

虽然我会保留它:

chown -R ${domain}:www-data ${domain}/*

当然,adduser ${domain} --disabled-password --disabled-login如果没有完成的话,之前是需要的。

答案1

我可能错过了一些东西,但这看起来很简单:

$ cd /var/www/html
$ for dir in *
do
    chown -R "$dir:$dir" "$dir"
done

如果您担心这些命令的正确性,可以插入以下单词echo之前chown,例如,

$ cd /var/www/html
$ 表示 * 中的目录
    回声chown -R "$dir:$dir" "$dir"
完毕

让它告诉你chown它将要执行什么命令,而不需要实际执行它们。这个技巧适用于整个答案,事实上,适用于大多数 shell 脚本解决方案(即其他问题)。

如果你想用一行来做,

$ cd /var/www/html  &&  for d in *; do chown -R "$d:$d" "$d"; done

我这样做是cd为了避免复杂性另一个答案 拥抱了。如果你这样做

$ for dir in /var/www/html/*

thendir将被设置为/var/www/html/domain1/var/www/html/domain2/var/www/html/domain3等,这对于操作目录来说很好,但不会为您提供 所需的用户名和组名chown。另一个答案使用相当复杂(且不完全可靠)的 awk过程将目录路径的最后一级(即目录名,也是用户名;例如,domain1)与路径的其余部分分开。幸运的是,我们可以完全在 shell 中完成等效的操作(但更好一些),如下所示:

$ for dir in /var/www/html/*
do
    owner="${dir##*/}"
    chown -R "$owner:$owner" "$dir"
done

${dir##*/}是一种特殊形式参数扩展$dir它获取最后一个/(斜杠)字符 的值并删除所有内容(包括)。当然,这仅留下目录库姓名,即用户名,因此我们将其分配给owner并在chown。请注意,这段代码是符合 POSIX 标准 并且应该可以在任何符合 POSIX 标准的 shell 中工作;与本网站上的一些答案不同,它不依赖于 bash。

如果你想做在一行中,

$ for d in /var/www/html/*; do o="${d##*/}"; chown -R "$o:$o" "$d"; done

当然,如果您只是担心不希望更改主 shell 的工作目录,那么您可以在子 shell 中执行第一个命令:

$ (cd /var/www/html  &&  for d in *; do chown -R "$d:$d" "$d"; done)

不言而喻(但无论如何我都会这么说),这要求您在运行任何这些命令之前定义名为 、 、 等domain1domain2用户(和组)。domain3如果您有一个添加新站点的脚本,那么在运行chown.如果您确实chown使用不是定义的用户名的名称运行,它将给您一条invalid user错误消息。

相关内容