Como chmod recursivamente todos os directórios excepto ficheiros?
Como chmod 755 todos os directórios mas nenhum ficheiro (recursivamente) ?
Inversamente, como chmod apenas ficheiros (recursivamente) mas nenhum directório ?
Como chmod 755 todos os directórios mas nenhum ficheiro (recursivamente) ?
Inversamente, como chmod apenas ficheiros (recursivamente) mas nenhum directório ?
Dar recursivamente directórios* privilégios de leitura
find /path/to/base/dir -type d -exec chmod 755 {} +
Dar recursivamente ** ficheiros*** privilégios de leitura:
find /path/to/base/dir -type f -exec chmod 644 {} +
Ou, se houver muitos objectos para processar:
chmod 755 $(find /path/to/base/dir -type d)
chmod 644 $(find /path/to/base/dir -type f)
Ou, para reduzir chmod
desova:
find /path/to/base/dir -type d -print0 | xargs -0 chmod 755
find /path/to/base/dir -type f -print0 | xargs -0 chmod 644
Uma razão comum para este tipo de coisas é fixar os directórios em 755, mas os ficheiros em 644. Neste caso há uma forma ligeiramente mais rápida do que o exemplo find
da nik’s:
chmod -R u+rwX,go+rX,go-w /path
Significado:
-R
= recursivamente; u+rwX
= os utilizadores podem ler, escrever e executar; go+rX
= grupo e outros podem ler e executar; go-w
= grupo e outros não podem escrever O importante aqui é notar que o X
em maiúsculas age de forma diferente do x
em minúsculas. No manual podemos ler:
Os bits execute/search se o ficheiro é um directório ou qualquer um dos bits execute/search são definidos no modo original (não modificado).
Por outras palavras, chmod u+X num ficheiro não define o bit execute; e g+X só o define se já estiver definido para o utilizador.
Se quiser ter a certeza que os ficheiros estão definidos para 644 e existem ficheiros no caminho que têm a bandeira de execução, terá de remover primeiro a bandeira de execução. +X não remove a bandeira de execução de ficheiros que já a têm.
Exemplo:
chmod -R ugo-x,u+rwX,go+rX,go-w path
Actualização: isto parece falhar porque a primeira alteração (ugo-x) torna a directoria inexecutável, por isso todos os ficheiros por baixo dela não são alterados.
Eu próprio decidi escrever um pequeno script para isto. Script chmod recursivo para dirs e/ou ficheiros - 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
Basicamente faz o chmod recursivo mas também fornece um pouco de flexibilidade para opções de linha de comando (define directórios e/ou permissões de ficheiros, ou exclui ambos repõe tudo automaticamente para 755-644). Também verifica alguns cenários de erro.
Também escrevi sobre isso no meu blog .
Dar recursivamente directórios privilégios de leitura e escrita:
find /path/to/base/dir -type d -exec chmod 755 {} \;
Dar recursivamente ** ficheiros*** privilégios de leitura:
find /path/to/base/dir -type f -exec chmod 644 {} \;
Mais vale tarde do que nunca deixar-me actualizar a resposta da nik do lado da correcção. A minha solução é mais lenta, mas funciona com qualquer número de ficheiros, com quaisquer símbolos em nomes de ficheiros, e pode executá-la com o sudo normalmente (mas tenha cuidado para que possa descobrir ficheiros diferentes com o sudo).
Experimente este script python; não requer a desova de processos e faz apenas dois syscalls por arquivo. Para além de uma implementação em C, será provavelmente a forma mais rápida de o fazer (precisava dela para corrigir um sistema de ficheiros de 15 milhões de ficheiros que estavam todos definidos para 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)
No meu caso, foi necessária uma tentativa/captura por volta do último chmod, uma vez que o chmod falhou alguns ficheiros especiais.
Também pode usar tree
:
tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1"' -- '{}'
e se quiser ver também a pasta adicione um eco
tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1" && echo$1' -- '{}'
Pode utilizar o seguinte guião de bash como exemplo. Não deixe de lhe dar permissões executáveis (755). Basta usar ./autochmod.sh para o directório actual, ou ./autochmod.sh <dir> para especificar um 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