その機能はksh
(最初にksh86で文書化された)によって導入され、その機能を利用してい/dev/fd/n
ました(以前のBSDやAT&Tシステムで独立して追加されました)。内ksh
とksh93uまで、それが仕事ではないだろう、あなたのシステムはは/ dev / fdを/ nのサポートがあった場合を除きます。zsh、bashなどはksh93u+
、/ dev / fd / nが利用できない一時的な名前付きパイプ(SysIIIで追加された名前付きパイプ)を使用できます。
利用可能なシステムでは(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では動作せず、シェルパイプはパイプではなく/dev/fd/3
ソケットペアで実装され、Linuxではfd 3がソケットを指す場所を開けません。
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"
(ここでは信号処理を行いません)。