我怎样才能让 chown 递归工作?

Nat*_*ong 357 unix permissions

我有一个名为的目录 pdfs,其中包含一堆子目录和子目录。我想更改所有子文件夹中所有 PDF 文件的所有权。我刚试过这个:

chown -R someuser:somegroup *.pdf
Run Code Online (Sandbox Code Playgroud)

...但它没有改变子目录中 PDF 的所有权。用户和组确实存在。

根据手册页的chown-R应该意味着递归:

-R, --recursive
          operate on files and directories recursively
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

Ric*_*lka 363

递归模式仅适用于目录,不适用于文件。通过使用 glob '*.pdf',shell 将文件列表传递给 chown,chown 看到这些文件,并更改它看到的文件的权限,就是这样。

请记住,在 shell 中,glob 是由 shell 计算的,而不是命令。如果 glob 匹配文件,它们将被传递给命令并且命令永远不知道存在一个 glob。(这与 Windows 命令提示符用来做事的方式不同)。如果您有一个目录,其内容类似于:

machine:$ ls -F
file1.pdf  file2.pdf  other.txt  subdir/
Run Code Online (Sandbox Code Playgroud)

你输入:

chown -R someuser:somegroup *.pdf
Run Code Online (Sandbox Code Playgroud)

外壳首先会列出:file1.pdf file2.pdf

然后运行你的命令:

chown -R someuser:somegroup file1.pdf file2.pdf
Run Code Online (Sandbox Code Playgroud)

看,没有可供 -R 操作的目录。它按照您的要求执行 - 在命令行上更改两个文件的所有权,忽略那个古怪的 -R 标志。

为了做你想做的事,使用 '*.pdf' 作为这个目录和子目录的模式,你可以使用find,它可以找到匹配文件名模式(或许多其他标准)的文件并传递给子命令

find . -type f -name '*.pdf' | xargs chown someuser:somegroup
Run Code Online (Sandbox Code Playgroud)

这从当前目​​录 '.' 开始 查找名称模式的文件(文件类型 f),'*.pdf'然后传递给 xargs,后者为 chmod 构造一个命令行。请注意 pattern 周围的引号'*.pdf',请记住,如果可以,shell 将创建一个 glob,但是您希望将模式传递给find,因此您需要引用它。

因为文件名中可能有空格,所以你想使用一个技巧来确保文件名与空格的安全:

find . -type f -name '*.pdf' -print0 | xargs -0 chown someuser:somegroup
Run Code Online (Sandbox Code Playgroud)

在 bash 3 及更低版本中,这是您需要的方式。bash 4 (with shopt -s globstar) 和其他 shell 中提供了更强大的通配符。在 zsh 中相同,使用递归 glob **

chown -R someuser:somegroup ./**/*.pdf
Run Code Online (Sandbox Code Playgroud)

  • 根据原始海报显示的手册页,我发现 chown -R 确实更改了文件夹和文件的所有者。没必要找。使用薄荷 15。 (2认同)

小智 78

chown -R someuser:somegroup /your/folder/here/*
Run Code Online (Sandbox Code Playgroud)

这将 chown 应用于指定文件夹的所有文件和所有子目录和子子目录。小心使用。

  • @RichHomolka 仅仅因为问题标题被带到这里,我很高兴找到这个答案。 (3认同)
  • 不知何故`sudo chown -R user ./` 对我有用,但`sudo chown -R user ./*` 没有 (2认同)
  • 我知道这已经很旧了,但这虽然回答了标题,但没有回答问题。这实际上比 OP 已经尝试过的要糟糕一些。 (2认同)

小智 15

您可以使用该find实用程序:

find . -name '*.pdf' -exec chown someuser:somegroup {} +
Run Code Online (Sandbox Code Playgroud)

请不要忘记周围的引号*.pdf。否则外壳将尝试扩展它。这意味着外壳已经将替换*.pdf为当前目录中找到的所有 PDF 文件的名称。但这不是你想要的。您要查找位于子目录中的 PDF 文件。顺便说一句:这也是你的chown命令的问题。


Mik*_*ott 6

命令

chown -R someuser:somegroup *.pdf
Run Code Online (Sandbox Code Playgroud)

如果目录名称以 .pdf 结尾,则只会向下递归目录。你需要这样的东西:

find . -name "*.pdf" -exec chown someuser:somegroup {} \;
Run Code Online (Sandbox Code Playgroud)