Precisa de ajuda para resgatar um servidor virtual RH - comando shell para corrigir o erro?

1

Eu tenho uma VM que executa um de nossos principais aplicativos. Antes de fazer uma mudança bastante pesada, fiz duas linhas de backup. Primeiro, tirei uma foto da VM. Em segundo lugar, executei um comando sed recursivo por todo o sistema para substituir texto em arquivos e criar backups à medida que acontecia. Foi só depois de executar isso que percebi o quão extensa era a mudança. Aqui está o que eu corri:

find / -type f -print0|xargs -0 sed -i.matthew05012013 's/oldtext/newtext/g'

Eu tentei reverter o instantâneo, mas acabei removendo-o, o que comprometeu todas as alterações (porque a nomenclatura do ESX é muito confusa com os instantâneos). Então, minha última linha de defesa é percorrer recursivamente o sistema e renomear qualquer coisa com a extensão .matthew05012013 adicionada ao mesmo nome de arquivo, sem a extensão, sobrescrevendo o que estiver lá.

Alguém tem alguma idéia sobre como melhor executar isso? À mão não vai funcionar, existem vários milhares de arquivos que foram modificados no sistema.

    
por Matthew 02.05.2013 / 14:48

2 respostas

1

Embora não seja exatamente gracioso, o seguinte deve ser o truque:

for modfile in 'find <dir> -name "*.matthew05012013"'; do
  realfile='echo $modfile | sed 's/.matthew05012013//''
  cp $modfile $realfile
done

Eu fiz isso em um diretório de teste:

$ find /tmp/deleteme/
/tmp/deleteme/
/tmp/deleteme/1
/tmp/deleteme/1/filea
/tmp/deleteme/1/fileb
/tmp/deleteme/1/filec
/tmp/deleteme/1/filed
/tmp/deleteme/1/fileb.matthew05012013
/tmp/deleteme/1/filed.matthew05012013
/tmp/deleteme/2
/tmp/deleteme/2/filea
/tmp/deleteme/2/fileb
/tmp/deleteme/2/filec
/tmp/deleteme/2/filed
/tmp/deleteme/2/fileb.matthew05012013
/tmp/deleteme/2/filed.matthew05012013
/tmp/deleteme/3
/tmp/deleteme/3/filea
/tmp/deleteme/3/fileb
/tmp/deleteme/3/filec
/tmp/deleteme/3/filed
/tmp/deleteme/3/fileb.matthew05012013
/tmp/deleteme/3/filed.matthew05012013
/tmp/deleteme/4
/tmp/deleteme/4/filea
/tmp/deleteme/4/fileb
/tmp/deleteme/4/filec
/tmp/deleteme/4/filed
/tmp/deleteme/4/fileb.matthew05012013
/tmp/deleteme/4/filed.matthew05012013
/tmp/deleteme/5
/tmp/deleteme/5/filea
/tmp/deleteme/5/fileb
/tmp/deleteme/5/filec
/tmp/deleteme/5/filed
/tmp/deleteme/5/fileb.matthew05012013
/tmp/deleteme/5/filed.matthew05012013
/tmp/deleteme/6
/tmp/deleteme/6/filea
/tmp/deleteme/6/fileb
/tmp/deleteme/6/filec
/tmp/deleteme/6/filed
/tmp/deleteme/6/fileb.matthew05012013
/tmp/deleteme/6/filed.matthew05012013

$ for modfile in 'find /tmp/deleteme -name "*.matthew05012013"'; do 
    realfile='echo $modfile | sed 's/.matthew05012013//''
    echo "cp $modfile $realfile"
    done

cp /tmp/deleteme/1/fileb.matthew05012013 /tmp/deleteme/1/fileb
cp /tmp/deleteme/1/filed.matthew05012013 /tmp/deleteme/1/filed
cp /tmp/deleteme/2/fileb.matthew05012013 /tmp/deleteme/2/fileb
cp /tmp/deleteme/2/filed.matthew05012013 /tmp/deleteme/2/filed
cp /tmp/deleteme/3/fileb.matthew05012013 /tmp/deleteme/3/fileb
cp /tmp/deleteme/3/filed.matthew05012013 /tmp/deleteme/3/filed
cp /tmp/deleteme/4/fileb.matthew05012013 /tmp/deleteme/4/fileb
cp /tmp/deleteme/4/filed.matthew05012013 /tmp/deleteme/4/filed
cp /tmp/deleteme/5/fileb.matthew05012013 /tmp/deleteme/5/fileb
cp /tmp/deleteme/5/filed.matthew05012013 /tmp/deleteme/5/filed
cp /tmp/deleteme/6/fileb.matthew05012013 /tmp/deleteme/6/fileb
cp /tmp/deleteme/6/filed.matthew05012013 /tmp/deleteme/6/filed

Obviamente, isso tem a mesma abordagem pesada que você mencionou antes, e se eu fizesse isso em produção, eu provavelmente iria ecoar os comandos cp (como mostrado no meu teste) e enviá-los para um arquivo para revisão. Em seguida, basta executá-las depois de verificar se tudo está certo. Apenas certifique-se de que a string que você procura (.matthew05012013 no exemplo) seja única o suficiente para que não corresponda a outra coisa. E substitua o 'cp' por um 'mv' ou qualquer outro comando que flutue no seu barco.

Eu também recomendaria fazer outro snapshot ANTES de fazer essa alteração, mas caso algo dê errado, você não precisa tentar limpar uma bagunça adicional.

Tenha também cuidado ao preservar as permissões durante essa alteração. Verifique a página de manual 'cp' para adicionar argumentos para preservar permissões ou implementar uma umask específica antes de executar isso. Você pode entrar rapidamente em água quente quando tiver milhares de arquivos com permissões que não permitem que seu aplicativo seja executado corretamente.

    
por 02.05.2013 / 15:33
0
find / -type f -name '*.matthew05012013' -print0 | \
  xargs -0 rename .matthew05012013 ""

Isso falhará se houver arquivos com ".matthew05012013" ocorrendo duas vezes no nome, uma vez no final. Este provavelmente não é o caso e pode ser evitado usando outra ferramenta como o mmv ou um simples shell script.

    
por 02.05.2013 / 15:32