Substitusi perintah / proses 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
Anda harus dapat menggunakannya seperti:
exec >"$(_log notice)" 2>"$(_log error)"
Berikut adalah versi yang menggunakan mktemp
perintah:
_log()( p=
mkfifo "${p:=$(mktemp -u)}" &&
printf %s "$p" &&
exec <&- >&- <>/dev/null >&0 &&
{ rm "$p"
logger --priority user."$1" --tag "${0##*/}"
} <"$p" &
)
... yang tidak jauh berbeda, kecuali memungkinkan mktemp
untuk memilih nama file untuk Anda. Ini bekerja karena proses substitusi sama sekali tidak ajaib dan bekerja dengan cara yang sangat mirip dengan perintah substitusi . Alih-alih mengganti ekspansi dengan nilai perintah yang dijalankan di dalamnya seperti yang dilakukan penggantian substitusi , substitusi proses menggantinya dengan nama tautan filesystem di mana output dapat ditemukan.
Sementara shell POSIX tidak memberikan akibat langsung pada hal seperti itu, meniru itu sangat mudah dilakukan. Yang perlu Anda lakukan adalah membuat file, mencetak namanya ke standar dari substitusi perintah, dan di latar belakang jalankan perintah Anda yang akan menghasilkan file itu. Sekarang Anda bisa mengarahkan kembali ke nilai ekspansi itu - persis seperti yang Anda lakukan dengan substitusi proses. Jadi shell POSIX menyediakan semua alat yang Anda butuhkan tentu saja - yang diperlukan hanyalah Anda menempatkannya untuk digunakan dengan cara yang sesuai untuk Anda.
Kedua versi di atas memastikan bahwa mereka menghancurkan tautan sistem file ke pipa yang mereka buat / gunakan sebelum menggunakannya. Ini berarti tidak ada pembersihan yang diperlukan setelah fakta, dan, yang lebih penting, aliran mereka hanya tersedia untuk proses yang awalnya membukanya - dan karenanya tautan sistem file mereka tidak dapat digunakan sebagai sarana untuk mengintai / membajak aktivitas logging Anda. Untuk meninggalkan fs-link mereka di sistem file adalah lubang keamanan potensial.
Cara lain adalah membungkusnya. Itu bisa dilakukan dari dalam skrip.
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
Itu pada dasarnya akan memungkinkan skrip Anda untuk memanggil dirinya sendiri jika belum dan membuat Anda direktori kerja di temp untuk boot.