相反,如何仅对文件进行chmod(递归)而不包含目录?
#1 楼
递归地授予目录读取和执行特权:find /path/to/base/dir -type d -exec chmod 755 {} +
递归地授予文件读取特权:
find /path/to/base/dir -type f -exec chmod 644 {} +
或者,如果要处理的对象很多:
chmod 755 $(find /path/to/base/dir -type d)
chmod 644 $(find /path/to/base/dir -type f)
或者,减少
chmod
的产生:find /path/to/base/dir -type d -print0 | xargs -0 chmod 755
find /path/to/base/dir -type f -print0 | xargs -0 chmod 644
评论
前两个示例对于文件过多的目录失败:-bash:/ bin / chmod:参数列表过长。最后一个命令可用于许多文件,但是在使用sudo时,必须小心将其放在xargs之前而不是chmod上:find / path / to / base / dir -type d -print0 |苏多xargs -0 chmod 755
– Agargara
17年11月7日在1:06
还要注意,这些命令包含基本目录。因此,在上面的示例中,dir也将设置为755。
–CenterOrbit
18年1月16日,0:16
chmod ... $(查找/ path / to / base / dir -type ...)对于名称中带有空格的文件名失败。
– Dan Dascalescu
18年2月6日,下午1:58
我认为关于文件名中的空格和符号和文件数的最正确(但不是最快)的版本是/ path / to / base / dir -type d -exec chmod 755 {} \; (找到/ path / to / base / dir -type f -exec chmod 644 {} \;)。
– Peter K
18年2月21日在11:49
请注意,这仅到达它可以读取的第一层。您将不得不执行几次,以更深入地了解目录树。
–汉克·波利(Henk Poley)
19年4月14日在18:56
#2 楼
发生这种情况的常见原因是将目录设置为755,但将文件设置为644。在这种情况下,比nik的find
示例要快一些的方法:chmod -R u+rwX,go+rX,go-w /path
含义:
-R
=递归; u+rwX
=用户可以读取,写入和执行; go+rX
=组并且其他人可以读取和执行; go-w
=组而其他人则不能编写这里要注意的重要一点是,大写
X
的行为与小写x
不同。在手册中,我们可以阅读:如果文件是目录,或者任何执行/搜索位设置为原始(未修改)模式,则执行/搜索位。
评论
-R =递归; u + rwX =用户可以读取,写入和执行; go + rX = group,其他人可以读取和执行; go-w =小组,其他人不能写
–släcker
2010年1月6日7:08
当有人完成chmod -R 777时,此模式无法解决这种情况,因为+ X选项不会重置文件上现有的执行位。使用-x将重置目录,并阻止其进入目录。
–安德鲁·维特(Andrew Vit)
2012年8月7日在4:57
@ ring0:我无意按字面意义回答问题-nik已经做得很好。我为最常见的情况指出了一种更便宜的解决方案。是的,您确实使用X获得了对文件和目录的不同权限,如注释中所述。
– bobince
2012年10月28日在1:05
go + rX,go-w-> go = rX是吗?
– Pierre de LESPINAY
2014-09-22 14:24
您还可以结合使用chmod u-x,u + X等来删除文件的执行位,但将其添加到目录中。
– w0rp
16年4月4日在18:27
#3 楼
如果要确保文件设置为644,并且路径中有包含execute标志的文件,则必须先删除execute标志。 + X不会从已有的文件中删除执行标志。示例:
chmod -R ugo-x,u+rwX,go+rX,go-w path
更新:这似乎失败了,因为第一个更改(ugo-x)使目录不可执行,因此其下的所有文件都不会更改。
评论
这对我有用,我不明白为什么不这样做。 (当然,如果您只是执行chmod -R ugo-x路径,则可能会出现问题。但是在尝试进入每个目录之前,complete命令将在每个目录上执行chmod u + rwX。)但是,我相信chmod R u = rw,go = r,a + X路径就足够了-而且更短。
–斯科特
2014年7月8日,0:25
我发现这工作正常;输入目录没有问题
–有人支持Monica
18年6月16日在12:54
整洁,这很好用-
– Jesse C
4月8日23:43
#4 楼
我决定为此写一个小脚本。用于目录和/或文件的递归chmod脚本—要点:
chmodr.sh
#!/bin/sh
#
# chmodr.sh
#
# author: Francis Byrne
# date: 2011/02/12
#
# Generic Script for recursively setting permissions for directories and files
# to defined or default permissions using chmod.
#
# Takes a path to recurse through and options for specifying directory and/or
# file permissions.
# Outputs a list of affected directories and files.
#
# If no options are specified, it recursively resets all directory and file
# permissions to the default for most OSs (dirs: 755, files: 644).
# Usage message
usage()
{
echo "Usage: q4312078q PATH -d DIRPERMS -f FILEPERMS"
echo "Arguments:"
echo "PATH: path to the root directory you wish to modify permissions for"
echo "Options:"
echo " -d DIRPERMS, directory permissions"
echo " -f FILEPERMS, file permissions"
exit 1
}
# Check if user entered arguments
if [ $# -lt 1 ] ; then
usage
fi
# Get options
while getopts d:f: opt
do
case "$opt" in
d) DIRPERMS="$OPTARG";;
f) FILEPERMS="$OPTARG";;
\?) usage;;
esac
done
# Shift option index so that now refers to the first argument
shift $(($OPTIND - 1))
# Default directory and file permissions, if not set on command line
if [ -z "$DIRPERMS" ] && [ -z "$FILEPERMS" ] ; then
DIRPERMS=755
FILEPERMS=644
fi
# Set the root path to be the argument entered by the user
ROOT=
# Check if the root path is a valid directory
if [ ! -d $ROOT ] ; then
echo "$ROOT does not exist or isn't a directory!" ; exit 1
fi
# Recursively set directory/file permissions based on the permission variables
if [ -n "$DIRPERMS" ] ; then
find $ROOT -type d -print0 | xargs -0 chmod -v $DIRPERMS
fi
if [ -n "$FILEPERMS" ] ; then
find $ROOT -type f -print0 | xargs -0 chmod -v $FILEPERMS
fi
它基本上它具有递归chmod的功能,但也为命令行选项(设置目录和/或文件权限,或者排除两者都提供了一定的灵活性)会自动将所有内容重置为755-644。它还会检查一些错误情况。
我也在我的博客上写过它。
评论
有没有办法防止文件夹。从获得许可更改?
– MaXi32
6月23日0:50
#5 楼
递归授予目录读取和执行特权:find /path/to/base/dir -type d -exec chmod 755 {} \;
递归授予文件读取特权:
find /path/to/base/dir -type f -exec chmod 644 {} \;
迟一点永远不要让我在正确性方面提升nik的答案。我的解决方案比较慢,但是它可以处理任意数量的文件,并且文件名中可以包含任何符号,并且您可以正常地使用sudo运行它(但是请注意,它可能会使用sudo查找不同的文件)。
评论
这是nik答案的降级。您为什么认为nik的答案有什么问题?
–斯科特
18-10-9在23:06
@ Scott,nik的答案失败,其中包含(非常)大量的文件。
– Peter K
18-10-25在14:54
我有99%的确定您弄错了。您可以提供任何证据支持您的主张吗?
–斯科特
18-10-25在23:56
是的,看来我确实错了。 find ... +似乎将行分成多个命令,不错!
– Peter K
18-10-28在13:40
#6 楼
试试这个python脚本;它不需要任何进程,并且每个文件只需要两个syscall。除了用C语言实现之外,这可能是最快的实现方式(我需要用它来修复包含1500万个文件的文件系统,设置为777)
#!/usr/bin/python3
import os
for par, dirs, files in os.walk('.'):
for d in dirs:
os.chmod(par + '/' + d, 0o755)
for f in files:
os.chmod(par + '/' + f, 0o644)
在我的情况下,由于对某些特殊文件进行格式化失败,因此需要在最后一个chmod周围进行try / catch。
#7 楼
我发布解决方案是因为我看不到仅使用chmod
的几乎所有情况的解决方案:仅chmod:对文件和目录的平滑权限
对于我的示例,我创建了多个具有不同权限的文件:
> tree -p chmodtests/
chmodtests/
├── [drwxr-xr-x] aa/
│ ├── [drwxr-xr-x] a1/
│ │ ├── [-r--r--r--] read_only
│ │ ├── [-rw-rw-rw-] read_w
│ │ └── [-rwxrwxrwx] read_wx*
│ ├── [drwxr-xr-x] a2/
│ ├── [-r--------] read_only
│ ├── [-rw-------] read_w
│ └── [-rwx------] read_wx*
└── [drwxr-xr-x] bb/
4 directories, 6 files
然后应用以下命令:
chmod -vR a=r-wx,u=wr,a+X chmodtests/
输出:
mode of 'chmodtests/' retained as 0755 (rwxr-xr-x)
mode of 'chmodtests/aa' retained as 0755 (rwxr-xr-x)
mode of 'chmodtests/aa/a1' retained as 0755 (rwxr-xr-x)
mode of 'chmodtests/aa/a1/read_only' changed from 0444 (r--r--r--) to 0644 (rw-r--r--)
mode of 'chmodtests/aa/a1/read_w' changed from 0666 (rw-rw-rw-) to 0644 (rw-r--r--)
mode of 'chmodtests/aa/a1/read_wx' changed from 0777 (rwxrwxrwx) to 0644 (rw-r--r--)
mode of 'chmodtests/aa/read_only' changed from 0400 (r--------) to 0644 (rw-r--r--)
mode of 'chmodtests/aa/a2' retained as 0755 (rwxr-xr-x)
mode of 'chmodtests/aa/read_w' changed from 0600 (rw-------) to 0644 (rw-r--r--)
mode of 'chmodtests/aa/read_wx' changed from 0700 (rwx------) to 0644 (rw-r--r--)
mode of 'chmodtests/bb' retained as 0755 (rwxr-xr-x)
结果:所有文件均为644;所有Dirs均为755
> tree -p chmodtests/
chmodtests/
├── [drwxr-xr-x] aa/
│ ├── [drwxr-xr-x] a1/
│ │ ├── [-rw-r--r--] read_only
│ │ ├── [-rw-r--r--] read_w
│ │ └── [-rw-r--r--] read_wx
│ ├── [drwxr-xr-x] a2/
│ ├── [-rw-r--r--] read_only
│ ├── [-rw-r--r--] read_w
│ └── [-rw-r--r--] read_wx
└── [drwxr-xr-x] bb/
说明部分
tl; dr说明:
此命令删除对文件和目录的所有执行/搜索,然后仅对dirs添加执行/搜索
chmod -vR
:冗长且递归a=r-wx
:a
:表示所有(用户,组和其他)=
:将权限设置为(请勿添加或删除)r-wx
:只读权限u=wr
:用户可以读写a+X
:仅添加执行/搜索目录(适用于所有类型u,g,o)其他示例
现在假设我只希望文件600和目录dirs:
chmod -vR a=-rwx,u=rw,u+X chmodtests/
限制
使用这种方法,您不能分别为文件和目录设置r和w。
例如您不能拥有以下内容
drwxr-xr-x dir/
-r-------- dir/myfile
hth
#8 楼
您还可以使用tree
:tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 ""' -- '{}'
,如果还要查看文件夹,请添加回显
tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "" && echo' -- '{}'
评论
@Scott 1)你对+ x是正确的,我改为755; 2)3)为了解决这个问题,我将占位符放在单引号中,例如“ {}”
–爱德华(Eduard Florinescu)
18-10-10在5:53
@Scott我同意这不是最好的答案,但也很慢,但出于“指导性”目的将离开此处,评论还将进一步解释,人们也可以了解xargs问题。文件名中的单引号本身就是许多命令和脚本的问题,这就是为什么我列出所有包含单引号的文件并将其删除的原因(我的意思是引号)
–爱德华(Eduard Florinescu)
18-10-10在6:16
@Scott在我的系统上,我搜索了所有包含单引号的文件并替换了单引号
–爱德华(Eduard Florinescu)
18-10-10在6:42
@Scott您将如何解决xargs不能正确解决单引号的问题?
–爱德华(Eduard Florinescu)
18-10-10在7:20
让我们继续聊天中的讨论。
–爱德华(Eduard Florinescu)
18-10-10在7:26
#9 楼
您可以使用以下bash脚本作为示例。确保为其授予可执行权限(755)。只需将./autochmod.sh用于当前目录,或将./autochmod.sh#!/bin/bash
if [ -e ]; then
if [ -d ];then
dir=
else
echo "No such directory: "
exit
fi
else
dir="./"
fi
for f in $(ls -l $dir | awk '{print }'); do
if [ -d $f ];then
chmod 755 $f
else
chmod 644 $f
fi
done
评论
哇!这么多问题! (1)如果$ 1不为null,但不是目录名称(例如,是错字),则dir设置为。没有消息。 (2)$ 1应该是“ $ 1”,$ dir应该是“ $ dir”。 (3)您无需说“ ./”; “。”很好(严格来说,您在这里不需要引号)。 (4)这不是递归解决方案。 (5)在我的系统上,ls -l…| awk'{print $ 8}'获取文件的修改时间。您需要{print $ 9}来获取文件名的第一个单词。即使这样,(6)仍不能处理带有空格的文件名。 …
–斯科特
2014年7月7日在22:59
…而且,最后但并非最不重要的(∞),如果此脚本位于当前目录中,它将chmod自身更改为644,从而使其自身不可执行!
–斯科特
2014年7月7日23:00
评论
相关:在SO上将目录的所有文件和文件夹权限更改为644/755
相关:在U&L处使用一个命令更改所有文件夹权限。