¿Cómo chmod recursivamente todos los directorios excepto los archivos?
¿Cómo chmod 755 todos los directorios pero ningún archivo (recursivamente)?
Inversamente, ¿cómo chmod sólo archivos (recursivamente) pero ningún directorio?
¿Cómo chmod 755 todos los directorios pero ningún archivo (recursivamente)?
Inversamente, ¿cómo chmod sólo archivos (recursivamente) pero ningún directorio?
Para dar recursivamente directorios privilegios de lectura y ejecución:
find /path/to/base/dir -type d -exec chmod 755 {} +
Para dar recursivamente archivos privilegios de lectura:
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 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
Una razón común para este tipo de cosas es establecer los directorios en 755 pero los archivos en 644. En este caso hay una forma un poco más rápida que la del ejemplo de nik find
:
chmod -R u+rwX,go+rX,go-w /path
Significado:
-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 escribir Lo importante 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 cualquiera de los bits de ejecución/búsqueda se establecen 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 sólo lo establecerá si ya está establecido para el usuario.
Si quieres asegurarte de que los archivos están configurados en 644 y hay archivos en la ruta que tienen la bandera de ejecución, tendrás que quitar la bandera de ejecución primero. +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 inejecutable, por lo que todos los archivos que están debajo no se cambian.
Decidí escribir un pequeño script para esto yo mismo. Script chmod recursivo para dirs 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 hace el chmod recursivo pero también provee un poco de flexibilidad para las opciones de la línea de comando (establece los permisos de directorio y/o archivo, o excluye ambos, automáticamente resetea todo a 755-644). También comprueba algunos escenarios de error.
También escribí sobre ello en mi blog .
Para dar recursivamente directorios privilegios de lectura y ejecución:
find /path/to/base/dir -type d -exec chmod 755 {} \;
Para dar recursivamente archivos privilegios de lectura:
find /path/to/base/dir -type f -exec chmod 644 {} \;
Más vale tarde que nunca me dejen actualizar la respuesta de Nik en el 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 los archivos, y puedes ejecutarlo con sudo normalmente (pero ten cuidado de que pueda descubrir diferentes archivos con sudo).
Pruebe este script pitón; no requiere la creación de procesos y sólo hace dos llamadas al sistema por archivo. Aparte de una implementación en C, probablemente sea la forma más rápida de hacerlo (lo necesitaba para arreglar un sistema de archivos de 15 millones de archivos que estaban todos configurados a 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 requería un try/catch alrededor del último chmod, ya que al chmodar algunos archivos especiales fallaban.
También puedes usar tree
:
tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1"' -- '{}'
y si quieres ver la carpeta añade un eco
tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1" && echo$1' -- '{}'
Podrías usar el siguiente guión como ejemplo. Asegúrate de darle permisos de ejecución (755). Simplemente usa ./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