alterando o UID do proprietário seletivamente para 10 usuários em um diretório de 10 TB +

2

Eu tenho mais de 10 TB NFS / home para mais de 100 usuários e pastas públicas. Eu preciso alterar o nome de usuário e UID de 10 desses usuários. No começo, eu estava pensando em executar o seguinte:

 find /home -uid 812 -exec chown NEWUSER {} \;

Agora, o problema é que ele passará por todos os meus 10 TB uma vez e alterará qualquer arquivo que encontrar com o uid 812 para NEWUSER, que é o que eu quero. Mas isso levará muito tempo e será feito apenas para esse usuário; então eu terei que executar o comando novamente para cada um dos outros 9 usuários, transformando-o de um tempo bem longo para um tempo bem longo * 9.

Além do fato de eu não gostar de scripts, acho que um roteiro seria um amigo aqui, mas não sei por onde começar. Eu quero usar o comando find e verificar todos os arquivos de / home. então:

IF FILEOWNER IS 813 then NEWOWNER IS NEWUSER1
IF FILEOWNER IS 814 then NEWOWNER IS NEWUSER2

... e assim por diante.

Você acha que existe uma maneira de fazer isso, então eu não preciso escanear 10 GB de dados 10 vezes - apenas escanear uma vez?

    
por DanielRodriguez87 14.07.2017 / 22:52

2 respostas

7

Faça a coisa toda usando find .

find /home ! -type l \( \
     -uid 812 -exec chown NEWUSER {} + \
  -o -uid 813 -exec chown ANOTHER {} + \
  -o -uid 814 -exec chown SOMEONE {} + \
  -o -uid 815 -exec chown SOMEGUY {} + \)

Uma passagem de estrutura de diretórios. Todos chown s completos.

Excluímos links simbólicos, caso contrário, o chown se aplicaria ao destino do symlink. Em alguns sistemas, você pode alterar o proprietário de um symlink com chown -h . Nesses, você poderia adicionar o -h e remover o ! -type l .

Observe que, se algum dos arquivos for setuid , isso estragará tudo. Você pode lidar com isso também usando find .

find's business is evaluating expressions — not locating files. Yes, find certainly locates files; but that's really just a side effect.

— Unix Power Tools

    
por 15.07.2017 / 05:12
0

Em primeiro lugar, você não precisa escanear os 10TB completos, apenas a estrutura de diretórios, então fazer a busca básica não é tão ruim quanto parece.

Segundo, se você fizer o básico e começar todos os dez ao mesmo tempo, provavelmente obterá melhor desempenho por causa do cache de leitura.

Ou você pode fazer find /home -uid 812 -o uid 813 -o ... -printf '%U:%p%code%'| sed -zre 's!["$]!\&!g' -e 's/^812:(.*)$/chown NEWUSER1 ""/'e -e 's/^813 ...

Acho que descobri as principais armadilhas, mas o teste é sempre arriscado. Se você não estiver usando o GNU sed, você pode enviar a saída para um shell.

Aqui está uma versão mais limpa com melhor manipulação de cotações usando as ferramentas do gnu.

find /home -uid 812 -o uid 813 -o ' ... ' -printf '%U:' -print0| \
sed -zre "s/'/'\''/g" \
   -e 's/^812:(.*)$/chown NEWUSER1 '"''/e" \
   -e 's/^813:(.*)$/chown NEWUSER2 '"''/e" \
   ...

A maneira como eles funcionam:

A primeira parte do achado é um monte de verificações uid ORed, a carne é o printf (ou printf e print0 na segunda versão) que imprime o uid numérico, dois pontos, o nome do arquivo com c escapa (sem escapes na segunda versão) e um nulo para cada arquivo. Então sed usando o separador nulo e regex estendido cita cifrões e aspas duplas, em seguida, com uma expressão por usuário corresponde a uid e dois pontos separa o nome do arquivo cria uma linha de comando shell para fazer um chown e avalia-o com um shell. Eu provavelmente deveria ter passado alguns minutos a mais verificando a lista de escapes no printf, mas o suficiente para começar se você testar sem o flag e no comando s. Na segunda versão, o único caractere que escapou é a aspa simples. A razão para não escapar é permitir que todos os caracteres, exceto null, passem sem um significado especial após o cabeçalho estritamente definido, não precisamos remover os escapes.

    
por 14.07.2017 / 23:54