Заміна команд / процесів 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
Ви повинні мати можливість використовувати таке, як:
exec >"$(_log notice)" 2>"$(_log error)"
Ось версія, яка використовує mktemp
команду:
_log()( p=
mkfifo "${p:=$(mktemp -u)}" &&
printf %s "$p" &&
exec <&- >&- <>/dev/null >&0 &&
{ rm "$p"
logger --priority user."$1" --tag "${0##*/}"
} <"$p" &
)
... що робить те саме, за винятком того, що дозволяє mktemp
вибрати ім'я файлу для вас. Це працює, тому що підміна процесу аж ніяк не магічна і працює дуже подібним чином до підстановки команд . Замість заміни розширення значенням команди, запущеної всередині нього, як це робить підміна команд , процес підстановки замінює його іменем посилання файлової системи, де можна знайти вихід.
У той час як оболонка POSIX не забезпечує прямого наслідку для такого поняття, емуляція це робиться дуже просто. Все, що вам потрібно зробити - це створити файл, надрукувати його ім'я до стандарту з підстановки команд, а на тлі тієї ж самої запустіть свою команду, яка виведе в цей файл. Тепер ви можете просто перенаправити на значення цього розширення - точно так само, як і при заміні процесу. І тому оболонка POSIX, безумовно, надає всі необхідні вам інструменти - все, що потрібно, це ви використовуєте їх для використання так, як вам підходить.
Обидві вищевказані версії гарантують, що вони руйнують посилання файлової системи на створені ними / використані труби, перш ніж використовувати їх. Це означає, що після факту не потрібно очищення, і, що ще важливіше, їх потоки доступні лише для тих процесів, які спочатку їх відкривають, - і тому їх посилання на файлові системи не можуть використовуватися як засіб для вивільнення / викрадення вашої активності журналу. Залишити свої fs-посилання у файловій системі - це потенційна дірка безпеки.
Ще один спосіб - загорнути його. Це можна зробити всередині сценарію.
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
Це в основному дозволить вашому сценарію зателефонувати, якщо він ще не працює, і отримати робочу директорію в темпе для завантаження.