No bash, como posso colocar um redirecionamento antes de um comando que contém um canal?
cmd1 >file # bash is happy
>file cmd1 # bash is happy
cmd1 | cmd2 >file # bash is happy
>file cmd1 | cmd2 # bash is happy but cmd2 and I are not
(cmd1 | cmd2) >file # bash is happy
>file (cmd1 | cmd2) # syntax error: bash: syntax error near unexpected token `('
>file {cmd1 | cmd2;} # syntax error: bash: syntax error near unexpected token `}'
Para o plano de fundo xy, preciso redirecionar vários comandos longos e feios para arquivos diferentes e é muito mais legível colocar esses arquivos primeiro.
Algo como:
>file1 command1 --with --lots --of arguments
>file2 command2 --with --even --more arguments
>file3 command3 big line | command4 big too # wrong
Minha solução até agora, além de colocar o redirecionamento no final, é utilizar uma função:
cmd3() { command3 $1 $2 $3 | command4 $4 $5 $6; }
>file3 cmd3 ${args[@]}
Mas talvez haja uma maneira mais direta?
Talvez:
Dito isto, a documentação do Bash diz:
Portanto, quaisquer formas diretas são descartadas, pois a liberdade de colocar redirecionamentos em qualquer lugar se aplica apenas a comandos simples.
Você poderia usar
eval
:Ou mude para
zsh
o que permite:E até mesmo:
Eles também funcionam com o
rc
shell (deveria ter sido o sucessor do Bourne-shell do plan9, Unix v10) do qual o zsh se inspirou.Com o zsh, isso também funciona para funções anônimas, com as sintaxes
(){...} args
e :function {...} args
Em qualquer caso, observe que longas filas sempre podem ser quebradas.
Pode ser escrito:
Ou: