Como chmod 755 todos os diretórios, mas nenhum arquivo (recursivamente)?
Inversamente, como chmod somente arquivos (recursivamente), mas nenhum diretório?
Como chmod 755 todos os diretórios, mas nenhum arquivo (recursivamente)?
Inversamente, como chmod somente arquivos (recursivamente), mas nenhum diretório?
Respostas:
Para dar recursivamente aos diretórios privilégios de leitura e execução:
find /path/to/base/dir -type d -exec chmod 755 {} +
Para dar recursivamente aos arquivos privilégios de leitura:
find /path/to/base/dir -type f -exec chmod 644 {} +
Ou, se houver muitos objetos para processar:
chmod 755 $(find /path/to/base/dir -type d)
chmod 644 $(find /path/to/base/dir -type f)
Ou, para reduzir a 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
-bash: /bin/chmod: Argument list too long
. O último comando funciona com muitos arquivos, mas ao usar sudo
um, deve-se ter o cuidado de colocá-lo antes do xargs em vez do chmod:find /path/to/base/dir -type d -print0 | sudo xargs -0 chmod 755
dir
também será definido como 755.
chmod ... $(find /path/to/base/dir -type ...)
falha nos nomes de arquivos com espaços no nome.
find /path/to/base/dir -type d -exec chmod 755 {} \;
( find /path/to/base/dir -type f -exec chmod 644 {} \;
).
Um motivo comum para esse tipo de coisa é definir diretórios para 755, mas arquivos para 644. Nesse caso, há uma maneira um pouco mais rápida que o find
exemplo da nik :
chmod -R u+rwX,go+rX,go-w /path
Significado:
-R
= recursivamente;u+rwX
= Os usuários podem ler, escrever e executar;go+rX
= grupo e outros podem ler e executar;go-w
= grupo e outros não podem escreverO importante a ser observado aqui é que maiúsculas X
atuam de maneira diferente para minúsculas x
. No manual, podemos ler:
Os bits de execução / pesquisa se o arquivo for um diretório ou qualquer um dos bits de execução / pesquisa estiver definido no modo original (não modificado).
Em outras palavras, chmod u + X em um arquivo não definirá o bit de execução; e o g + X o definirá apenas se já estiver definido para o usuário.
chmod -R 777
pois a +X
opção não redefinirá os bits de execução existentes nos arquivos. O uso de -x redefinirá os diretórios e evitará a descida neles.
X
, conforme explicado nos comentários.
go+rX,go-w
-> go=rX
não é?
chmod u-x,u+X
em combinação, etc., para remover bits de execução de arquivos, mas adicioná-los aos diretórios.
Se você deseja garantir que os arquivos estejam configurados para 644 e que existam arquivos no caminho que possuem o sinalizador de execução, será necessário remover o sinalizador de execução primeiro. + X não remove o sinalizador de execução dos arquivos que já o possuem.
Exemplo:
chmod -R ugo-x,u+rwX,go+rX,go-w path
Atualização: isso parece falhar porque a primeira alteração (ugo-x) torna o diretório não executável, para que todos os arquivos abaixo dele não sejam alterados.
chmod -R ugo-x path
isso, isso pode ser um problema. Mas o comando completo fará o comando chmod u+rwX
em cada diretório antes de tentar descer para ele.) No entanto, acredito que isso chmod R u=rw,go=r,a+X path
é suficiente - e é mais curto.
Decidi escrever um pequeno roteiro para isso.
Script chmod recursivo para dirs e / ou arquivos - 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, ele executa o chmod recursivo, mas também oferece um pouco de flexibilidade para as opções de linha de comando (define permissões de diretório e / ou arquivo ou exclui as duas, ela redefine automaticamente tudo para 755-644). Ele também verifica alguns cenários de erro.
Eu também escrevi sobre isso no meu blog .
Para dar recursivamente aos diretórios privilégios de leitura e execução:
find /path/to/base/dir -type d -exec chmod 755 {} \;
Para dar recursivamente aos arquivos privilégios de leitura:
find /path/to/base/dir -type f -exec chmod 644 {} \;
Antes tarde do que nunca, deixe-me atualizar a resposta de nik do lado da correção. Minha solução é mais lenta, mas funciona com qualquer número de arquivos, com símbolos nos nomes de arquivos, e você pode executá-la com o sudo normalmente (mas lembre-se de que ele poderá descobrir arquivos diferentes com o sudo).
Experimente este script python; ele não requer geração de processos e faz apenas dois syscalls por arquivo. Além de uma implementação em C, provavelmente será a maneira mais rápida de fazê-lo (eu precisava corrigir um sistema de arquivos de 15 milhões de arquivos, todos definidos como 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ário um try / catch em torno do último chmod, pois o chmodding alguns arquivos especiais falhou.
Você também pode usar tree
:
tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1"' -- '{}'
e se você quiser ver também a pasta, adicione um eco
tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1" && echo$1' -- '{}'
xargs
questões. Aspas simples em nomes de arquivos são eles próprios um problema para muitos comandos e roteiro que é por isso que eu listados todos os arquivos que contêm aspas simples e removidos-los (as aspas quero dizer)
Você pode usar o seguinte script bash como exemplo. Certifique-se de fornecer permissões executáveis (755). Simplesmente use ./autochmod.sh para o diretório atual ou ./autochmod.sh <dir> para especificar um diretório 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
não for nulo, mas não for o nome de um diretório (por exemplo, é um erro de digitação), dir
será definido como .
sem mensagem. (2) $1
deve ser "$1"
e $dir
deve ser "$dir"
. (3) Você não precisa dizer "./"
; "."
é bom (e, estritamente falando, você não precisa de aspas aqui). (4) Esta não é uma solução recursiva. (5) No meu sistema, ls -l … | awk '{ print $8 }'
obtém os tempos de modificação dos arquivos. Você precisa { print $9 }
obter a primeira palavra do nome do arquivo. E mesmo assim, (6) isso não trata nomes de arquivos com espaço em branco. ...
chmod
-se para 644, tornando-se assim não executável!