Eu acidentalmente chmod -R + x em um diretório. Como faço para restaurar as permissões corretas?

20

Bem, para ser específico, foi chmod -R 755. Agora todo arquivo é executável, o que eu não quero. Eu estou pensando que eu deveria olhar para os dois primeiros bytes de cada arquivo para o #!, mas isso vai cobrir tudo? Em vez disso, devo fileolhar para tudo e basear minha decisão nisso? Ou, mais provavelmente, existe uma maneira ainda melhor de fazer isso?

Qual é a maneira preferida de percorrer recursivamente um diretório e definir -x em arquivos que não devem ser executáveis?

Larry Wang
fonte
Você fez isso em /ou em outro diretório?
precisa saber é
11
@ gvkv: Não /, um diretório totalmente de minha propriedade.
Larry Wang
11
@ Larry no futuro, você provavelmente deve usar alguma variante de + x em vez de violar todas as permissões e possivelmente causar gravações em todos os arquivos.
Xenoterracide
@xenoterracide: Concordado. O que eu realmente queria era dar ao grupo as mesmas permissões que eu (o que acabou acontecendo!), Mas não pensei o suficiente antes de digitar.
Larry Wang
De quantos arquivos estamos falando? Quantos devem ser executáveis? Existe alguma maneira de saber a partir dos nomes dos arquivos?
David Thornley

Respostas:

15

Não há bala mágica aqui. As permissões carregam informações que nem sempre são redundantes.

Se você tivesse feito isso em um diretório de sistema, seu sistema estaria em um estado muito ruim, porque você precisaria se preocupar com bits setuid e setgid e com arquivos que não deveriam ser legíveis pelo mundo e com arquivos que deveriam ser graváveis ​​em grupo ou mundo.

Em um diretório por usuário, você precisa se preocupar com arquivos que não devem ser legíveis pelo mundo. Ninguém pode ajudá-lo lá.

Quanto à executabilidade, uma boa regra geral seria fazer com que tudo que não parece ser executado possa ser executável. O kernel pode executar scripts cujos dois primeiros bytes são #!, binários ELF cujos quatro primeiros bytes estão \x7fELFonde \x7festá o byte com o valor 12 e alguns tipos de arquivos mais raros (a.out, qualquer coisa registrada binfmt_misc). Portanto, o comando a seguir deve restaurar suas permissões para um estado razoável (assume bash 4 ou zsh, caso contrário, use findpara percorrer a árvore de diretórios; aviso digitado diretamente no navegador):

for x in **/*; do
  if ! [ -f "$x" ]; then continue; fi # skip all but regular files
  case $(head -c 4 "$x") in
    "#!"??) :;; # skip script
    "\x7fELF") :;; # skip ELF executable
    *) chmod a-x "$x";;
  esac
done

Observe que existe uma maneira simples de fazer backup e restaurar permissões de uma árvore de diretórios, no Linux e possivelmente em outras unidades com suporte a ACL:

getfacl -R >saved-permissions
setfacl --restore=saved-permissions
Gilles 'SO- parar de ser mau'
fonte
Obrigado! Felizmente, acho que tudo se encaixa nessas duas categorias. Se isso perder alguma coisa, eu posso lidar com isso mais tarde.
Larry Wang
Tenha em mente que isso **/*requer globstar.
Chris Baixo
Eu recomendaria duas alterações neste script. Um, use findao invés de globstar; dois, em vez de olhar para a cabeça, use o filecomando para ver o que é e ramifique a partir daí.
Shadur 12/11/11
O @Shadur findé menos confiável do que globstar, globstaré preferível em quase todos os casos.
Chris Baixo
11
@Gilles Preferível como em "se você tiver, é muito superior", não só é mais rápido, como também é mais confiável (e não possui SNAFUs inesperados).
Chris Baixo
6

Eu acredito que você vai querer algo como

find dir -type f -exec chmod ugo-x '{}' +

Ele procura todos os arquivos regulares, recursivamente no diretório (exclui diretórios e dispositivos) e remove o bit executável.

Eu começaria aqui e depois trabalharia para tornar os arquivos que deveriam ser executáveis, executáveis.

O seguinte deve funcionar exatamente como você solicitou (ele encontrará todos os arquivos regulares, cumprimente-os por #! E remova os bits x, se não forem encontrados)

find . -type f | xargs grep -L #! | xargs chmod ugo-x

possivelmente uma versão melhor do anterior (menos tubos)

find . -type f -exec grep -L #! '{}' + | xargs chmod ugo-x 
xenoterracida
fonte
3
Faça isso grep -L '^#!'pelo menos (as aspas são necessárias e ^restringe-se à correspondência no início da linha), mas ainda é muito permissivo, pois corresponde #!a qualquer linha. O uso xargsfalhará com nomes de arquivos que contenham espaços ou caracteres entre aspas; use xargs -d '\n'(requer GNU xargs).
Gilles 'SO- stop be evil'
0

Bem, sem uma linha shebang, o arquivo será executado como um script de shell, nominalmente com /bin/sh. Sua idéia é um bom começo e, supondo que o diretório em questão não contenha arquivos de missão crítica, provavelmente não há muito risco de executar alguns grepe chmodcombo. Você pode encontrar falsos positivos, ou seja, arquivos com uma linha shebang que não devem ter o bit executável definido, mas sem saber mais informações sobre o objetivo do diretório, apenas você pode decidir se isso representa uma ameaça existencial significativa para o seu sistema e / ou dados.

gvkv
fonte
Não estou preocupado tanto com falsos positivos como falsos negativos. Existem binários com os quais não acho que começar #!.
Larry Wang