Quella funzione è stata introdotta da ksh
(documentata per la prima volta in ksh86) e la utilizzava /dev/fd/n
(aggiunta in modo indipendente in alcuni sistemi BSD e AT&T in precedenza). In ksh
e fino a ksh93u, non funzionerebbe se il tuo sistema non avesse il supporto per / dev / fd / n. zsh, bash e ksh93u+
sopra possono usare pipe nominate temporanee (credo che vengano aggiunte pipe nominate nel SysIII) dove / dev / fd / n non sono disponibili.
Sui sistemi in cui è disponibile (POSIX non specifica quelli), è possibile eseguire personalmente la sostituzione ( ) con:/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
Tuttavia, ciò non funziona ksh93
su Linux in quanto lì, i pipe shell sono implementati con socket al posto dei pipe e l'apertura in /dev/fd/3
cui fd 3 punta a un socket non funziona su Linux.
Sebbene POSIX non specifichi . Specifica le pipe con nome. Le pipe con nome funzionano come normali pipe tranne per il fatto che è possibile accedervi dal file system. Il problema qui è che devi crearne di temporanei e ripulirli in seguito, il che è difficile da fare in modo affidabile soprattutto considerando che POSIX non ha meccanismi standard (come quelli che si trovano su alcuni sistemi) per creare file o directory temporanei e fare portabilità del segnale in modo portabile (ripulire dopo aver riagganciato o ucciso) è anche difficile da fare in modo portabile./dev/fd/n
mktemp -d
Potresti fare qualcosa del tipo:
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"
(non occupandosi della gestione del segnale qui).