如何递归地 chmod 文件之外的所有目录?

如何递归地 chmod 文件之外的所有目录?

如何遍历chmod 755所有目录但不遍历文件(递归)?

相反,如何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)

请注意,如果您的输入中有空格,这些配方可能无法正常工作[下面的 xargs 示例也是如此]。


或者,为了减少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

答案2

这种事情的常见原因是将目录设置为 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文件不会设置执行位;并且chmod g+X仅当已为用户设置时才会设置它。

答案3

如果您想确保文件设置为 644 并且路径中有具有执行标志的文件,则必须先删除执行标志。 +X 不会从已经具有执行标志的文件中删除执行标志。

例子:

chmod -R ugo-x,u+rwX,go+rX,go-w path

更新:这似乎失败了,因为第一个更改(ugo-x)使得目录无法执行,所以其下的所有文件都没有改变。

答案4

我决定自己为此编写一个小脚本。

目录和/或文件的递归 chmod 脚本 — Gist

chmodr命令

#!/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)。它还会检查一些错误情况。

我也写过在我的博客上

相关内容