`command .*` 作用于父目录

g00*_*0ze 22 shell bash directory wildcards dot-files

我们团队中的某个人想要递归更改用户主目录中所有隐藏目录的用户权限。为此,他执行了以下命令:

cd /home/username
chown -R username:groupname .*
Run Code Online (Sandbox Code Playgroud)

当我们意识到他实际上递归地更改了 /home 中所有用户目录的权限时,我们感到非常惊讶,因为.*equals to..也是如此。不过,您会在 Linux 中预料到这种行为吗?

pgo*_*etz 17

当我尝试将 .* 用于任何事情时,我总是会感到焦躁,很久以前就切换到使用字符类:

chown -R username.groupname .[A-Za-z]*
Run Code Online (Sandbox Code Playgroud)

是我会如何做到这一点。

编辑:有人指出这不会得到,例如._Library. 要使用的捕获所有字符类将是

chown -R username.groupname .[A-Za-z0-9_-]*
Run Code Online (Sandbox Code Playgroud)

  • 为什么不直接使用`.[^.]*`? (20认同)
  • 另一个更常见的选择:`.??*` 这将包括数字和其他可能以文件名结尾的符号:) (13认同)
  • 这不会得到名称类似 `.....` 的文件。 (6认同)
  • `.??*` 会遗漏任何单个字符名称的点文件;例如`.a`。诚然,这种情况不太可能存在,但值得指出。 (2认同)

cho*_*oba 10

使用扩展的通配符 ( shopt -s extglob),您可以使用

.!(.|)
Run Code Online (Sandbox Code Playgroud)

即点后面没有点或什么都没有。


Gil*_*il' 10

字符.只从通配符匹配排除时,它的文件名的第一个字符,它会通过通配符匹配。在模式中.**匹配以.,开头的字符串,所以.*包含..(以及.,*匹配空字符串)。这是模式匹配规则的直接结果,尽管它可能很烦人。

例外并系统地排除.和排除..匹配是有意义的,但这不是历史上的做法,因此许多 Bourne/POSIX shell(sh, dash, bash, AT&T ksh, yash...)包括它们, (t)csh 甚至鱼 1.x。一些炮弹排除...所有通配符匹配:zsh中,pdksh程序/豪华/ mksh(与AT&T的ksh),鱼2.0?

如果您设置GLOBIGNORE为任何非空值,bash将切换为方便但非标准的排除.和排除..匹配项的行为。设置GLOBIGNORE也会关闭排除点文件的行为;与GLOBIGNORE='.*',您将获得./*排除点文件的通常行为,但./.*仅匹配点文件而不匹配.or ..。设置GLOBIGNORE=.:..(或GLOBIGNORE=../*匹配所有文件,包括点文件,但不包括...

在 ksh93 中,设置FIGNORE='@(.|..)'为排除.和排除..匹配但包含点文件。因此.*将扩展为点文件但不包括....

无需求助于特定于 shell 的功能,您可以将点文件与以下两个全局匹配:

.[!.]* ..?*
Run Code Online (Sandbox Code Playgroud)

以及所有文件(不包括...)具有以下三个 glob:

..?* .[!.]* *
Run Code Online (Sandbox Code Playgroud)

但是您需要小心,因为一个或多个 glob 可能不匹配任何文件,这会导致相应的模式保持未扩展。

为了避免意外,使用find. find从不递归到父目录(除非被告知遵循符号链接)。

find /home/username/. -name . -o -prune -name '.*' -exec chown -R username:groupname {} +
Run Code Online (Sandbox Code Playgroud)


Chr*_*own 6

考虑使用find(-maxdepth是一个非 POSIX 扩展,但它应该在 Linux 上很容易获得):

find . -maxdepth 1 -type d -name '.*' -exec chown -R user:group {} +
Run Code Online (Sandbox Code Playgroud)


Joh*_*ith 6

如果目录本身与其文件(隐藏或不隐藏)共享相同的所有权,那么您可以chown递归它。-R在当前目录中递归时,该选项将包含隐藏文件。

$ chown user:group . -R # Will include all hidden files
Run Code Online (Sandbox Code Playgroud)