如何chmod 755所有目录但没有文件(递归)?
相反,如何仅递归chmod文件,而没有目录chmod?
如何chmod 755所有目录但没有文件(递归)?
相反,如何仅递归chmod文件,而没有目录chmod?
Answers:
要递归地授予目录读取和执行特权:
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: Argument list too long
。最后一个命令可用于许多文件,但是使用sudo
一个文件时必须小心,将其放在xargs之前而不是chmod:find /path/to/base/dir -type d -print0 | sudo xargs -0 chmod 755
dir
也将设置为
chmod ... $(find /path/to/base/dir -type ...)
名称中带有空格的文件名失败。
find /path/to/base/dir -type d -exec chmod 755 {} \;
(find /path/to/base/dir -type f -exec chmod 644 {} \;
)。
发生这种情况的常见原因是将目录设置为755,但将文件设置为644。在这种情况下,比nik的find
示例要快一些:
chmod -R u+rwX,go+rX,go-w /path
含义:
-R
=递归u+rwX
=用户可以读取,写入和执行;go+rX
=组,其他人可以阅读和执行;go-w
=群组,其他人无法写这里要注意的重要一点是,大写字母X
与小写字母的行为不同x
。在手册中,我们可以阅读:
如果文件是目录,则执行/搜索位或任何执行/搜索位都设置为原始(未修改)模式。
换句话说,文件上的chmod u + X不会设置执行位。而g + X只会在已为用户设置的情况下进行设置。
chmod -R 777
因为该+X
选项不会重置文件上现有的执行位。使用-x将重置目录,并阻止其进入目录。
X
,如注释中所述。
go+rX,go-w
-> go=rX
是吗?
chmod u-x,u+X
组合使用等,以删除文件的执行位,但为目录添加它们。
如果要确保将文件设置为644,并且路径中存在带有execute标志的文件,则必须先删除execute标志。+ X不会从已有的文件中删除执行标志。
例:
chmod -R ugo-x,u+rwX,go+rX,go-w path
更新:这似乎失败了,因为第一个更改(ugo-x)使该目录不可执行,因此该目录下的所有文件均未更改。
chmod -R ugo-x path
这样做了,那可能是个问题。但是complete命令将chmod u+rwX
在尝试进入每个目录之前在每个目录上执行on。)但是,我认为这chmod R u=rw,go=r,a+X path
已经足够了,而且它更短。
我决定为此写一个小脚本。
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: $0 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 $1 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=$1
# 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。它还检查一些错误情况。
要递归地授予目录读取和执行特权:
find /path/to/base/dir -type d -exec chmod 755 {} \;
递归地授予文件读取权限:
find /path/to/base/dir -type f -exec chmod 644 {} \;
迟到总比永远不要让我从正确性的角度来提升nik的答案要好。我的解决方案比较慢,但是它可以处理任意数量的文件,文件名中可以包含任何符号,并且可以正常使用sudo运行它(但请注意,它可能会使用sudo查找不同的文件)。
试试这个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)
在我的情况下,由于chmodding一些特殊文件失败,因此需要在最后一个chmod周围进行try / catch。
您也可以使用tree
:
tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1"' -- '{}'
如果您还想查看文件夹,请添加回显
tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1" && echo$1' -- '{}'
xargs
问题。文件名中的单引号本身就是许多命令和脚本的问题,这就是为什么我列出所有包含单引号的文件并将其删除(我的意思是引号)的原因
您可以使用以下bash脚本作为示例。确保为其授予可执行权限(755)。只需将./autochmod.sh用于当前目录,或将./autochmod.sh <dir>用于指定其他目录。
#!/bin/bash
if [ -e $1 ]; then
if [ -d $1 ];then
dir=$1
else
echo "No such directory: $1"
exit
fi
else
dir="./"
fi
for f in $(ls -l $dir | awk '{print $8}'); do
if [ -d $f ];then
chmod 755 $f
else
chmod 644 $f
fi
done
$1
不为null,但不是目录名(例如,是错字),则将其dir
设置为.
没有消息。(2)$1
应该是"$1"
并且$dir
应该是"$dir"
。(3)你不必说"./"
;"."
很好(严格来说,这里不需要引号)。(4)这不是递归解决方案。(5)在我的系统上,ls -l … | awk '{ print $8 }'
获取文件的修改时间。您需要{ print $9 }
获取文件名的第一个单词。即使这样,(6)仍不能处理带有空格的文件名。…
chmod
本身将变为644,从而使其自身不可执行!