Adlandırılmış bir boruya otomatik EOF'leri önleme ve istediğim zaman bir EOF gönderme


12

Belirli bir akış (aşağıdaki durumda, stdin) bir EOF okuduktan sonra otomatik olarak çıkan bir program var.
Şimdi adlandırılmış bir kanal oluşturan ve programın stdin'ini ona bağlayan bir kabuk betiği yapmak istiyorum. Daha sonra komut dosyası, ve (ve çıktıklarında otomatik olarak bir EOF oluşturan diğer araçlar) kullanarak birkaç kez boruya yazar . Karşılaştığım sorun, ilk yapıldığında boruya bir EOF gönderiyor ve programdan çıkış yapıyor. Eğer böyle bir şey kullanırsam , programdan çıkmak istediğimde EOF gönderemem. Dengeli bir çözüm araştırıyorum ama boşuna. Zaten EOF'ların nasıl önleneceğini ve manuel olarak bir EOF'un nasıl gönderileceğini buldum ama bunları birleştiremiyorum. İpucu var mı? echocatechotail -f

#!/bin/sh
mkfifo P
program < P & : # Run in background
# < P tail -n +1 -f | program
echo some stuff > P # Prevent EOF?
cat more_stuff.txt > P # Prevent EOF?
send_eof > P # How can I do this?
# fg

Yanıtlar:


13

Diğerlerinin de belirttiği gibi, bir boru okuyucu kalmadı, EOF alır. Dolayısıyla çözüm, onu daima açık tutan bir yazar olduğundan emin olmaktır. O yazar hiçbir şey göndermek zorunda değil, sadece açık tutun.

Bir kabuk komut dosyası kullandığınızdan, en basit çözüm kabuğa yazmak için boruyu açmasını söylemektir. Ve sonra işiniz bittiğinde kapatın.

#!/bin/sh
mkfifo P
exec 3>P # open file descriptor 3 writing to the pipe
program < P
# < P tail -n +1 -f | program
echo some stuff > P
cat more_stuff.txt > P
exec 3>&- # close file descriptor 3

Son satırı atlarsanız, komut dosyası çıktığında dosya tanımlayıcı 3'ün otomatik olarak kapatılacağını (ve böylece okuyucunun EOF aldığını) unutmayın. Kolaylığın yanı sıra, komut dosyasının bir şekilde erken sona erdirilmesi durumunda da bu tür bir güvenlik sağlar.


2
bu exec 3>Pneden bash içinde asılı, neden?
Wang

@Wang Olmamalı. Eğer öyleyse, muhtemelen sorudaki POC koduyla aynı şeyi yapmıyorsunuzdur. Engellemesini düşünebilmemin tek nedeni, bunun yerine böyle bir şey yapıyorsanız exec 2>Pve set -xbashın boruya yazacağı izleme modunuz açıksa ( ), ancak okuyucu yok, bu yüzden beklemeyi engelliyor okunacak bir şey.
Patrick

1
@ Wang @Patrick Gerçekten de makinemde exec 3>Pbash asılı. Bunun nedeni, okuma işlemi yapılmamasıdır P. Böylece, çözüm hatları değiştirmek exec 3>Pve program < P &(ve işareti programın arka planda çalışmasını sağlamak için) eklemekti.
macieksk

2

Bir boru son yazar gittiğinde EOF alır. Bundan kaçınmak için her zaman bir yazar olduğundan emin olun (boruyu yazmaya açık olan, ancak aslında hiçbir şey yazmayan bir işlem). EOF'u göndermek için yedek yazarın gitmesini sağlayın.

mkfifo P
while sleep 1; do :; done >P &
P_writer_pid=$!
send_eof_to_P () {
  kill $P_writer_pid
}

0

Programın "bırakma zamanı" anlamına gelen bir EOF ile "bir yazar yapılır, ancak başka birinden daha fazla girdi olabilir" anlamına gelen bir EOF arasında ayrım yapmanın bir yolu yoktur.

Programınızın davranışını değiştirme yeteneğine sahipseniz, okumayı sonsuz bir döngüde yapın (bir yineleme EOF'a kadar sürer) ve ona "çıkış zamanı" anlamına gelen belirli bir komut dizesi gönderin. Bu dizeyi göndermek, send_eofsorunuzdaki komutun görevi olacaktır .

Başka seçenek:

( echo some stuff; cat more_stuff.txt ) >P

veya

{ echo some stuff; cat more_stuff.txt; } >P
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.