Comando POSIX / sustitución de procesos
_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
Deberías poder usar eso como:
exec >"$(_log notice)" 2>"$(_log error)"
Aquí hay una versión que hace uso del 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 hace casi lo mismo, excepto que permite mktemp
seleccionar el nombre de archivo por usted. Esto funciona porque la sustitución del proceso no es mágica y funciona de manera muy similar a la sustitución de comandos . En lugar de reemplazar la expansión con el valor del comando ejecutado dentro de ella como lo hace la sustitución de comando , la sustitución del proceso la reemplaza con el nombre de un enlace del sistema de archivos donde se puede encontrar la salida.
Si bien el shell POSIX no proporciona un corolario directo a tal cosa, emularlo es muy simple. Todo lo que necesita hacer es crear un archivo, imprimir su nombre al estándar de una sustitución de comando, y en el fondo del mismo ejecutar su comando que se enviará a ese archivo. Ahora puede redirigir al valor de esa expansión, exactamente como lo hace con la sustitución de procesos. Y, por lo tanto, el shell POSIX proporciona todas las herramientas que necesita, por supuesto, todo lo que se requiere es que las use de la manera que más le convenga.
Ambas versiones anteriores aseguran que destruyan el enlace del sistema de archivos a las tuberías que crean / usan antes de usarlas. Esto significa que no se requiere una limpieza después del hecho y, lo que es más importante, sus transmisiones solo están disponibles para los procesos que inicialmente las abren, por lo que sus enlaces del sistema de archivos no pueden usarse como un medio para espiar / secuestrar su actividad de registro. Dejar sus enlaces fs en el sistema de archivos es un agujero de seguridad potencial.
Otra forma es envolverlo. Se puede hacer desde el 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
Básicamente, eso permitiría que su script se llame a sí mismo si aún no lo ha hecho y le obtenga un directorio de trabajo en temp para arrancar.