Traço equivalente ao auto-redirecionamento da saída do script

9

No Bash, você pode redirecionar todas as saídas stdout futuras do script em execução no momento . Por exemplo, com este script,

exec > >(logger -t my-awesome-script)
echo 1
echo 2
echo 3

Isso terminará no syslog:

Oct 26 01:03:16 mybox my-awesome-script[72754]: 1
Oct 26 01:03:16 mybox my-awesome-script[72754]: 2
Oct 26 01:03:16 mybox my-awesome-script[72754]: 3

Mas isso é específico do Bash e o executivo nu com redirecionamento não parece funcionar no Dash.

Syntax error: redirection unexpected

Como posso fazê-lo funcionar no Dash, ou possivelmente nos dois reservatórios?

Alex B
fonte
Você poderia esclarecer exatamente o que precisa? Você pode redirecionar com >no traço. Sei que você parece estar pedindo outra coisa, mas não sei dizer o que é.
terdon
@terdon Eu expandi a explicação.
Alex B

Respostas:

6

Você pode apenas fazer:

{ commands
....
} | logger -t my_awesome_script

Você pode fazer isso com qualquer shell.

Se você não gosta da aparência, talvez faça o script se envolver em uma função.

#!/bin/sh
run() if     [ "$run" != "$$" ] || return
      then   sh -c 'run=$$ exec "$0" "$@"' "$0" "$@" |
             logger -t my-awesome-script
      fi
#script-body
run "$@" || do stuff
mikeserv
fonte
Essa última linha deve ser run ${1+"$@"} || do stuffpara que os argumentos sejam mantidos.
Adam Katz
@ AdamKatz - bom ponto, execpt ${1+"$@"}não faz nada "$@" não. Teve outros problemas de qualquer maneira.
mikeserv
"$@"passará ""quando não houver argumentos, enquanto ${1+"$@"}passará uma string vazia quando não houver argumentos. Isso é extremamente importante para muitos programas, pois eles analisam ""como um argumento vazio, enquanto uma string vazia (sem aspas) não seria interpretada como um argumento.
23416 Adam
@ AdamKatz - um shell Bourne muito antigo pode (e eu não esperaria encontrar dashem um sistema assim) , mas por outro lado "$@"é único, pois um caso de zero-args não substitui um argumento nulo para shells POSIX.
mikeserv
1
@ AdamKatz - na verdade era um bug mesmo no antigo bsh e nunca deveria ter funcionado assim. Foi finalmente corrigido, mas não sei se ainda deve ser necessário em um Solaris 10, por exemplo. Você está certo sobre $ * - ele não exibe as mesmas propriedades puras de expansão - sua singularidade única pertence ao conteúdo variável de sua expansão, embora sempre seja alguma coisa. Na minha opinião "${@+is especially cool $@}" ,. Mas não é praticamente muito diferente do que a ${1+”$@"}solução alternativa antiga, afinal. Se você tiver um ksh93:"${1+quoted" not quoted "quoted again}"
mikeserv 02/02
5

A substituição do processo é facilmente simulada com pipes nomeados.

mkfifo logger_input
logger -t my_awesome_script < logger_input &
exec > logger_input
echo 1
echo 2
echo 3

De fato, pipes nomeados são um dos mecanismos (sendo o outro /dev/fd) com os quais a substituição de processo pode ser implementada bash.

chepner
fonte
O mais versátil na minha opinião: eu poderia usar o tee para redirecionar para vários fluxos sem problemas. Apenas uma coisa: não se esqueça de excluir o logger_input criado no final de um script.
lauhub
2

Eu não acho que isso seja possível dash. Tanto quanto posso ver na sua manpágina , ele não tem suporte para substituição de processos.

Como solução alternativa, você pode tentar o que o mikserv sugeriu ou pode redirecionar tudo para um arquivo e, depois que seu script terminar (presumivelmente, isso está em um script), adicione o conteúdo desse arquivo ao logger:

$ exec > ~/foo/foo.txt
$ ls
$ echo something
$ cat foo/foo.txt | sudo logger -t my-awesome-script
terdon
fonte
De fato, a substituição de processo - ou o que outros shells chamam de substituição de processo - é mais fácil do que em dashoutros shells. A substituição de processo equivale apenas a um argumento que aponta para um /dev/fd/[num]link para um canal anônimo. dashdocumenta aqui com pipes anônimos, em vez de gerar arquivos temporários, como a maioria dos outros shells. Portanto, cat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\nnão é apenas funcionalmente equivalente, você também pode nomear o fd. Ainda assim, seu argumento é bem fundamentado: é preciso abrir um novo arquivo com execum processo que o leia.
mikeserv
2
@ mikeserv: Em que sentido é cat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\n"mais fácil" do que cat <(get output)?
ruakh 25/10
@ mikeserv: envolve muitas regras para lembrar; talvez você simplesmente tenha se acostumado a eles que nem percebe.
ruakh
@ruakh - bem, com certeza. < >redirecionamentos de shell. basicamente, se você fizer apenas dois deles, também poderá empilhar nas linhas a seguir. Mas sim, você tem razão - eu gosto dos documentos aqui. Ainda assim, quantas coisas forem necessárias para lembrar, é mais fácil quando elas funcionam universalmente, eu acho. Então, novamente, muitas pessoas não têm muito uso para outras conchas e, portanto, não faz diferença para elas. Eu apenas não estou entre eles.
mikeserv
1
@ mikeserv: Não apenas heredocs, mas também /dev/fd/3(nessa forma precisa), e os detalhes do que acontece com o espaço em branco. . . e, por falar nisso, o fato de toda essa abordagem funcionar no Dash, quando não funciona em outros shells que possuem todos os componentes, significa que a abordagem geral é uma regra especial a ser lembrada. (Isso me lembra de tentativas de criar uma Inglês simplificado com menos vocabulário; eles cortaram palavras como persistem , mas eles ignoram just-como-difícil expressões como Keep On .)
ruach