2012-05-07 26 views
8

Python'da bir kabuk komut dosyasını çağırmaya çalışıyorum ancak bozuk boru hatasını bildirmeye devam ediyor (sonuç tamam, ancak STDERR'deki hata mesajını görmek istemiyorum). Ben nedenini kesin olarak belirlemiş ve bu şu pasajı olarak yeniden olabilir:Python: subprocess.call kırık boru

subprocess.call('cat /dev/zero | head -c 10 | base64', shell=True)

aaaaaaaaaaaaaa ==

kedi: yazma hatası: Broken boru

/dev/zero, sonsuz akışıdır ama head -c 10 sadece ondan 10 bayt okur ve çıkar, sonra eşler boruyu kapattığı için kedi SIGPIPE alır. Komutu kabukta çalıştırdığımda kırık bir boru hatası mesajı yok, ancak python bunu neden gösteriyor?

+4

Hata kaybolduktan:

sen subprocess.call için preexec_fn argüman kullanabilirsiniz cat hata iletileri engellemek için Cat_% 28Unix% 29 # Useless_use_of_cat): 'subprocess.call ('head -c 10

+2

@larsmans: bunu bir yanıt olarak koyabilirsiniz –

+0

@ChrisMorgan: aslında, Cevabını şiddetle tercih ederim. –

cevap

2

Bu önemsiz durumda en azından kabuk komutlarını — kullanarak hiçbir şey kazanmıyorsunuz ve taşınabilirlik ve hız kaybediyorsunuz.

Python 2 kodu:

>>> import base64 
>>> base64.b64encode(open('/dev/zero', 'rb').read(10)) 
'AAAAAAAAAAAAAA==' 
>>> base64.b64encode('\0' * 10) 
'AAAAAAAAAAAAAA==' 

Python 3 (bu str yerine bytes daha örneklerini geri olsa kodu da, 2.6+ çalışır): Her iki durumda da

>>> import base64 
>>> base64.b64encode(open('/dev/zero', 'rb').read(10)) 
b'AAAAAAAAAAAAAA==' 
>>> base64.b64encode(b'\0' * 10) 
b'AAAAAAAAAAAAAA==' 

, ilk örnek, /dev/zero'un (kendi içinde taşınabilir olmayan, ama boşver) kullanımını korur, ikincisi etkiyi üretir, ancak özellikle istediğin gibi olmadığını hayal ediyorum.

+0

+1. '' x00 '' de '' 0 '' yazılabilir (ya da Python 3.x’de 'b '\ 0’'). –

+1

'\ 0',' \ x00'den daha kısa, sanırım ... –

+0

Sanırım alt adımın cevabını tercih ederim, bu da soruyu doğrudan ele alıyor ve sorunu açıklıyor. –

6

SIGPIPE sinyalinin varsayılan eylemi programı sonlandırmaktır. Python yorumlayıcısı, bozuk boru hatalarını bir programa istisnalar biçiminde bildirebilmek için SIG_IGN olarak değiştirir.

Kabukta cat ... |head ...'u çalıştırdığınızda, cat varsayılan SIGPIPE işleyicisine sahiptir ve OS çekirdeği yalnızca SIGPIPE üzerinde sonlandırır.

bunu kendi üst (piton yorumlayıcı) den SIGPIPE işleyicisi türetir subprocess kullanılarak cat yürütmek

, SIGPIPE sadece göz ardı ve cat errno değişken ve baskı hata mesajı kontrol ederek hatasını kendisi işler. Eğer [uuoc] atlamak zaman https://en.wikipedia.org/wiki/ (

from signal import signal, SIGPIPE, SIG_DFL 
subprocess.call(
    'cat /dev/zero | head -c 10 | base64', 
    shell = True, 
    preexec_fn = lambda: signal(SIGPIPE, SIG_DFL) 
) 
+0

Mükemmel, bunun için çok teşekkürler, sadece kedi kullanarak bir kabuk betiği ile benim problemi çözdüm (ve uuoc, belki de başka bir soru değil, eminim). –

+0

gerçekten mükemmel bir açıklama ve çözüm. –

+0

Mükemmel! Sabit bir tr: subprocess.call() ile bir bash komutunu çağırmaktan kaynaklanan kırık bir boru hatası – Hanynowsky

İlgili konular