bash
sürüm 4, coproc
bunun bash
adlandırılmış yöneltmeler olmadan saf olarak yapılmasına izin veren bir komuta sahiptir :
coproc cmd1
eval "exec cmd2 <&${COPROC[0]} >&${COPROC[1]}"
Bazı diğer kabukları da yapabilir coproc
.
Aşağıda daha ayrıntılı bir cevap var, ancak sadece biraz daha ilginç kılan iki komut yerine iki komut yerine.
Eğer kullanmaktan da memnunsanız cat
ve stdbuf
yapımı daha sonra anlamak daha kolay hale getirilebilir.
Sürüm kullanarak bash
ile cat
ve stdbuf
kolay anlaşılması:
# 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}"
Unutmayın, eval kullanmalısınız çünkü <& $ var değişkenindeki genişleme bash 4.2.25 versiyonumda geçersizdir.
Pure kullanarak sürüm bash
: İki parçaya bölün, ilk boru hattını coproc altında çalıştırın, sonra öğle yemeği ikinci kısmını (ya tek bir komut ya da bir boru hattı) ilkine yeniden bağlayın:
coproc {
cmd 1 | cmd2
}
endcmd="exec cmd3 <&${COPROC[0]} >&${COPROC[1]}"
eval "${endcmd}"
Kavramın ispatı:
dosya ./prog
, sadece tüketmek, etiketlemek ve satırları yeniden yazdırmak için sahte bir prog. Arabellek sorunlarından kaçınmak için alt kabukları kullanmak, muhtemelen fazla önemsiz, burada mesele değil.
#!/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
dosya ./start_cat
Bu kullanarak bir sürümüdür bash
, cat
vestdbuf
#!/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}"
veya dosya ./start_part
. Bu bash
sadece saf kullanan bir versiyondur . Demo amaçlı olarak, hala kullanıyorum stdbuf
çünkü gerçek programınız arabelleğe alma nedeniyle engellemeyi önlemek için zaten dahili olarak tamponlama yapmak zorunda kalacak.
#!/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}"
Çıktı:
> ~/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
Bu yapar.