Fitur itu diperkenalkan oleh ksh
(pertama kali didokumentasikan dalam ksh86) dan memanfaatkan /dev/fd/n
fitur tersebut (ditambahkan secara independen di beberapa BSD dan sistem AT&T sebelumnya). Di ksh
dan hingga ksh93u, itu tidak akan berfungsi kecuali sistem Anda memiliki dukungan untuk / dev / fd / n. zsh, bash dan ksh93u+
dan di atas dapat menggunakan pipa bernama sementara (pipa bernama ditambahkan di SysIII saya percaya) di mana / dev / fd / n tidak tersedia.
Pada sistem di mana tersedia (POSIX tidak menentukan itu), Anda dapat melakukan sendiri proses substitusi ( ) dengan:/dev/fd/n
diff <(cmd1) <(cmd2)
{
cmd1 4<&- | {
# in here fd 3 points to the reading end of the pipe
# from cmd1, while fd 0 has been restored from the original
# stdin (saved on fd 4, now closed as no longer needed)
cmd2 3<&- | diff /dev/fd/3 -
} 3<&0 <&4 4<&- # restore the original stdin for cmd2
} 4<&0 # save a copy of stdin for cmd2
Namun itu tidak bekerja dengan ksh93
di Linux seperti di sana, pipa shell diimplementasikan dengan socketpairs bukan pipa dan membuka di /dev/fd/3
mana fd 3 menunjuk ke soket tidak bekerja di Linux.
Meskipun POSIX tidak menentukan . Itu menentukan pipa bernama. Pipa bernama bekerja seperti pipa normal kecuali Anda dapat mengaksesnya dari sistem file. Masalahnya di sini adalah bahwa Anda harus membuat yang sementara dan membersihkan yang sulit dilakukan dengan andal terutama mengingat bahwa POSIX tidak memiliki mekanisme standar (seperti yang ditemukan pada beberapa sistem) untuk membuat file atau direktori sementara, dan melakukan penanganan sinyal dengan mudah. (untuk membersihkan pada saat hang-up atau membunuh) juga sulit dilakukan dengan mudah./dev/fd/n
mktemp -d
Anda dapat melakukan sesuatu seperti:
tmpfifo() (
n=0
until
fifo=$1.$$.$n
mkfifo -m 600 -- "$fifo" 2> /dev/null
do
n=$((n + 1))
# give up after 20 attempts as it could be a permanent condition
# that prevents us from creating fifos. You'd need to raise that
# limit if you intend to create (and use at the same time)
# more than 20 fifos in your script
[ "$n" -lt 20 ] || exit 1
done
printf '%s\n' "$fifo"
)
cleanup() { rm -f -- "$fifo"; }
fifo=$(tmpfifo /tmp/fifo) || exit
cmd2 > "$fifo" & cmd1 | diff - "$fifo"
rm -f -- "$fifo"
(tidak mengurus penanganan sinyal di sini).