Substitution de commandes / processus POSIX
_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
Vous devriez pouvoir l'utiliser comme:
exec >"$(_log notice)" 2>"$(_log error)"
Voici une version qui utilise la mktemp
commande:
_log()( p=
mkfifo "${p:=$(mktemp -u)}" &&
printf %s "$p" &&
exec <&- >&- <>/dev/null >&0 &&
{ rm "$p"
logger --priority user."$1" --tag "${0##*/}"
} <"$p" &
)
... qui fait à peu près la même chose, sauf qu'il permet mktemp
de sélectionner le nom de fichier pour vous. Cela fonctionne parce que la substitution de processus n'est en aucun cas magique et fonctionne de manière très similaire à la substitution de commandes . Au lieu de remplacer l'expansion avec la valeur de la commande exécuter en son sein comme une substitution de commande fait, la substitution de processus remplace par le nom d'un lien de système de fichiers où la sortie se trouve.
Bien que le shell POSIX ne fournisse pas de corollaire direct à une telle chose, l'émuler se fait très simplement. Tout ce que vous avez à faire est de créer un fichier, d'imprimer son nom dans la norme à partir d'une substitution de commande et, en arrière-plan, d'exécuter votre commande qui sortira dans ce fichier. Maintenant, vous pouvez simplement rediriger vers la valeur de cette expansion - exactement comme vous le faites avec la substitution de processus. Et donc le shell POSIX fournit tous les outils dont vous avez besoin bien sûr - tout ce qui est requis est que vous les utilisiez d'une manière qui vous convient.
Les deux versions ci-dessus garantissent qu'elles détruisent le lien du système de fichiers vers les canaux qu'elles créent / utilisent avant de les utiliser. Cela signifie qu'aucun nettoyage n'est requis après coup, et, plus important encore, leurs flux ne sont disponibles que pour les processus qui les ouvrent initialement - et donc leurs liens de système de fichiers ne peuvent pas être utilisés comme un moyen pour espionner / détourner votre activité de journalisation. Laisser leurs liens fs dans le système de fichiers est une faille de sécurité potentielle.
Une autre façon est de l'envelopper. Cela peut être fait à partir du 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
Cela permettrait essentiellement à votre script de s'appeler s'il ne l'a pas encore fait et de vous obtenir un répertoire de travail dans temp pour démarrer.