如何使chown递归工作?


285

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

chown -R someuser:somegroup *.pdf

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

根据的手册页chown-R应表示递归:

-R, --recursive
          operate on files and directories recursively

我想念什么?

Answers:


291

递归模式仅适用于目录,不适用于文件。通过使用glob'* .pdf',外壳程序将文件列表传递给chown,后者将看到这些文件,并更改对其看到的文件的权限,仅此而已。

请记住,在shell中,glob是由shell而不是命令求值的。如果glob与文件匹配,则将它们传递给命令,并且该命令永远不会知道glob存在。(这与Windows Command提示符用于执行操作的方式不同)。如果您有目录,其内容类似于:

machine:$ ls -F
file1.pdf  file2.pdf  other.txt  subdir/

然后您输入:

chown -R someuser:somegroup *.pdf

外壳程序将首先列出该列表:file1.pdf file2.pdf

然后运行命令:

chown -R someuser:somegroup file1.pdf file2.pdf

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

要执行所需的操作,可以将'* .pdf'用作该目录和子目录的模式,可以使用find,它可以找到与文件名模式(或许多其他criterea)匹配的文件并传递给子命令

find . -type f -name '*.pdf' | xargs chown someuser:somegroup

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

因为文件名中可能包含空格,所以您想使用一个技巧使它与空格一起使用是安全的:

find . -type f -name '*.pdf' -print0 | xargs -0 chown someuser:somegroup

在bash 3及更低版本中,这是您需要执行的操作。bash 4(带有shopt -s globstar)和其他shell 提供了更强大的glob 。在zsh中,使用递归glob相同**

chown -R someuser:somegroup ./**/*.pdf

1
编辑以反映具有shopt -s globstar递归遍历的bash 4 。
kojiro 2011年

@kojiro谢谢!如您所知,我仍然使用bash3
Rich Homolka

2
根据原始海报显示的手册页,我发现chown -R确实改变了文件夹和文件的所有者。无需查找。使用
Mint15。– gwideman

@gwideman我知道这很旧了...但是,是的,-R当然是递归的。OP只是遇到了一个非常具体的递归类型问题,即扩展名和“文件类型就是文件”被过滤掉了
Rich Homolka

@RichHomolka啊。OP表示这些文件位于名为“ pdfs”的目录中,因此我认为问题在于如何将pdfs指定为要递归的目录,并且其中包含的所有文件均为pdfs,因此无需专门选择它们。但是,如果您的工作是仅选择pdf文件,而其他文件保持不变,则您可能是对的。
gwideman

52
chown -R someuser:somegroup /your/folder/here/*

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


2
莫名其妙地sudo chown -R user ./为我工作,但sudo chown -R user ./*没有
Slav

1
我知道这很老了,但是尽管这回答了标题,却没有回答问题。这实际上比OP已经尝试的要差一些。
Rich Homolka '18

2
@RichHomolka仅仅因为问题标题而来到这里,我很高兴找到这个答案。
费利克斯·加侬-格雷尼尔

@FélixGagnon-Grenier足够公平。如果这个答案对您有用,我会很高兴。但这对原始问题不起作用。
Rich Homolka

这对于点文件(例如)似乎无效.env
瑞安

14

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

find . -name '*.pdf' -exec chown someuser:somegroup {} +

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


1
我必须查找+整洁的性能技巧。-exec command {} +-exec操作的此变体在选定的文件上运行指定的命令,但是通过在末尾附加每个选定的文件名来构建命令行。该命令的调用总数将大大少于匹配文件的数目。命令行的构建与xargs构建命令行的方式几乎相同。命令中仅{}允许的一个实例。该命令在起始目录中执行。
Patrick M

@PatrickM + vs的另一个(次要)优势;....再加上不是外壳元字符,也不必逃脱
Rich Homolka

6

命令

chown -R someuser:somegroup *.pdf

如果目录名称以.pdf结尾,则仅递归目录。您需要类似:

find . -name "*.pdf" -exec chown someuser:somegroup {} \;

从技术上讲,它只会下降一级。无论您是否称呼真正的递归都是用户的一项练习:)
Rich Homolka

1

要递归更改目录的所有权,只需使用:

sudo chown -R <username>:<groupname> <dir name>

这里username =应该是目录所有者的新用户

groupname =应该是目录所有者的新组

每个文件/目录都有一个用户所有者和一个组所有者


这不符合OP的要求。OP要求一组特定的文件,这将更改所有内容的所有权。
Rich Homolka


0

要成为目录中所有文件的所有者,请使用

find directory -type f -name '*' | sudo xargs -d '\n' chown $USER

代替

sudo chown $USER directory\*

要么

sudo chown --recursive $USER directory

如果*产生的参数过多(目录中的文件过多),则可能不起作用,或者它们不能分别满足您的要求。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.