সাবপ্রসেসের স্টপ আউটপুট.পেন কল একটি স্ট্রিংয়ে


300

আমি পাইথনে একটি সিস্টেম কল করার চেষ্টা করছি এবং আউটপুটটি স্ট্রিংয়ের মধ্যে সঞ্চয় করি যা আমি পাইথন প্রোগ্রামে ম্যানিপুলেট করতে পারি।

#!/usr/bin/python
import subprocess
p2 = subprocess.Popen("ntpq -p")

আমি এখানে কিছু পরামর্শ সহ কয়েকটি জিনিস চেষ্টা করেছি:

সাবপ্রসেসক্লুএল আউটপুট পুনরুদ্ধার করা ()

তবে কোনও ভাগ্য ছাড়াই


3
আপনার যে দৌড়ে আসল কোডটি পোস্ট করা এবং এর মতো কংক্রিট প্রশ্নের জন্য প্রকৃত ট্রেসব্যাক বা অপ্রত্যাশিত বাহাওয়ের পোস্ট করা সর্বদা ভাল। উদাহরণস্বরূপ, আউটপুট পেতে আপনি কী চেষ্টা করেছেন তা আমি জানি না এবং আমার সন্দেহ হয় যে আপনি আসলে এটি শুরু করতে পেলেন না for ফাইলটির সন্ধান না করার ক্ষেত্রে আপনি একটি ত্রুটি অর্জন করতে পেরেছিলেন "ntpq -p", যা একটি আলাদা অংশ আপনি যা জিজ্ঞাসা করছেন তার চেয়ে সমস্যা
মাইক গ্রাহাম

উত্তর:


467

পাইথন ২.7 বা পাইথন 3 এ

Popenসরাসরি কোনও বস্তু তৈরির পরিবর্তে , আপনি একটি কমান্ডের আউটপুট স্ট্রিংয়ে সঞ্চয় করতে subprocess.check_output()ফাংশনটি ব্যবহার করতে পারেন :

from subprocess import check_output
out = check_output(["ntpq", "-p"])

পাইথনে ২.৪-২..6

communicateপদ্ধতিটি ব্যবহার করুন ।

import subprocess
p = subprocess.Popen(["ntpq", "-p"], stdout=subprocess.PIPE)
out, err = p.communicate()

out আপনি কি চান

অন্যান্য উত্তর সম্পর্কে গুরুত্বপূর্ণ নোট

কমান্ডটি কীভাবে পাস করেছি তা নোট করুন। "ntpq -p"উদাহরণস্বরূপ অন্য ব্যাপার দেখাবে। যেহেতু Popenশেল ডাকা না করে, আপনি কমান্ড options- একটি তালিকা ব্যবহার করতে হবে ["ntpq", "-p"]


3
এই ক্ষেত্রে, অজগর কি এই সিস্টেম কলটি শেষ হওয়ার জন্য অপেক্ষা করে? অথবা স্পষ্টভাবে ওয়েট / ওয়েলপিড ফাংশনটি কল করা প্রয়োজন?
টাইপ করুন

7
@ ননটাইপ, Popen.communicateপ্রক্রিয়াটি শেষ না হওয়া পর্যন্ত ফিরে আসে না।
মাইক গ্রাহাম

10
আপনি যদি ত্রুটিযুক্ত স্ট্রিম পেতে চান p = subprocess.Popen(["ntpq", "-p"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
স্ট্যাডার

82
সাবধান, subprocess.check_output()কোনও bytesবস্তু ফেরায়, একটি নয় str। আপনি যা করতে চান তা যদি ফলাফলটি মুদ্রণ করা হয় তবে তাতে কোনও তফাত হবে না। তবে আপনি যদি myString.split("\n")ফলাফলের মতো কোনও পদ্ধতি ব্যবহার করতে চান তবে আপনাকে প্রথমে bytesঅবজেক্টটি ডিকোড করতে হবে : subprocess.check_output(myParams).decode("utf-8")উদাহরণস্বরূপ।
টাঙ্গুইপি

17
universal_newlines=Trueপ্যারামিটার হিসাবে যুক্ত করা পাইথন 3 এ স্ট্রিং অবজেক্টটি পেতে আমাকে সহায়তা করেছিল। ইউনিভার্সাল_নউলাইনগুলি যদি সত্য হয় তবে সেগুলি ডিফল্ট এনকোডিং সহ পাঠ্য মোডে খোলা হয়। অন্যথায়, এগুলি বাইনারি স্ট্রিম হিসাবে খোলা হয়।
জনাথন কোমার

38

এটি স্টাডাউটকে পুনর্নির্দেশের জন্য আমার পক্ষে কাজ করেছে (স্ট্ডার একইভাবে পরিচালনা করা যেতে পারে):

from subprocess import Popen, PIPE
pipe = Popen(path, stdout=PIPE)
text = pipe.communicate()[0]

যদি এটি আপনার পক্ষে কাজ করে না, দয়া করে আপনার ঠিক কী সমস্যা হচ্ছে তা নির্দিষ্ট করে দিন।


3
এটি কিছু অদ্ভুত বস্তু তৈরি করে। আমি যখন এটিকে স্ট্রিংয়ে রূপান্তর করি তখন এটি সাদা স্থানের মতো পালিয়ে যায় \n
টোমা জ্যাটো - মনিকা

1
নোট করুন যে এটি সাব-প্রসেসটি সঠিকভাবে চলছিল কিনা তা পরীক্ষা করে না। আপনি সম্ভবত pipe.returncode == 0শেষ লাইনের পরে এটি পরীক্ষা করতে চান ।
ঠাকিস

এই কাজ করার কারণটি হ'ল Popenএকগুচ্ছ ফেরত দেয় stdoutএবং stderrতাই, যখন আপনি অ্যাক্সেস করেন তখন আপনি [0]কেবল দখল করছেন stdout। আপনি এটি করতেও পারেন text, err = pipe.communicate()এবং তারপরে textআপনি যা প্রত্যাশা করেছেন তা পাবেন
জোনা

23

pwdএটি কেবল একটি উদাহরণ হিসাবে ধরে নেওয়া , আপনি এটি এটি করতে পারেন:

import subprocess

p = subprocess.Popen("pwd", stdout=subprocess.PIPE)
result = p.communicate()[0]
print result

দেখুন subprocess ডকুমেন্টেশন জন্য অন্য একটি উদাহরণ এবং আরো তথ্য।


22

subprocess.Popen: http://docs.python.org/2/library/subprocess.html#subprocess.Popen

import subprocess

command = "ntpq -p"  # the shell command
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None, shell=True)

#Launch the shell command:
output = process.communicate()

print output[0]

Popen কন্সট্রাকটর, যদি শেল হল সত্য , আপনি কমান্ড একটি স্ট্রিং হিসাবে বদলে একটা ক্রম হিসাবে পাস করা উচিত। অন্যথায়, কমান্ডকে কেবল একটি তালিকায় বিভক্ত করুন:

command = ["ntpq", "-p"]  # the shell command
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None)

আপনার কাছে মান ত্রুটি, Popen আরম্ভের মধ্যে পড়তে প্রয়োজন হয়, আপনি সেট করতে পারেন দ্বারা stderr করার subprocess.PIPE বা subprocess.STDOUT :

import subprocess

command = "ntpq -p"  # the shell command
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)

#Launch the shell command:
output, error = process.communicate()

ভয়ঙ্কর এটি আমি যা খুঁজছিলাম
কেআরজি আর

14

পাইথন ২.7++ এর জন্য অভিব্যক্তিক উত্তরটি ব্যবহার করা subprocess.check_output()

সাব-প্রসেসটি চালানোর সময় আপনার যুক্তিগুলির পরিচালনাও নোট করা উচিত, কারণ এটি কিছুটা বিভ্রান্ত হতে পারে ....

আরগস যদি নিজস্ব কোনও আরগস সহ কেবলমাত্র একক কমান্ড হয় (বা আপনার কাছে রয়েছে shell=True সেট করেছেন), এটি স্ট্রিং হতে পারে। অন্যথায় এটি অবশ্যই একটি তালিকা হতে হবে।

উদাহরণস্বরূপ ... lsআদেশটি প্রার্থনা করার জন্য , এটি ঠিক আছে:

from subprocess import check_call
check_call('ls')

সুতরাং এটি:

from subprocess import check_call
check_call(['ls',])

তবে, আপনি যদি শেল কমান্ডের কাছে কিছু আরগস দিতে চান তবে আপনি এটি করতে পারবেন না :

from subprocess import check_call
check_call('ls -al')

পরিবর্তে, আপনাকে অবশ্যই এটি তালিকা হিসাবে পাস করতে হবে:

from subprocess import check_call
check_call(['ls', '-al'])

shlex.split()ফাংশন কখনও কখনও মত শেল সিনট্যাক্স একটি subprocesses তৈরি ... এই মত সামনে মধ্যে একটি স্ট্রিং বিভক্ত করতে উপযোগী হতে পারে:

from subprocess import check_call
import shlex
check_call(shlex.split('ls -al'))

পাঁচ বছর পরে, এই প্রশ্নটি এখনও প্রচুর ভালবাসা পাচ্ছে। 2.7+ আপডেটের জন্য ধন্যবাদ, কোরি!
চিহ্নিত করুন

11

এটি আমার পক্ষে নিখুঁতভাবে কাজ করে:

import subprocess
try:
    #prints results and merges stdout and std
    result = subprocess.check_output("echo %USERNAME%", stderr=subprocess.STDOUT, shell=True)
    print result
    #causes error and merges stdout and stderr
    result = subprocess.check_output("copy testfds", stderr=subprocess.STDOUT, shell=True)
except subprocess.CalledProcessError, ex: # error code <> 0 
    print "--------error------"
    print ex.cmd
    print ex.message
    print ex.returncode
    print ex.output # contains stdout and stderr together 

9

এটা আমার জন্য নিখুঁত ছিল। আপনি একটি টিপলে রিটার্ন কোড, স্টাডআউট এবং স্টডার পাবেন।

from subprocess import Popen, PIPE

def console(cmd):
    p = Popen(cmd, shell=True, stdout=PIPE)
    out, err = p.communicate()
    return (p.returncode, out, err)

উদাহরণ স্বরূপ:

result = console('ls -l')
print 'returncode: %s' % result[0]
print 'output: %s' % result[1]
print 'error: %s' % result[2]

6

গৃহীত উত্তরটি এখনও ভাল, আরও নতুন বৈশিষ্ট্যগুলি সম্পর্কে কয়েকটি মন্তব্য। পাইথন ৩.6 থেকে আপনি সরাসরি ইনকোডিং পরিচালনা করতে পারেন check_output, ডকুমেন্টেশন দেখুন । এটি এখন একটি স্ট্রিং অবজেক্ট প্রদান করে:

import subprocess 
out = subprocess.check_output(["ls", "-l"], encoding="utf-8")

পাইথন ৩.7-এ, capture_outputসাবপ্রসেস.আরুন () -র সাথে একটি প্যারামিটার যুক্ত করা হয়েছিল, যা আমাদের জন্য পোপেন / পিআইপিই হ্যান্ডলিং করে, পাইথন ডকসটি দেখুন :

import subprocess 
p2 = subprocess.run(["ls", "-l"], capture_output=True, encoding="utf-8")
p2.stdout

4
 import os   
 list = os.popen('pwd').read()

এই ক্ষেত্রে তালিকায় আপনার কেবল একটি উপাদান থাকবে।


7
os.popensubprocessমডিউলটির পক্ষে অবমূল্যায়ন করা হয় ।
মাইক গ্রাহাম

3
পাইথনের ২.২. এক্স সিরিজটি ব্যবহার করে পুরানো বাক্সে অ্যাডমিনের পক্ষে এটি বেশ সহায়ক ছিল।
নীল ম্যাকএফ

4

আমি এখানে অন্যান্য উত্তরের উপর ভিত্তি করে একটি সামান্য ফাংশন লিখেছি:

def pexec(*args):
    return subprocess.Popen(args, stdout=subprocess.PIPE).communicate()[0].rstrip()

ব্যবহার:

changeset = pexec('hg','id','--id')
branch = pexec('hg','id','--branch')
revnum = pexec('hg','id','--num')
print('%s : %s (%s)' % (revnum, changeset, branch))

4

পাইথন ৩.7 এ একটি নতুন কীওয়ার্ড আর্গুমেন্ট capture_outputচালু হয়েছিল subprocess.run। সংক্ষিপ্ত এবং সহজ সক্ষম:

import subprocess

p = subprocess.run("echo 'hello world!'", capture_output=True, shell=True, encoding="utf8")
assert p.stdout == 'hello world!\n'


0

নিম্নলিখিত একক ভেরিয়েবলের প্রক্রিয়াটির স্টডআউট এবং স্টডারকে ক্যাপচার করে। এটি পাইথন 2 এবং 3 সামঞ্জস্যপূর্ণ:

from subprocess import check_output, CalledProcessError, STDOUT

command = ["ls", "-l"]
try:
    output = check_output(command, stderr=STDOUT).decode()
    success = True 
except CalledProcessError as e:
    output = e.output.decode()
    success = False

যদি আপনার কমান্ডটি অ্যারের পরিবর্তে স্ট্রিং হয় তবে এটির সাথে উপসর্গ করুন:

import shlex
command = shlex.split(command)

0

অজগর 3.5 এর জন্য আমি পূর্ববর্তী উত্তরের ভিত্তিতে ফাংশন রাখি। লগটি মুছে ফেলা হতে পারে, ভেবে ভাল লাগবে

import shlex
from subprocess import check_output, CalledProcessError, STDOUT


def cmdline(command):
    log("cmdline:{}".format(command))
    cmdArr = shlex.split(command)
    try:
        output = check_output(cmdArr,  stderr=STDOUT).decode()
        log("Success:{}".format(output))
    except (CalledProcessError) as e:
        output = e.output.decode()
        log("Fail:{}".format(output))
    except (Exception) as e:
        output = str(e);
        log("Fail:{}".format(e))
    return str(output)


def log(msg):
    msg = str(msg)
    d_date = datetime.datetime.now()
    now = str(d_date.strftime("%Y-%m-%d %H:%M:%S"))
    print(now + " " + msg)
    if ("LOG_FILE" in globals()):
        with open(LOG_FILE, "a") as myfile:
            myfile.write(now + " " + msg + "\n")

0

এর ckeck_outputপদ্ধতি ব্যবহার করুনsubprocess

import subprocess
address = 192.168.x.x
res = subprocess.check_output(['ping', address, '-c', '3'])

অবশেষে স্ট্রিংটি পার্স করুন

for line in res.splitlines():

আশা করি এটি সাহায্য করবে, খুশি কোডিং

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.