কেন পপেন.কমিউনিকেট () 'হাই' এর পরিবর্তে 'hi n' ফিরিয়ে দেয়?


92

কেউ কী ব্যাখ্যা করতে পারে যে আমি কীভাবে ফলাফল চাইছি, "হাই", তার আগে 'বি' অক্ষর দিয়ে একটি নতুন লাইন অনুসরণ করা হয়েছিল?

আমি পাইথন ৩.৩ ব্যবহার করছি

>>> import subprocess
>>> print(subprocess.Popen("echo hi", shell=True,
                           stdout=subprocess.PIPE).communicate()[0])
b'hi\n'

পাইথন ২. with দিয়ে চালালে এই অতিরিক্ত 'বি' প্রদর্শিত হবে না


4
পাইথনের কোন সংস্করণ আপনি ব্যবহার করছেন?
Necrolyte2

4
'বি' সম্পর্কে নিশ্চিত নয়, তবে নিউলাইনটি কারণ echo hiমুদ্রণ hi\r\n। এটি এড়াতে, আপনি শেষে .strip () যোগ করতে পারেন বা অনুরূপ সমাধান fix
আজরেই

7
আপনি এখানে check_output()পরিবর্তে ব্যবহার করতে পারেন .communicate():print(subprocess.check_output("echo hi", shell=True, universal_newlines=True), end="")
jfs

উত্তর:


22

ইকো কমান্ড ডিফল্টরূপে একটি নতুন লাইন অক্ষর দেয়

এর সাথে তুলনা করুন:

print(subprocess.Popen("echo -n hi", \
    shell=True, stdout=subprocess.PIPE).communicate()[0])

স্ট্রিংয়ের পূর্ববর্তী বি হিসাবে এটি নির্দেশ করে যে এটি একটি বাইট ক্রম যা পাইথন ২.6+ এর সাধারণ স্ট্রিংয়ের সমান is

http://docs.python.org/3/references/lexical_analysis.html#literals


4
প্রথম বন্ধনের ভিতরে আপনার '\' লাগবে না।
jfs

94

bইঙ্গিত করে যে কি আছে bytesযা একটি বাইনারি বদলে ইউনিকোড অক্ষর একটি স্ট্রিং বাইটের অনুক্রম হয়। অক্ষর নয়, আউটপুট বাইটগুলিকে সাবস্ক্রোস করে, তাই communicate()এটিই ফিরে আসবে।

bytesটাইপ সরাসরি নয় print()তাই আপনি দেখানো হচ্ছে করছি, সক্ষম reprএর bytesআপনার টি আছে। আপনি যদি সাব-প্রসেস থেকে প্রাপ্ত বাইটগুলির এনকোডিং জানেন তবে আপনি decode()সেগুলি মুদ্রণযোগ্য হিসাবে রূপান্তর করতে ব্যবহার করতে পারেন str:

>>> print(b'hi\n'.decode('ascii'))
hi

অবশ্যই, এই সুনির্দিষ্ট উদাহরণটি কেবলমাত্র তখনই কাজ করে যদি আপনি প্রকৃতপক্ষে উপ-প্রসেস থেকে ASCII পান। এটি ASCII না হলে আপনি একটি ব্যতিক্রম পাবেন:

>>> print(b'\xff'.decode('ascii'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0…

নতুন লাইনটি echo hiআউটপুট রয়েছে তারই একটি অংশ । echoকাজটি হ'ল আপনি যে পরামিতিগুলি পাস করেছেন তা আউটপুট করা, তার পরে একটি নতুন লাইন। আপনি যদি প্রক্রিয়া আউটপুটটির চারপাশে সাদা স্পেসে আগ্রহী না হন তবে আপনি এটির strip()মতো ব্যবহার করতে পারেন :

>>> b'hi\n'.strip()
b'hi'

4
পূর্ববর্তী 'বি' ছাড়াই আপনি কীভাবে বাইট স্ট্রিং মুদ্রণ করতে মুদ্রণ () ফাংশনটি পাবেন? বা আপনাকে প্রথমে একটি ইউনিকোড স্ট্রিংয়ে রূপান্তর করতে হবে?
কল্পনাকারী

আমি কৌতূহলী, যখন os.popenপাঠ্যের স্ট্রিংগুলি ফেরত পাঠায়, সেখানে subprocess.Popenবাইট স্ট্রিংয়ের পরিবর্তে সেগুলি ফেরত দেওয়ার কোনও উপায় আছে কিনা ।
পাভেল Šিমেরদা

11
আমি নিজেই উত্তর দেব, ক্রিপ্টিক নাম সহ একটি বিকল্প রয়েছে universal_newlinesযার ফলে Popenঅবজেক্টটি পাঠ্য স্ট্রিং গ্রহণ করে এবং ফিরে পেতে পারে।
পাভেল Šিমেরদা

4
টুইট উদাহরণস্বরূপ চলমান check_output("dir"), আউটপুট থেকে একটি ফাইলের নাম বের করা এবং তারপরে এটি অ্যাক্সেস করার চেষ্টা করা openযদি ব্যর্থ হয় তবে যদি ফাইলনেমে জার্মান উমলুট থাকে। একটি বাগ হতে পারে।
কেডিবি

57

পূর্বে উল্লিখিত হিসাবে, echo hiআসলে ফিরে আসে hi\n, যা এটি একটি প্রত্যাশিত আচরণ।

তবে আপনি সম্ভবত কেবল "ডান" ফর্ম্যাটে ডেটা পেতে চান এবং এনকোডিংয়ের সাথে ডিল করতে পারেন না। আপনাকে যা করতে হবে তা হ'ল universal_newlines=Trueপছন্দ করার জন্য পাস অপশন subprocess.Popen():

>>> import subprocess
>>> print(subprocess.Popen("echo hi",
                           shell=True,
                           stdout=subprocess.PIPE,
                           universal_newlines=True).communicate()[0])
hi

এই Popen()উপায়টি এই অযাচিত প্রতীকগুলিকে নিজেই প্রতিস্থাপন করবে।


11
universal_newlines=Trueএকটি কবজ মত কাজ। আমার নম্র মতে এটি গ্রহণযোগ্য উত্তর হওয়া উচিত ...
ইথান স্ট্রাইডার

4
এটি অতিরিক্ত খালি লাইন উত্পাদন করে।
LoMaPh

4
আপনার প্রয়োজন হতে পারে উভয় universal_newlines=True মধ্যে Popen(পরিত্রাণ পেতে b'') এবং একটি strip()ফলে স্ট্রিং উপর, যদি আপনি সসীম সম্পর্কে newline কাটতে চাই।
আরিফেল

এফওয়াইআই, ডকুমেন্টেশন বলছে universal_newlinesযে এখন textপ্যারামিটারের জন্য কেবল পিছনের দিকের সামঞ্জস্যপূর্ণ একটি নাম , যা পরিষ্কার তবে কেবল পাইথন ৩.7 এবং তারপরে।
হ্যারি কাটস

এটি অতিরিক্ত খালি লাইন তৈরি করে কারণ এটি কাজ করে না। ইউনিভার্সাল_নিউজলাইনগুলি
ol

8

b হ'ল বাইট উপস্থাপনা এবং \ n হল প্রতিধ্বনির ফলাফল।

নিম্নলিখিতটি কেবল ফলাফলের ডেটা মুদ্রণ করবে

import subprocess
print(subprocess.Popen("echo hi", shell=True,stdout=subprocess.PIPE).communicate()[0].decode('utf-8').strip())
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.