POSIX-Befehls- / Prozessersetzung
_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
Sie sollten in der Lage sein, Folgendes zu verwenden:
exec >"$(_log notice)" 2>"$(_log error)"
Hier ist eine Version, die den mktemp
Befehl verwendet:
_log()( p=
mkfifo "${p:=$(mktemp -u)}" &&
printf %s "$p" &&
exec <&- >&- <>/dev/null >&0 &&
{ rm "$p"
logger --priority user."$1" --tag "${0##*/}"
} <"$p" &
)
... was fast genauso ist, außer dass es erlaubt mktemp
, den Dateinamen für Sie auszuwählen. Dies funktioniert, weil die Prozessersetzung keineswegs magisch ist und der Befehlssubstitution sehr ähnlich ist . Anstatt die Erweiterung durch den Wert des darin ausgeführten Befehls zu ersetzen, wie dies bei der Befehlsersetzung der Fall ist, wird sie durch die Prozessersetzung durch den Namen einer Dateisystemverknüpfung ersetzt, in der sich die Ausgabe befindet.
Während die POSIX-Shell keine direkte Folge davon bietet, ist die Emulation sehr einfach. Alles, was Sie tun müssen, ist, eine Datei zu erstellen, ihren Namen aus einer Befehlsersetzung in den Standard zu drucken und im Hintergrund desselben Ihren Befehl auszuführen, der in diese Datei ausgegeben wird. Jetzt können Sie einfach in den Wert dieser Erweiterung umleiten - genau wie bei der Prozessersetzung. Und so bietet die POSIX-Shell natürlich alle Tools, die Sie benötigen - alles, was Sie benötigen, ist, dass Sie sie auf eine Weise verwenden, die zu Ihnen passt.
Beide oben genannten Versionen stellen sicher, dass die Dateisystemverbindung zu den von ihnen erstellten / verwendeten Pipes zerstört wird, bevor sie jemals verwendet werden. Dies bedeutet, dass nachträglich keine Bereinigung erforderlich ist und, was noch wichtiger ist, ihre Streams nur für die Prozesse verfügbar sind, die sie anfänglich öffnen. Daher können ihre Dateisystem-Links nicht als Mittel zum Aufspüren / Entführen Ihrer Protokollierungsaktivität verwendet werden. Ihre fs-Links im Dateisystem zu belassen, ist eine potenzielle Sicherheitslücke.
Eine andere Möglichkeit besteht darin, es einzuwickeln. Dies kann innerhalb des Skripts erfolgen.
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
Das würde es Ihrem Skript grundsätzlich ermöglichen, sich selbst aufzurufen, wenn dies noch nicht geschehen ist, und Ihnen ein Arbeitsverzeichnis in temporärem Zustand zum Booten zu geben.