Ця функція була введена ksh
(вперше задокументована в ksh86) і використовує цю /dev/fd/n
функцію (додається незалежно в деяких системах BSD та AT&T раніше). До ksh
і до ksh93u, воно не працюватиме, якщо ваша система не мала підтримку / dev / fd / n. zsh, bash і ksh93u+
вище можуть використовувати тимчасові названі труби (названі труби додані в SysIII, я вважаю), де / dev / fd / n недоступні.
У системах, де доступні (POSIX не вказує їх), ви можете зробити заміну самостійно ( ):/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
Однак це не працює з ksh93
Linux, як там, оболонки труби реалізуються разом з socketpairs, а не відкриттями, /dev/fd/3
де fd 3 бали на сокет не працює в Linux.
Хоча POSIX не вказує . У ньому вказуються названі труби. Названі труби працюють як звичайні труби, за винятком того, що ви можете отримати доступ до них з файлової системи. Проблема тут полягає в тому, що вам потрібно створити тимчасові та очистити їх згодом, що важко зробити надійно, особливо враховуючи, що POSIX не має стандартного механізму (як, наприклад , у деяких системах) для створення тимчасових файлів чи каталогів, а також обробку сигналів портативно (прибирати під час відключення чи вбивства) також важко зробити портативно./dev/fd/n
mktemp -d
Ви можете зробити щось на кшталт:
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"
(не піклуючись про обробку сигналу тут).