سؤال

ولدي بعض البيانات التي أود أن غزيب، UUENCODE ثم الطباعة إلى مستوى الخروج. ما أنا أساسا دينا هو:

compressor = Popen("gzip", stdin = subprocess.PIPE, stdout = subprocess.PIPE)
encoder    = Popen(["uuencode", "dummy"], stdin = compressor.stdout)

والطريقة أنا تغذية البيانات إلى الضاغط من خلال compressor.stdin.write (الاشياء).

وماذا أنا حقا بحاجة الى القيام به هو إرسال EOF إلى الضاغط، وليس لدي أي فكرة عن كيفية القيام بذلك.

وعند نقطة ما، حاولت compressor.stdin.close () ولكن هذا لا يعمل - أنها تعمل بشكل جيد عندما يكتب الضاغط إلى ملف مباشرة، ولكن في حالة أعلاه، فإن العملية لا تنتهي والأكشاك على compressor.wait ().

واقتراحات؟ في هذه الحالة، غزيب هو مثال وأنا فعلا بحاجة إلى القيام بشيء ما مع الأنابيب إخراج عملية واحدة إلى أخرى.

ملحوظة: البيانات ولست بحاجة لضغط لن تجد لها مكانا في الذاكرة، لذلك التواصل ليس حقا خيارا جيدا هنا. أيضا، إذا كنت مجرد تشغيل

compressor.communicate("Testing") 

وبعد خطوط 2 أعلاه، فإنه لا يزال يخيم مع الخطأ

  File "/usr/lib/python2.4/subprocess.py", line 1041, in communicate
    rlist, wlist, xlist = select.select(read_set, write_set, [])
هل كانت مفيدة؟

المحلول

وأظن أن المشكلة مع الترتيب الذي قمت بفتح الأنابيب. UUENCODE هو مضحك هو أنها لن الأنين عند إطلاقه اذا لم يكن هناك الأنابيب واردة فقط في الطريق الصحيح (محاولة إطلاق الشيء الرتق على نفسه في مكالمة Popen لرؤية الانفجار مع PIPE تماما كما ستدين والمعياري)

وجرب هذا:

encoder = Popen(["uuencode", "dummy"], stdin=PIPE, stdout=PIPE)
compressor = Popen("gzip", stdin=PIPE, stdout=encoder.stdin)

compressor.communicate("UUencode me please")
encoded_text = encoder.communicate()[0]
print encoded_text

begin 644 dummy
F'XL(`%]^L$D``PL-3<U+SD])5<A-52C(24TL3@4`;2O+"!(`````
`
end

وأنت على حق، راجع للشغل ... لا توجد وسيلة لإرسال EOF عامة أسفل الأنبوب. بعد كل شيء، كل برنامج وتعرف حقا EOF الخاص بها. على طريقة للقيام بذلك هي لإغلاق الأنابيب، كما كنت تحاول القيام به.

وتحرير: يجب أن أكون أكثر وضوحا حول إلغاء ترميز. كبرنامج قذيفة، انها السلوك الافتراضي هو أن نتوقع إدخال وحدة التحكم. إذا قمت بتشغيل دون أنبوب واردة "العيش"، فإنه سيتم منع انتظار إدخال وحدة التحكم. عن طريق فتح الثانية التشفير، قبل كنت قد أرسلت المواد إلى أسفل الأنبوب ضاغط، والتشفير تم حظر انتظاركم لبدء الكتابة. كان Jerub الحق في أن هناك شيئا حظر.

نصائح أخرى

وهذه ليست نوعا من شيء يجب أن تقوم به مباشرة في بيثون، هناك غرابة الاطوار بشأن كيفية الشيء العمل التي تجعل من فكرة أفضل بكثير للقيام بذلك مع قذيفة. إذا يمكنك فقط استخدام subprocess.Popen. ( "فو | شريط"، قذيفة = صحيح)، ثم كل ما هو أفضل

وماذا يمكن أن يحدث هو أن غزيب لم تكن قادرة على انتاج كل من مدخلاته بعد، وسيكون قد تم الانتهاء لا خروج حتى يكتب المعياري في هذه العملية.

ويمكنك أن تبحث في ما هو نظام الاتصال عملية يتم حظر على إذا كنت تستخدم strace. استخدام ps auxwf لاكتشاف أي عملية هي عملية غزيب، ثم استخدم strace -p $pidnum لمعرفة ما يطلق عليه نظام يجري. لاحظ أن ستدين هو FD 0 و المعياري هي FD 1، وربما كنت سوف نرى ذلك القراءة أو الكتابة على تلك اصفات الملف.

وإذا كنت ترغب فقط لضغط ولا تحتاج إلى مغلفة ملف النظر في استخدام وحدة زليب

import zlib
compressed = zlib.compress("text")

ولأي سبب كان السبب في وعاء = حقيقية ويونيكس أنابيب اقتراحات لا تعمل؟

from subprocess import *

pipes = Popen("gzip | uuencode dummy", stdin=PIPE, stdout=PIPE, shell=True)
for i in range(1, 100):
    pipes.stdin.write("some data")
pipes.stdin.close()
print pipes.stdout.read()

ويبدو أن العمل

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top