Estou usando o rsync para fazer backup de alguns arquivos:
rsync -PaSh --stats --delete -e "-i key -p XXXX" "/source/" [email protected]:/destination/ 2> output.txt | grep -e 'bytes received' -e 'total bytes' -e files -e 'total file size:' >> output.txt
porque são milhares de arquivos, só quero ver os erros e um resumo no final.
O comando acima gera isso:
rsync: delete_file: unlink(test/test.txt) failed: Permission denied (13)
Number of files: 12 (reg: 10, dir: 2)
Number of created files: 0
Number of regular files transferred: 0
sent 382 bytes received 137 bytes 41.52 bytes/sec
Desejo converter em letras maiúsculas apenas os erros (para chamar a atenção para eles) e deixar o resumo inalterado.
Então ficaria assim:
RSYNC: DELETE_FILE: UNLINK(TEST/TEST.TXT) FAILED: PERMISSION DENIED (13)
Number of files: 12 (reg: 10, dir: 2)
Number of created files: 0
Number of regular files transferred: 0
sent 382 bytes received 137 bytes 41.52 bytes/sec
Como posso conseguir isso?
Obrigado
Você pode efetivamente trocar stdin e stdout com a ajuda de um descritor de arquivo temporário (fd 3 aqui):
Isso diz "aponte o novo fd para o local para onde stderr aponta, aponte stderr para onde stdout aponta, aponte stdout para onde stderr originalmente apontou"... fácil, certo? :)
Ou em outras palavras: agora o stderr from
cmd
passará pelo pipe como stdout enquanto o stdout original foi redirecionado para stderr . E otr
comando fará a conversão de maiúsculas.Atualização: embora você tenha aceitado a resposta acima, sua lista de desejos incluía a capacidade de manipular stdout e stderr simultaneamente. Então, vamos tentar resolver isso... tendo em mente que estamos nos deparando com algumas coisas que não faço com muita frequência!
Uma simples troca de stdout / stderr não fará nada de útil. Com ou sem a troca, você não pode usar dois fluxos diferentes por meio de um único pipeline. A primeira coisa que vem à mente como alternativa é usar FIFOs (pipes nomeados):
Você poderia realmente colocar tudo isso em uma linha, se assim o desejar!
Minhas verificações de sanidade estão funcionando bem, então experimente.
Para converter stderr para letras maiúsculas sem alterar para onde stdout e stderr vão:
Isso é duplicar o stdout original no fd 3, para que possamos restaurá-lo para
rsync
.Aqui, usar
perl
em vez detr
dá melhores resultados para coisas comoStéphane
->STÉPHANE
(STéPHANE
com GNUtr
) outraffic
->TRAFFIC
(TRAffiC
com GNU tr/sed/awk).Observe que agora que stderr passa por um canal, isso pode afetar a ordem relativa das mensagens stdout e stderr, pois as mensagens stderr agora estão sendo atrasadas.
Ver
para algumas outras abordagens que você pode achar úteis.
Use o comando abaixo em vez do seu comando. Eu adicionei um comando extra depois de redirecionar o erro para output.txt
Eu adicionei sed -i "s/.*/\U&/g" output.txt
Conforme testado, funciona bem