¿Cómo chmod 755 todos los directorios pero ningún archivo (recursivamente)?
Inversamente, ¿cómo chmod solo archivos (recursivamente) pero no directorio?
¿Cómo chmod 755 todos los directorios pero ningún archivo (recursivamente)?
Inversamente, ¿cómo chmod solo archivos (recursivamente) pero no directorio?
Respuestas:
Para otorgar recursivamente a los directorios privilegios de lectura y ejecución:
find /path/to/base/dir -type d -exec chmod 755 {} +
Para otorgar recursivamente privilegios de lectura de archivos :
find /path/to/base/dir -type f -exec chmod 644 {} +
O, si hay muchos objetos para procesar:
chmod 755 $(find /path/to/base/dir -type d)
chmod 644 $(find /path/to/base/dir -type f)
O, para reducir el chmod
desove:
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
. El último comando funciona con muchos archivos, pero al usar sudo
uno debe tener cuidado de ponerlo antes de xargs en lugar de chmod:find /path/to/base/dir -type d -print0 | sudo xargs -0 chmod 755
dir
también se establecerá en 755.
chmod ... $(find /path/to/base/dir -type ...)
falla para nombres de archivos con espacios en el nombre.
find /path/to/base/dir -type d -exec chmod 755 {} \;
( find /path/to/base/dir -type f -exec chmod 644 {} \;
).
Una razón común para este tipo de cosas es establecer directorios en 755 pero archivos en 644. En este caso, hay una forma un poco más rápida que el find
ejemplo de Nik :
chmod -R u+rwX,go+rX,go-w /path
Sentido:
-R
= recursivamente;u+rwX
= Los usuarios pueden leer, escribir y ejecutar;go+rX
= grupo y otros pueden leer y ejecutar;go-w
= grupo y otros no pueden escribirLo importante a tener en cuenta aquí es que las mayúsculas X
actúan de manera diferente a las minúsculas x
. En el manual podemos leer:
Los bits de ejecución / búsqueda si el archivo es un directorio o alguno de los bits de ejecución / búsqueda se configuran en el modo original (sin modificar).
En otras palabras, chmod u + X en un archivo no establecerá el bit de ejecución; y g + X solo lo configurará si ya está configurado para el usuario.
chmod -R 777
ya que la +X
opción no restablecerá los bits de ejecución existentes en los archivos. El uso de -x restablecerá los directorios y evitará descender a ellos.
X
, como se explica en los comentarios.
go+rX,go-w
-> go=rX
¿no es así?
chmod u-x,u+X
en combinación, etc., para eliminar bits de ejecución para archivos, pero agregarlos para directorios.
Si desea asegurarse de que los archivos estén configurados en 644 y que haya archivos en la ruta que tengan el indicador de ejecución, primero deberá eliminar el indicador de ejecución. + X no elimina el indicador de ejecución de los archivos que ya lo tienen.
Ejemplo:
chmod -R ugo-x,u+rwX,go+rX,go-w path
Actualización: esto parece fallar porque el primer cambio (ugo-x) hace que el directorio sea ejecutable, por lo que no se cambian todos los archivos debajo.
chmod -R ugo-x path
, eso podría ser un problema. Pero el comando completo lo hará chmod u+rwX
en cada directorio antes de intentar descender a él). Sin embargo, creo que eso chmod R u=rw,go=r,a+X path
es suficiente, y es más corto.
Decidí escribir un pequeño guión para esto yo mismo.
Script chmod recursivo para directorios y / o archivos - Gist :
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
Básicamente realiza el chmod recursivo, pero también proporciona un poco de flexibilidad para las opciones de línea de comandos (establece los permisos de directorio y / o archivo, o excluye ambos, restablece automáticamente todo a 755-644). También comprueba algunos escenarios de error.
También escribí sobre eso en mi blog .
Para otorgar recursivamente a los directorios privilegios de lectura y ejecución:
find /path/to/base/dir -type d -exec chmod 755 {} \;
Para otorgar recursivamente privilegios de lectura de archivos :
find /path/to/base/dir -type f -exec chmod 644 {} \;
Más vale tarde que nunca, déjame actualizar la respuesta de Nik del lado de la corrección. Mi solución es más lenta, pero funciona con cualquier número de archivos, con cualquier símbolo en los nombres de archivo, y puede ejecutarlo con sudo normalmente (pero tenga cuidado de que pueda descubrir diferentes archivos con sudo).
Prueba este script de Python; no requiere generación de procesos y solo hace dos syscalls por archivo. Además de una implementación en C, probablemente será la forma más rápida de hacerlo (lo necesitaba para arreglar un sistema de archivos de 15 millones de archivos que estaban configurados en 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)
En mi caso, se requirió un try / catch alrededor del último chmod, ya que chmodding algunos archivos especiales fallaron.
También puedes usar tree
:
tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1"' -- '{}'
y si quieres ver también la carpeta agrega un eco
tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1" && echo$1' -- '{}'
xargs
. Las comillas simples en los nombres de archivo son en sí mismas un problema para muchos comandos y guiones, por eso enumeré todos los archivos que contienen comillas simples y los
Puede usar el siguiente script bash como ejemplo. Asegúrese de darle permisos ejecutables (755). Simplemente use ./autochmod.sh para el directorio actual, o ./autochmod.sh <dir> para especificar uno diferente.
#!/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
no es nulo, pero no es el nombre de un directorio (p. Ej., Es un error tipográfico), dir
se configura .
sin mensaje. (2) $1
debería ser "$1"
y $dir
debería ser "$dir"
. (3) No necesitas decirlo "./"
; "."
está bien (y, estrictamente hablando, no necesita citas aquí). (4) Esta no es una solución recursiva. (5) En mi sistema, ls -l … | awk '{ print $8 }'
obtiene los tiempos de modificación de los archivos. Necesita { print $9 }
obtener la primera palabra del nombre del archivo. E incluso entonces, (6) esto no maneja nombres de archivos con espacios en blanco. ...
chmod
sí a 644, con lo que en sí no ejecutable!