答え1
この機能はksh
導入され(ksh86で最初に文書化されている)使用中です(以前は一部のBSDおよびAT&Tシステムに独立して追加されました)。 ksh93u以前では、システムがサポートしていない限り、zsh、bash以降では使用できない場合は、一時的な名前付きパイプ(System IIIに追加された名前付きパイプ)を使用できます。/dev/fd/n
ksh
/dev/fd/n
ksh93u+
/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
ただし、シェルパイプはパイプではなくソケットペアとして実装され、ソケットの場所を指す/dev/fd/3
fd 3を開くことはLinuxでは機能しないため、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"
cleanup
(ここでは信号処理を考慮していません。)
答え2
これを達成するには、heredocファイルと/ dev / fd / nファイルを使用できます。たとえば、bash
次のようにできます。
#!/usr/bin/env bash
paste <(echo "$SHELL") <(echo "$TERM") <(echo "$LANG")
ただし、POSIX shでは、次のことを行う必要があります。
#!/bin/sh
paste /dev/fd/3 3<<-EOF /dev/fd/4 4<<-EOF /dev/fd/5 5<<-EOF
$SHELL
EOF
$TERM
EOF
$LANG
EOF
出力は同じです。
質問に答えるには、次のように動作します。
#!/bin/sh
diff /dev/fd/3 3<<-EOF /dev/fd/4 4<<-EOF
$(sort file1)
EOF
$(sort file2)
EOF
あいまいに見えますが動作します。
答え3
便利な変数を失わないようにするにはcmd | while read A B C
:
VAR="before"
while read A B C
do
VAR="$A $VAR"
done < <(cmd)
echo "$VAR"
あなたはそれを使用することができます:
VAR="before"
while read A B C
do
VAR="$A $VAR"
done << EndOfText
`cmd`
EndOfText
echo "$VAR"
したがって、この質問に答えるには、次の手順を実行します。
sort file1 | diff /dev/stdin /dev/stdout 2<<EOT
`sort file2`
EOT