bashVersion 4 verfügt über einen coprocBefehl, der dies in reinen bashPipes ohne Named Pipes ermöglicht:
coproc cmd1
eval "exec cmd2 <&${COPROC[0]} >&${COPROC[1]}"
Einige andere Muscheln können das coprocauch.
Nachfolgend finden Sie eine ausführlichere Antwort, die jedoch drei anstelle von zwei Befehlen verkettet, was ein wenig interessanter macht.
Wenn Sie auch gerne verwenden catund stdbufdann konstruieren, kann das leichter verständlich gemacht werden.
Version bashmit catund stdbuf, leicht verständlich:
# start pipeline
coproc {
cmd1 | cmd2 | cmd3
}
# create command to reconnect STDOUT `cmd3` to STDIN of `cmd1`
endcmd="exec stdbuf -i0 -o0 /bin/cat <&${COPROC[0]} >&${COPROC[1]}"
# eval the command.
eval "${endcmd}"
Beachten Sie, dass Sie eval verwenden müssen, da die Variablenerweiterung in <& $ var in meiner Version von Bash 4.2.25 illegal ist.
Version using pure bash: In zwei Teile aufteilen, erste Pipeline unter Coproc starten, dann den zweiten Teil zu Mittag essen (entweder ein einzelner Befehl oder eine Pipeline) und wieder mit der ersten verbinden:
coproc {
cmd 1 | cmd2
}
endcmd="exec cmd3 <&${COPROC[0]} >&${COPROC[1]}"
eval "${endcmd}"
Konzeptioneller Beweiß:
Datei ./prog, nur ein Dummy-Programm zum Verzehren, Markieren und erneuten Drucken von Zeilen. Die Verwendung von Subshells, um Pufferprobleme zu vermeiden, kann zu einem Übermaß führen. Hier geht es nicht darum.
#!/bin/bash
let c=0
sleep 2
[ "$1" == "1" ] && ( echo start )
while : ; do
line=$( head -1 )
echo "$1:${c} ${line}" 1>&2
sleep 2
( echo "$1:${c} ${line}" )
let c++
[ $c -eq 3 ] && exit
done
Datei ./start_cat
Dies ist eine Version mit bash, catundstdbuf
#!/bin/bash
echo starting first cmd>&2
coproc {
stdbuf -i0 -o0 ./prog 1 \
| stdbuf -i0 -o0 ./prog 2 \
| stdbuf -i0 -o0 ./prog 3
}
echo "Delaying remainer" 1>&2
sleep 5
cmd="exec stdbuf -i0 -o0 /bin/cat <&${COPROC[0]} >&${COPROC[1]}"
echo "Running: ${cmd}" >&2
eval "${cmd}"
oder Datei ./start_part. Dies ist eine Version, die bashnur pure verwendet . Für Demozwecke verwende ich immer noch, stdbufweil Ihr echter Prog sich sowieso intern mit dem Puffern befassen müsste, um ein Blockieren aufgrund von Puffern zu vermeiden.
#!/bin/bash
echo starting first cmd>&2
coproc {
stdbuf -i0 -o0 ./prog 1 \
| stdbuf -i0 -o0 ./prog 2
}
echo "Delaying remainer" 1>&2
sleep 5
cmd="exec stdbuf -i0 -o0 ./prog 3 <&${COPROC[0]} >&${COPROC[1]}"
echo "Running: ${cmd}" >&2
eval "${cmd}"
Ausgabe:
> ~/iolooptest$ ./start_part
starting first cmd
Delaying remainer
2:0 start
Running: exec stdbuf -i0 -o0 ./prog 3 <&63 >&60
3:0 2:0 start
1:0 3:0 2:0 start
2:1 1:0 3:0 2:0 start
3:1 2:1 1:0 3:0 2:0 start
1:1 3:1 2:1 1:0 3:0 2:0 start
2:2 1:1 3:1 2:1 1:0 3:0 2:0 start
3:2 2:2 1:1 3:1 2:1 1:0 3:0 2:0 start
1:2 3:2 2:2 1:1 3:1 2:1 1:0 3:0 2:0 start
Das tut es.