Comando POSIX / Substituição de Processo
_log()( x=0
while [ -e "${TMPDIR:=/tmp}/$$.$((x+=1))" ]
do continue; done &&
mkfifo -- "$TMPDIR/$$.$x" &&
printf %s\\n "$TMPDIR/$$.$x" || exit
exec >&- >/dev/null
{ rm -- "$TMPDIR/$$.$x"
logger --priority user."$1" --tag "${0##*/}"
} <"$TMPDIR/$$.$x" &
) <&- </dev/null
Você deve poder usar isso como:
exec >"$(_log notice)" 2>"$(_log error)"
Aqui está uma versão que faz uso do mktemp
comando:
_log()( p=
mkfifo "${p:=$(mktemp -u)}" &&
printf %s "$p" &&
exec <&- >&- <>/dev/null >&0 &&
{ rm "$p"
logger --priority user."$1" --tag "${0##*/}"
} <"$p" &
)
... que faz o mesmo, exceto que permite mktemp
selecionar o nome do arquivo para você. Isso funciona porque a substituição do processo não é de forma alguma mágica e funciona de maneira muito semelhante para comandar a substituição . Em vez de substituir a expansão pelo valor do comando executado dentro da mesma forma que a substituição de comando , a substituição do processo a substitui pelo nome de um link do sistema de arquivos no qual a saída pode ser encontrada.
Enquanto o shell POSIX não fornece um corolário direto para tal coisa, a emulação é muito simples. Tudo o que você precisa fazer é criar um arquivo, imprimir seu nome no padrão a partir de uma substituição de comando e, no segundo plano, executar o comando que produzirá para esse arquivo. Agora você pode apenas redirecionar para o valor dessa expansão - exatamente como na substituição de processos. E, portanto, o shell POSIX fornece todas as ferramentas necessárias, é claro - tudo o que é necessário é que você as use de uma maneira que seja mais adequada para você.
Ambas as versões acima garantem que eles destruam o link do sistema de arquivos para os pipes que eles criam / usam antes de utilizá-los. Isso significa que não há necessidade de limpeza após o fato e, mais importante, seus fluxos estão disponíveis apenas para os processos que os abrem inicialmente - e, portanto, seus links do sistema de arquivos não podem ser usados como um meio de espionar / seqüestrar sua atividade de registro. Deixar seus links fs no sistema de arquivos é uma falha de segurança em potencial.
Outra maneira é envolvê-lo. Isso pode ser feito de dentro do script.
x=${x##*[!0-9]*}
_log(){
logger --priority user."$1" --tag "${0##*/}"
} 2>/dev/null >&2
cd ../"$PPID.$x" 2>/dev/null &&
trap 'rm -rf -- "${TMPDIR:-/tmp}/$PPID.$x"' 0 ||
{ until cd -- "${TMPDIR:=/tmp}/$$.$x"
do mkdir -- "$TMPDIR/$$.$((x+=1))"
done &&
x=$x "$0" "$@" | _log notice
exit
} 2>&1 | _log error
Basicamente, isso permitiria que seu script se chamasse se ainda não o fez e obterá um diretório de trabalho em temp para inicializar.