Precisa corrigir permissões de arquivo no diretório inicial de um usuário

24

Alguém tem uma ferramenta ou script que irá corrigir recursivamente as permissões de arquivo em um diretório?

Em uma máquina Ubuntu Linux, vários arquivos foram copiados para um disco USB com permissões 777 completas (usuário, grupo, outra - leitura, gravação, execução) por erro. Quero colocá-los novamente no diretório do usuário corrigido.

Os diretórios devem ter 775 e todos os outros arquivos podem ter 664. Todos os arquivos são imagens, documentos ou MP3, portanto nenhum deles precisa ser executável. Se o bit do diretório estiver definido, ele precisará de execução; caso contrário, ele precisará apenas de usuário e grupo, leitura e gravação.

Achei que valia a pena verificar se esse utilitário existe antes de hackear um shell script :)

mlambie
fonte

Respostas:

51

Isso deve fazer o truque:

find /home/user -type d -print0 | xargs -0 chmod 0775
find /home/user -type f -print0 | xargs -0 chmod 0664
freiheit
fonte
1
+1 para usar -print0 / xargs -0 :-).
Sleske 01/12/2009
14

O find pode fazer o truque sozinho com -exec:

find /home/user -type f -exec chmod 0664 {} \;
find /home/user -type d -exec chmod 0775 {} \;

para impedir a localização de um chmod para cada entrada:

find /home/user -type f -exec chmod 0664 {} +
find /home/user -type d -exec chmod 0775 {} +

(efetivamente chama o chmod uma vez com a lista de todos os arquivos como parâmetros, em vez de um chmod por arquivo)

ThorstenS
fonte
6
Mais lento do que usar xargs, pois você está criando um chmod para cada arquivo, enquanto o xargs executará um processo chmod com o máximo de arquivos que puder caber em uma linha de comando. Em uma árvore muito grande, isso pode fazer uma diferença justa.
David Pashley
1
Além disso, print0 / xargs -0 manipula até nomes de arquivos muito estranhos; não tenho tanta certeza sobre encontrar -exec.
Sleske 01/12/2009
8

Esta resposta não resolverá o seu problema, mas alguém pode achar útil para um problema semelhante em que os arquivos têm menos permissão do que deveriam.

# chmod -R . u=rwX,g=rX,o=rX

A mágica é a permissão X, em vez de x. A página de manual do chmod descreve assim:

executar / pesquisar apenas se o arquivo for um diretório ou se já tiver permissão de execução para algum usuário

Isso não é adequado no seu caso, pois seus arquivos têm permissão de execução, portanto, corresponderá ao segundo teste.

David Pashley
fonte
1
g deve ser rwX para 775 e 664.
aventurin
1

Eu criei um script a partir da solução do freiheit, que adiciona verificação básica de argumentos.

#!/bin/sh

if [ $# -lt 1 ]; then
    echo "USAGE: $0 <path>"
    exit 1
fi

find $1 -type d -print0 | xargs -0 chmod 0755
find $1 -type f -print0 | xargs -0 chmod 0644
Marcs
fonte
Boa ideia. No entanto, a segunda linha gera um erro quando o alvo é um directório: chmod: missing operand after ‘0644’. Posso sugerir agrupar as instruções find com uma verificação para ver se o destino existe? if [ -d $1 ]; then find $1 -type d -print0 | xargs -0 chmod 0755; fi; if [ -f $1 ]; then find $1 -type f -print0 | xargs -0 chmod 0644; fi
Underverse
Está quase correto; mas se o destino for um diretório, você esqueceu de chmod os arquivos nele e, se for um arquivo, precisará apenas chmod esse arquivo.
sean
0

Caso você esteja usando ssh, é recomendável não modificar ~/.sshpermissões.

DIR=/home/user
find $DIR -type d -not -path "$DIR/.ssh" -print0 | xargs -0 chmod 0775
find $DIR -type f -not -path "$DIR/.ssh/*" -print0 | xargs -0 chmod 0664
Tombart
fonte
0

Criei um script bash muito simples outro dia porque precisava corrigir permissões. Por que não existe um utilitário formal para redefinir as permissões básicas, não raiz, de arquivos e pastas?

O script usa para localizar 755 todas as pastas e 644 bibliotecas. Em seguida, ele testa cada arquivo consigo mesmo para verificar se ele possui um cabeçalho binário de elfo. Caso contrário, ele procura nos dois primeiros caracteres por shebang #!. Ele 755 essas instâncias e 644 tudo o resto depois de verificar se o arquivo já tem a permissão correspondente.

Casos especiais são tratados com uma exceção como a *.bakde arquivos a serem ignorados.

#!/bin/bash
read -r -p "Correct file and folder permissions? [y/N] " chse
if [[ "$chse" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
  echo "Processing ..."
  find -H $(pwd) -type d -exec chmod 0755 {} \;
  # set dirs to 755
  find -H $(pwd) -type f \( -iname '*.so.*' -o -iname '*.so' \) -exec chmod 0644 {} \;
  # libs
  IFS=$'\n'
  for value in $(find -H $(pwd) -type f ! \( -iname '*.so.*' -o -iname '*.so' -o -iname '*.bak' \) -printf '%p\n'); do
    tstbin=$(readelf -l "$value" 2>/dev/null | grep -Pio 'executable|shared')
    if [ -z "$tstbin" ]; then
      tstbat=$(cat "$value" | head -c2 | grep -io '#!')
      if [ -n "$tstbat" ]; then
        perm=$(stat -c '%a' "$value")
        if [ "$perm" != "755" ]; then
          chmod 755 $value
          echo "Set script  755 $value"
          # set batch to 755
        fi
      else
        perm=$(stat -c '%a' "$value")
        if [ "$perm" != "644" ]; then
          chmod 644 $value
          echo "Set regular 644 $value"
          # set regular files to 644
        fi
      fi
      # above aren't elf binary
    else
      perm=$(stat -c '%a' "$value")
      if [ "$perm" != "755" ]; then
        chmod 755 $value
        echo "Set binary  755 $value"
        # set elf binaries to 755
      fi
    fi
  done
  unset IFS
  # process linux permissions for files and folders
else
  echo "Aborted."
fi
noabody
fonte
0

Encontrei uma solução simplificada de C-shell. Isso pode não ser completamente infalível, mas deve funcionar para a maioria dos diretórios. Ele assume que o comando 'file' do Unix funciona e encontra os arquivos exec para redefini-los de volta às permissões exec:

find /home/user -type d | xargs chmod 0775
find /home/user -type f | xargs -0 chmod 0664
find /home/user -type f -exec file {} \; | grep executable | cut -d":" -f1 | xargs chmod 0775
K. Donovan
fonte
1
Isso não apenas repete algumas das respostas, mas também apresenta um erro e uma funcionalidade que o OP não solicitou.
RalfFriedl 21/03
0

Uma alternativa, que não responde exatamente à solicitação original, mas é mais provável que o OP pretenda, é especificar simbolicamente as permissões. Por exemplo, suponho que o OP deseja "remover o acesso de gravação para o público e remover a permissão executável de todos os arquivos".

Isso é possível se você usar a representação de permissão simbólica.

  • ow é "remover o acesso de gravação do público" ("o" - outros, "-" - remove, "w" - gravação)
  • ax é "remover executar para todos apenas em arquivos" ("a" - todos "-" - remover, "x" - executar)

Escrevendo dessa maneira, em vez de definir explicitamente "0664", você evita acidentalmente permitir permissões extras para arquivos que foram bloqueados anteriormente. Por exemplo, se um arquivo era 0770, ele não se tornará 0664 por engano.

Para fazer o primeiro requisito, basta usar chmod:

chmod --recursive o-w $dir

Para fazer o segundo requisito:

find $dir -type f -exec chmod a-x {} +

Ou para fazer as duas coisas:

find $dir -type f -exec chmod a-x,o-w {} +
find $dir -type d -exec chmod o-w {} +
chutz
fonte