পাইথন ২.7 এ সাবপ্রসেসির আউটপুট কীভাবে আড়াল করা যায়


283

আমি উবুন্টুতে ইস্পেক ব্যবহার করছি এবং পাইথন ২.7 স্ক্রিপ্ট রয়েছে যা একটি বার্তা প্রিন্ট করে এবং বলে:

import subprocess
text = 'Hello World.'
print text
subprocess.call(['espeak', text])

ইএসপিয়াক পছন্দসই শব্দ উত্পন্ন করে, তবে কিছু ত্রুটিযুক্ত শেলটি ছড়িয়ে দেয় (ALSA lib ..., কোনও সকেট সংযুক্ত হয় না) তাই আগে যা ছাপা হয়েছিল তা আমি সহজেই পড়তে পারি না। প্রস্থান কোড 0 হয়।

দুর্ভাগ্যক্রমে এর ভার্বোসটি বন্ধ করার জন্য কোনও নথিভুক্ত বিকল্প নেই, সুতরাং আমি কেবলমাত্র এটি চাক্ষুষভাবে নিঃশব্দ করার জন্য এবং খোলা শেলটিকে আরও মিথস্ক্রিয়া করার জন্য একটি উপায় অনুসন্ধান করছি।

কিভাবে আমি এটি করতে পারব?


আপনি কি তখন ওএস.সিস্টেমের সাথে কল করতে পারবেন না? আদর্শ নয় তবে মুদ্রণ করা উচিত নয় আমি ভাবি
জোড়ান বিসলে

@JoranBeasley: os.system () কনসোলে প্রিন্ট হবে যদি না আপনি শেল কমান্ড পুনর্নির্দেশ
jdi

না, ওএস.সিস্টেম ('এস্পিক' + পাঠ্য) এই আচরণটির পুনরুত্পাদন করে।
রাইপেল

@ স্পারকুল্যাট: os.systemসিনট্যাক্সটি দেখানোর জন্য আমি আমার উত্তর আপডেট করেছি । যদিও এটি কেবল উদাহরণের জন্য। সাব
jdi

2
২. Non নির্দিষ্ট সংস্করণ নয়: স্ট্যাকওভারফ্লো / প্রশ্নগুলি / ৫৫৫৫০78০ / / যা নিখুঁত subprocess.DEVNULসমাধানের অনুমতি দেয় ।
সিরো সান্তিলি :26 冠状 病 六四 事件

উত্তর:


426

আউটপুটটি ডিভনুলে পুনর্নির্দেশ করুন:

import os
import subprocess

FNULL = open(os.devnull, 'w')
retcode = subprocess.call(['echo', 'foo'], stdout=FNULL, stderr=subprocess.STDOUT)

এটি কার্যকরভাবে এই শেল কমান্ডটি চালানোর মতো:

retcode = os.system("echo 'foo' &> /dev/null")

50
মাইক্রো ঝরঝরে অকার্যকর: আপনি ব্যবহার করতে পারে os.devnullযদি subprocess.DEVNULLপাওয়া যায় না (<3.3), ব্যবহার check_call()পরিবর্তে call()যদি তোমার জন্য বাইনারি মোডে তার ফিরে কোড, ফাইল খুলুন চেক করবেন না stdin/stdout/stderr, ব্যবহার os.system()নিরুৎসাহিত করা উচিত, &>না কাজের জন্য নয় shউবুন্টু একটি অন স্পষ্টত >/dev/null 2>&1ব্যবহার করা যেতে পারে।
jfs

1
@ জেএসএবেস্টিয়ান: পরামর্শের জন্য ধন্যবাদ। আমি আসলে ব্যবহার করতে চাইছিলাম os.devnullকিন্তু দুর্ঘটনাক্রমে এটি টাইপ করেছিলাম। এছাড়াও, আমি ওপিগুলির ব্যবহারের সাথে লেগে আছি callযেহেতু তারা সম্ভবত সম্ভাব্য ব্যতিক্রম ধরতে পারে না check_call। এবং os.systemপুনঃনির্দেশের জন্য, সাব-প্রসেস পদ্ধতির কার্যকর ব্যবহারটি কী করছে তার এটি কেবলমাত্র একটি চিত্র ছিল। দ্বিতীয় পরামর্শ হিসাবে আসলেই নয়।
jdi

13
আপনার খোলার এফএনএলএল বন্ধ করার দরকার নেই?
Val,

13
শুধু একটি নোট, আপনি ব্যবহার করতে পারেন close_fds=Trueমধ্যে subprocess.callবন্ধ করতে FNULLবর্ণনাকারী পর subprocess বিদ্যমান
ewino

7
@ewino: চালু close_fds=True, ফাইল বর্ণনাকারী বন্ধ করা হয় পরে fork() কিন্তু আগে execvp() অর্থাত, তারা বন্ধ করে দেয়া হয় শিশু প্রক্রিয়া মাত্র সামনে এক্সিকিউটেবল চালানো হয়। close_fds=Trueকোনও স্ট্রিম পুনঃনির্দেশিত হলে উইন্ডোজে কাজ করবে নাপিতামাতার প্রক্রিয়াতে close_fdsফাইলগুলি বন্ধ করে না ।
jfs

89

এখানে আরও বহনযোগ্য সংস্করণ (কেবল মজাদার জন্য, এটি আপনার ক্ষেত্রে প্রয়োজনীয় নয়):

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from subprocess import Popen, PIPE, STDOUT

try:
    from subprocess import DEVNULL # py3k
except ImportError:
    import os
    DEVNULL = open(os.devnull, 'wb')

text = u"René Descartes"
p = Popen(['espeak', '-b', '1'], stdin=PIPE, stdout=DEVNULL, stderr=STDOUT)
p.communicate(text.encode('utf-8'))
assert p.returncode == 0 # use appropriate for your program error handling here

4
নোট করুন যে এটি এমন একটি উত্পাদন করে DEVNULLযা সম্পূর্ণরূপে সাধারণ নয়, যেমন সরবরাহিত হিসাবে subprocess; যেহেতু এটি খুলে দিয়েছে wbতার জন্য ব্যবহার করা যাবে না stdin
রিড

1
@ রিড: আপনার 'r+b'পরিবর্তে মোড দরকার হলে আপনি ব্যবহার করতে পারেন ।
jfs

28

ব্যবহার subprocess.check_output(পাইথন ২. 2. এ নতুন)। কমান্ড ব্যর্থ হলে এটি স্টাডাউটকে দমন করবে এবং ব্যতিক্রম করবে raise (এটি আসলে স্টডআউটের বিষয়বস্তু ফেরত দেয়, তাই আপনি যদি চান তবে আপনার প্রোগ্রামে এটি পরে ব্যবহার করতে পারেন)) উদাহরণ:

import subprocess
try:
    subprocess.check_output(['espeak', text])
except subprocess.CalledProcessError:
    # Do something

আপনি স্টাডার এর সাথে দমন করতে পারেন:

    subprocess.check_output(["espeak", text], stderr=subprocess.STDOUT)

২.7 এরও আগের সময়ের জন্য ব্যবহার করুন

import os
import subprocess
with open(os.devnull, 'w')  as FNULL:
    try:
        subprocess._check_call(['espeak', text], stdout=FNULL)
    except subprocess.CalledProcessError:
        # Do something

এখানে, আপনি স্টাডার দিয়ে দমন করতে পারেন

        subprocess._check_call(['espeak', text], stdout=FNULL, stderr=FNULL)

আরও স্পষ্টতই, এটি স্টডআউটটি ফেরত দেয়। এটি এড়াতে সক্ষম হওয়ার পাশাপাশি এটি ব্যবহার করতে চাইলে দুর্দান্ত।
সিওরো সান্তিলি :01 冠状 病 六四 事件 法轮功

আমি মনে করি এটি আরও সোজা। @ স্টুডেন্টটি আমি মনে করি আপনার কলডপ্রসেসেররর সাথে ত্রুটিগুলি পরিচালনা করা উচিত। except subprocess.CalledProcessError as eএবং তারপরে e.codeবা ব্যবহার করুনe.output
রদ্রিগো ই প্রিন্সিপট

21

পাইথন 3 হিসাবে আপনাকে আর ডিভনুল খোলার দরকার নেই এবং সাব-প্রসেসে কল করতে পারেন DE ডিভিএনইউএল

আপনার কোড যেমন আপডেট করা হবে:

import subprocess
text = 'Hello World.'
print(text)
subprocess.call(['espeak', text], stderr=subprocess.DEVNULL)

কাজ করে! উপরন্তু, অদলবদল করতে পারেন stderrসঙ্গে stdoutদমন আউটপুট (অন্য আর্গুমেন্ট হিসাবে বা সংযোজন) উপরের কোড পারে। "আউটপুট" প্রশ্নের শিরোনামে রয়েছে এবং আমাকে কী এখানে নিয়ে যায় ... সম্ভবত তুচ্ছ, তবে ভেবেছিল এটি উল্লেখ করার মতো ছিল।
ThatsRightJack

-7

পরিবর্তে কমান্ড.গেটআউটপুট () ব্যবহার করবেন না কেন?

import commands

text = "Mario Balotelli" 
output = 'espeak "%s"' % text
print text
a = commands.getoutput(output)

ক) এটি ইনপুটটি বাতিল করে না, এটি অযথা মেমরিতে জমেছে খ) এটিতে textকোটেশন থাকলে তা ভেঙে যায়, বা কোনও ভিন্ন চরিত্রের এনকোডিং ব্যবহার করে, বা কমান্ড লাইনের জন্য খুব বড় গ) এটি কেবল ইউনিক্স (পাইথন 2 এ)
jfs
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.