Ta funkcja została wprowadzona przez ksh
(po raz pierwszy udokumentowana w ksh86) i korzystała z tej /dev/fd/n
funkcji (dodana niezależnie w niektórych systemach BSD i AT&T wcześniej). W ksh
wersjach ksh93u i nowszych nie działałoby, gdyby Twój system nie obsługiwał / dev / fd / n. Zsh, bash i ksh93u+
wyżej mogą korzystać z tymczasowych nazwanych potoków (uważam nazwane potoki dodane w SysIII), gdzie / dev / fd / n nie są dostępne.
W systemach, w których jest dostępny (POSIX ich nie określa), możesz samodzielnie dokonać procesu podstawienia ( ):/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
Jednak to nie działa ksh93
w systemie Linux, ponieważ potoki powłoki są implementowane za pomocą par /dev/fd/3
gniazd zamiast potoków i otwierania, w którym fd 3 wskazuje gniazdo nie działa w systemie Linux.
Chociaż POSIX nie określa . Określa nazwane potoki. Nazwane potoki działają jak normalne potoki, z wyjątkiem tego, że można uzyskać do nich dostęp z systemu plików. Problem polega na tym, że musisz utworzyć pliki tymczasowe i wyczyścić je później, co jest trudne do wykonania w sposób niezawodny, szczególnie biorąc pod uwagę, że POSIX nie ma standardowego mechanizmu (takiego jak w niektórych systemach) do tworzenia plików tymczasowych lub katalogów i przenoszenia sygnałów w sposób przenośny (sprzątanie po rozłączeniu lub zabiciu) jest również trudne do przeniesienia./dev/fd/n
mktemp -d
Możesz zrobić coś takiego:
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"
(nie zajmując się tutaj obsługą sygnałów).