Diese Funktion wurde von ksh
(erstmals in ksh86 dokumentiert) eingeführt und nutzte die /dev/fd/n
Funktion (in einigen BSDs und AT & T-Systemen zuvor unabhängig hinzugefügt). In ksh
und bis ksh93u würde es nicht funktionieren, wenn Ihr System nicht die Unterstützung für / dev / fd / n hätte. Ab zsh, bash und ksh93u+
höher können temporäre Named Pipes (Named Pipes, die meiner Meinung nach in SysIII hinzugefügt wurden) verwendet werden, bei denen / dev / fd / n nicht verfügbar ist.
Auf Systemen, auf denen verfügbar ist (POSIX gibt diese nicht an), können Sie die Substitution selbst durchführen ( ) mit:/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
Unter ksh93
Linux funktioniert dies jedoch nicht , da Shell-Pipes mit Socket-Paaren anstelle von Pipes implementiert werden und das Öffnen, /dev/fd/3
bei dem fd 3 auf einen Socket zeigt, unter Linux nicht funktioniert.
Obwohl POSIX nicht spezifiziert . Es werden Named Pipes angegeben. Named Pipes funktionieren wie normale Pipes, nur dass Sie über das Dateisystem darauf zugreifen können. Das Problem hierbei ist, dass Sie temporäre Dateien erstellen und diese anschließend bereinigen müssen. Dies ist schwierig, da POSIX über keinen Standardmechanismus (wie er auf einigen Systemen zu finden ist) verfügt, um temporäre Dateien oder Verzeichnisse zu erstellen und die Signalverarbeitung portabel durchzuführen (beim Auflegen oder Töten aufzuräumen) ist auch schwer tragbar zu machen./dev/fd/n
mktemp -d
Sie könnten etwas tun wie:
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"
(kümmert sich hier nicht um die Signalverarbeitung).