Biliyorsunuz, diyagramlarınızın gösterdiği gibi mutlaka tekrar eden bir geri bildirim döngüsüne ihtiyacınız olduğuna ikna olmadım, belki bir yardımcı işlemler arasında kalıcı bir boru hattı . Sonra tekrar, çok fazla bir fark olmayabilir - bir coprocess üzerinde bir çizgi açtığınızda, sıradan bir şey yapmadan sadece bilgi yazma ve ondan bilgi okuma tipik stil döngülerini uygulayabilirsiniz.
İlk olarak, bc
sizin için bir işbirliği süreci için birincil bir aday gibi görünecektir . İçindebc
define
pseudocode'unuzda istediğinizi yapabilen işlevler yapabilirsiniz. Örneğin, bunu yapmak için bazı çok basit işlevler şöyle görünebilir:
printf '%s()\n' b c a |
3<&0 <&- bc -l <<\IN <&3
a=1; b=0; c=0;
define a(){ "a="; return (a = c+1); }
define b(){ "b="; return (b = 3*a); }
define c(){ "c="; return (c = s(b)); }
IN
... yazdıracak ...
b=3
c=.14112000805986722210
a=1.14112000805986722210
Ama elbette, sürmez . En kısa sürede sorumlu alt kabuğa olarak printf
bireyin boru kapanıyor (hemen sonraprintf
yazma a()\n
borusuna) boru yıkılıp edilir bc
'ın giriş kapanır ve çok kapanıyor. Bu neredeyse olabildiğince yararlı değil.
@derobert zaten belirtildiği FIFO bir oluşturarak vardı edilebilir s adlandırılan boru dosyayı mkfifo
programı. Bunlar, sistem çekirdeğinin bir dosya sistemi girişini her iki uca da bağlaması dışında, aslında sadece borulardır. Bunlar çok faydalıdır, ancak dosya sisteminde gözetleme riski olmadan bir boruya sahip olmanız daha iyi olurdu.
Olduğu gibi, kabuğunuz bunu çok yapar. İşlem ikamesi uygulayan bir kabuk kullanıyorsanız kalıcı bir boru elde etmek için çok basit bir yolunuz vardır - bu, iletişim kurabileceğiniz arka planlı bir sürece atayabileceğiniz türde.
İçinde bash
Örneğin, nasıl işlem ikame işleri görebilirsiniz:
bash -cx ': <(:)'
+ : /dev/fd/63
Görüyorsunuz gerçekten bir ikame . Kabuk, genişleme sırasında bir boru bağlantısına giden yola karşılık gelen bir değer yerine geçer . Bundan faydalanabilirsiniz - bu boruyu yalnızca içinde hangi işlem yapılırsa kullanılsın iletişim kurmak için kısıtlamanız gerekmez.()
ikame ...
bash -c '
eval "exec 3<>"<(:) "4<>"<(:)
cat <&4 >&3 &
echo hey cat >&4
read hiback <&3
echo "$hiback" here'
... hangi baskı ...
hey cat here
Şimdi farklı kabuklar yapmak biliyoruz yardımcı işlemci farklı şekillerde şey - ve belirli bir sözdizimi olduğunu bash
birini kurmak için (ve muhtemelen bir için zsh
de) - ama nasıl böyle şeyler işi bilmiyorum. Sadece hem tekerleme tüm olmadan hemen hemen aynı şeyi yapmak için yukarıdaki sözdizimi kullanabileceğinizi biliyor bash
ve zsh
- ve de çok benzer bir şeyi yapabilir dash
ve busybox ash
burada-belgelerle aynı amaca ulaşmak için (çünkü dash
vebusybox
burada-do diğer ikisi gibi geçici dosyalar yerine pipetli belgeler) .
Yani, uygulandığında bc
...
eval "exec 3<>"<(:) "4<>"<(:)
bc -l <<\INIT <&4 >&3 &
a=1; b=0; c=0;
define a(){ "a="; return (a = c+1); }
define b(){ "b="; return (b = 3*a); }
define c(){ "c="; return (c = s(b)); }
INIT
export BCOUT=3 BCIN=4 BCPID="$!"
... zor kısmı bu. Ve bu eğlenceli kısım ...
set --
until [ "$#" -eq 10 ]
do printf '%s()\n' b c a >&"$BCIN"
set "$@" "$(head -n 3 <&"$BCOUT")"
done; printf %s\\n "$@"
... hangi baskı ...
b=3
c=.14112000805986722210
a=1.14112000805986722210
#...24 more lines...
b=3.92307618030433853649
c=-.70433330413228041035
a=.29566669586771958965
... ve hala çalışıyor ...
echo a >&"$BCIN"
read a <&"$BCOUT"
echo "$a"
... bana son değerini aldığı bc
'ın a
yerine çağırmaktan daha a()
bunu ve baskılar artırmak işlevini ...
.29566669586771958965
Aslında onu öldürüp IPC borularını yıkana kadar koşmaya devam edecek ...
kill "$BCPID"; exec 3>&- 4>&-
unset BCPID BCIN BCOUT