Adlandırılmış bir kanaldan stdin alma


10

Ne yapmaya çalışıyorum bir terminal penceresinde python çalıştırmak ve bu adlandırılmış bir borudan stdin yönlendirmektir. Sonra başka bir terminalde adlandırılmış boruya yazarım ve bu komutun python'da çalıştırılmasını sağlarım.

Terminal 1:

mkfifo p1
python < p1

Terminal 2:

echo -n "print \"Hello World\"" > p1

Ne olur - python yazdırır Hello Worldve çıkar. Ne yapmak istiyorum bir sonraki komutu almak için python çalışan tutmaktır. Bunu kabukta nasıl yaparım?

Yanıtlar:


10

Gerek

  • Stdin bir terminal olmasa bile python'u etkileşimli olarak çalıştırın: use python -i
  • borunun yazma ucunu açık tutun, aksi takdirde python EOF'u algılar ve çıkar.

Yani:

python -i < p1

Ve başka yerlerde:

exec 3> p1
echo '1j*1j' >&3
...
# and when done, close that file descriptor so python sees the EOF:
exec 3>&-

Teşekkürler! İşe yaradı. Yaptıklarına aşina değilim. Neler olduğunu açıklamak için lütfen cevabınıza biraz ayrıntı ekler misiniz? Ne exec 3> p1yapıyor ve nedir &3& exec 3> &1? Teşekkür ederim.
Lord Loh.

1
Cevabınız bana bu afiş hatırlattı - sphotos-b.xx.fbcdn.net/hphotos-ash4/… facebook bir arkadaşın kapak pic :-)
Lord Loh.

Bir soru, burada exec 3>&-olduğu gibi çalışır exec 3>&1mı?
Joker

1
@Wildcard Buraya yazmak istediğimi sanıyorum 3>&-. 3>&1de işe yarayacaktı ama çok az mantıklı olacaktı. Teşekkürler
Stéphane Chazelas

5

tail -fFifo yazdıktan sonra açık tutmak için kullanabilirsiniz echo.

tail -n1 -f p1 | python

Bu neden çalışıyor?

pythonokuyor p1. Dosyanın sonuna geldiğinde okumayı durdurur. Bu, dosya adlandırılmış bir kanal olsa bile dosya okumaları için normal bir davranıştır. tailile -fbitiş ulaştıktan sonra (gidin) bayrağı bir dosyadan okumaya devam edecektir.


echo "print \"Hello World\" " > p1İkinci terminalde denedim ve hiçbir şey olmadı - ama terminal de engellenmedi. Python'lu terminal, ben çıkıncaya kadar bloke kaldı ^cve python tarafından görüntülenen bir klavye kesme mesajıyla python'u sonlandırdı.
Lord Loh.

Bu tail -fnumarayı, blok bölünmüş katran arşivini adlandırılmış bir borudan açarken kullandım . Harika çalıştı.
Mael

2

Tüm programı bir kerede göndermeniz gerekir.

Run python < p1komutunu çağırdığınızda, kabuk python çağırmadan önce girdi bekliyor. Olduğunu, piton bile yürütme başlamıyor hiç tüm veri akışı için bütünüyle geçirilir daha sonra kabuk tarafından okunur ve edilene kadar python.

python -u p1Bunun yerine çalıştırıldığında bile (yani, arabelleksiz ve dosyadan okuma p1) python, dosyayı yürütmeden önce tüm dosyayı okumaya çalışır.

Bu denemeyi deneyin.

Terminal 1:

mkfifo p1
python < p1

Terminal 2:

cat > p1
print "Hello World"
print "Hello World"

Birden çok satır gönderebileceğinizi göreceksiniz, ancak Terim 1'deki python hiçbir şey yapmıyor. Şimdi ctrl+ düğmesine basın D. Tüm program aynı anda yürütülür.

Özetlemek gerekirse, python'un bir kanaldan okumasını istiyorsanız, tüm programı göndermeniz gerekir. Python'u bu şekilde etkileşimli olarak kullanamazsınız.


1

Belki kuyruk yaklaşımı daha iyidir (daha esnek), ancak alternatif olarak:

{ echo -n "print \"Hello World\""; cat; } > p1

Bu istediğim gibi çalışmıyor. -nkaldırılmış olabilir. Ve bundan sonra, birlikte 0. terminali echokomutuyla ben basın dek 1. piton komutunu yürütmüyor bloke olur ^cyılında echoterminali ve hem süreç sona erdirebilir.
Lord Loh.

1
@LordLoh. Arabelleğe alma sorunu olabilir. Muhtemelen python, ilk satırın FIFO'ya yazılması için yeterli çıktı oluşturulduysa komutu yürütür. Ancak çalışan bir çözüm olduğu için bu sorunun çözümünde çaba sarf etmek mantıklı olmaz.
Hauke ​​Laging
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.