পাইথনে সাবপ্রসেসের সাহায্যে আউটপুট কীভাবে পুনঃনির্দেশ করা যায়?


97

কমান্ড লাইনে আমি কী করি:

cat file1 file2 file3 > myfile

অজগর নিয়ে আমি কী করতে চাই:

import subprocess, shlex
my_cmd = 'cat file1 file2 file3 > myfile'
args = shlex.split(my_cmd)
subprocess.call(args) # spits the output in the window i call my python program

সাবপ্রসেসে এই জাতীয় কমান্ড কার্যকর করা আপনাকে কোনও আউটপুট দেয় না। আপনি কি এটি > মাইফাইল বিড়াল ফাইল 1 ফাইল 2 ফাইল 3 থেকে আউটপুটটিকে পাইথনে রূপান্তরিত না করে চালাতে চান ?
PoltoS

@ পোল্টোস আমি কয়েকটি ফাইলগুলিতে যোগ দিতে চাই এবং তারপরে ফলাফলটি ফাইলটি প্রক্রিয়া করতে চাই। আমি ভেবেছিলাম বিড়াল ব্যবহার করা সবচেয়ে সহজ বিকল্প। এটি করার কি আরও ভাল / পাইথোনিক উপায় আছে?
ক্যাটাটমিপাইথনকোড

os.sendfile()-ভিত্তিক সমাধান সম্ভব, দেখুন
পাইথনে

4
আমি মনে করি আউটপুট পুনর্নির্দেশ ('>' বা '>>') সাবপ্রসেসে কাজ করে না op পোপেন (কমপক্ষে পাইথন ২.7 এ) (শেল = ট্রু মোডে) উদাহরণস্বরূপ, অন্যরা দেখায়, আপনি প্রায় কাজ করতে পারেন এটি পুনঃনির্দেশ ব্যবহার না করে, তবে অন্যান্য ক্ষেত্রে পুনঃনির্দেশ দরকারী। যদি সাব-প্রসেসে পুনঃনির্দেশ বা পাইপিং সমর্থন না করা হয় তবে পোপেনটি নথিভুক্ত করা উচিত (এবং / অথবা os.sisstm () এটি স্থির না হওয়া অবধি অবনতি করা উচিত নয়)
রিবো

উত্তর:


20

আপডেট: ওস.সিস্টেম নিরুত্সাহিত, যদিও পাইথন 3 এ এখনও উপলব্ধ।


ব্যবহার os.system:

os.system(my_cmd)

আপনি যদি সত্যিই সাব-প্রসেস ব্যবহার করতে চান তবে সমাধানটি এখানে দেওয়া হয়েছে (বেশিরভাগ সাবপ্রসেসের জন্য ডকুমেন্টেশন থেকে তুলে নেওয়া হয়েছে):

p = subprocess.Popen(my_cmd, shell=True)
os.waitpid(p.pid, 0)

OTOH, আপনি সিস্টেম কল সম্পূর্ণরূপে এড়াতে পারবেন:

import shutil

with open('myfile', 'w') as outfile:
    for infile in ('file1', 'file2', 'file3'):
        shutil.copyfileobj(open(infile), outfile)

4
এটি কাজ করে, তবে আমাকে তখন আপনাকে জিজ্ঞাসা করতে দিন: ওএস.সিস্টেম ইতিমধ্যে কাজটি সেরে ফেললে সাবপ্রসেস লাইব্রেরির মূল বক্তব্য কী? আমি এই অনুশাসনটি অনুভব করি যে আমি এই কাজের জন্য উত্সর্গীকৃত একটি গ্রন্থাগার হওয়ার পরিবর্তে সাব-প্রসেস ব্যবহার করা উচিত ছিল, যদিও আমি কেবল নিজের জন্য এটি করছি কারণ এবার আমি ওএস.সিস্টেমটি ব্যবহার করে ভাল থাকব।
ক্যাটাটমিপাইথনকোড

সাবপ্রসেস লাইব্রেরি তুলনায় অনেক বেশি নমনীয় os.systemএবং os.systemসুনির্দিষ্টভাবে মডেল করতে পারে তবে এটি দিয়ে কাজ করা আরও জটিল।
মার্সেলো ক্যান্টোস

13
os.systemআগে এসেছিল subprocess। পূর্ববর্তীটি হ'ল একটি উত্তরাধিকার সূত্র যা পরবর্তীকৃত প্রতিস্থাপন করতে চায় to
সান্তা

4
@ ক্যাটাটেমিপাইথনকোড: আপনার ব্যবহার os.system()বা করা উচিত নয় shell=True। একটি সাবপ্রসেসের আউটপুট পুনর্নির্দেশ করতে, রায়ান থম্পসনের উত্তরেstdout প্রদর্শিত প্যারামিটার ব্যবহার করুন । যদিও আপনার ক্ষেত্রে সাব-প্রসেসের প্রয়োজন নেই , আপনি খাঁটি পাইথন ব্যবহার করে ফাইলগুলি সংযুক্ত করতে পারেন। cat
jfs

4
OTOH = অন্যদিকে
সেফ্লিন

279

ইন পাইথন 3.5+ আউটপুট পুনর্নির্দেশ করতে, শুধু জন্য একটি খোলা ফাইল হ্যান্ডেল পাস stdoutআর্গুমেন্ট প্রাপ্ত করতে subprocess.run:

# Use a list of args instead of a string
input_files = ['file1', 'file2', 'file3']
my_cmd = ['cat'] + input_files
with open('myfile', "w") as outfile:
    subprocess.run(my_cmd, stdout=outfile)

অন্যরা যেমন উল্লেখ করেছে, catএই উদ্দেশ্যে যেমন একটি বাহ্যিক কমান্ডের ব্যবহার সম্পূর্ণ বহিরাগত।


9
পাইথন থেকে শেলটি ব্যবহার করার সময় পাইপিংয়ের সাধারণ প্রশ্নের উত্তর হওয়া উচিত
কৌশিক ঘোষ

47
এটি সঠিক উত্তর, সঠিক হিসাবে চিহ্নিত চিহ্ন নয়।
জাস্টিন ব্লেক

7
পাইথন 3.5+ ব্যবহারের জন্য subprocess.run(my_cmd, stdout=outfile)যা প্রতিস্থাপন করছেsubprocess.call(...)
অস্টিন ইয়েটস

4
দ্রষ্টব্য, এটি কাস্টম ফাইল অবজেক্টগুলির সাথে কাজ করে না, যদি তাদের কাছে ফাইলনো ক্ষেত্র না থাকে (যদি তারা প্রকৃত ফাইল না হয়))
এলিয়েজার মিরন

4
পাইথন <3.5 এখন অবধি হ্রাস করা হয়েছে, আমি আপনার মন্তব্য, উত্তর অস্টাইনইটসের সাথে উত্তরটি আপডেট করেছি।
গ্রেগ ডাবিকি

5

@ পোল্টোস আমি কয়েকটি ফাইলগুলিতে যোগ দিতে চাই এবং তারপরে ফলাফলটি ফাইলটি প্রক্রিয়া করতে চাই। আমি ভেবেছিলাম বিড়াল ব্যবহার করা সবচেয়ে সহজ বিকল্প। এটি করার কি আরও ভাল / পাইথোনিক উপায় আছে?

অবশ্যই:

with open('myfile', 'w') as outfile:
    for infilename in ['file1', 'file2', 'file3']:
        with open(infilename) as infile:
            outfile.write(infile.read())

1
size = 'ffprobe -v error -show_entries format=size -of default=noprint_wrappers=1:nokey=1 dump.mp4 > file'
proc = subprocess.Popen(shlex.split(size), shell=True)
time.sleep(1)
proc.terminate() #proc.kill() modify it by a suggestion
size = ""
with open('file', 'r') as infile:
    for line in infile.readlines():
        size += line.strip()

print(size)
os.remove('file')

আপনি যখন সাবপ্রসেস ব্যবহার করেন , প্রক্রিয়াটি অবশ্যই মারা যেতে হবে his এটি একটি উদাহরণ you আপনি যদি প্রক্রিয়াটি না খোলেন তবে ফাইলটি খালি থাকবে এবং আপনি কিছুই পড়তে পারবেন না Windows এটি উইন্ডোতে চলতে পারে I আমি এটি নিশ্চিত করতে পারি না যে এটি করতে পারে ইউনিক্সে চালান।


4
এটি একটি খারাপ কোড উদাহরণ (এটি ইউনিক্সে কাজ করবে না; এটি খারাপ অভ্যাসগুলি দেখায় for line in .readlines():, s +=) এবং proc.kill()সাধারণভাবে তথ্য ক্ষতির কারণ হতে পারে (এটি সাবপ্রসেসটি সুদৃfully়ভাবে শেষ করতে দেয় না (ইউনিক্সে)) - নিখরচায় সামগ্রী হারিয়ে যায় )। যাইহোক, বাফারিং সম্পর্কে নোটটি মন্তব্য হিসাবে বেশি উপযুক্ত।
jfs

আমি এটি উইন্ডোতে চালিত করি ঠিক আছে (কারণ উইন্ডোতে খুন সমাপ্তির সমান)। ইউনিক্সে আপনার পক্ষে প্র্যাকটার্মিনেট () ব্যবহার করা উচিত। @ জেএফ সেবাস্তিয়ান আমার কম্পিউটারে ইউনিক্স সিস্টেমটি নেই।
wyx

আপনি Windows হয় তাহলে ড্রপ shlex.split(), ড্রপ shell=True, ড্রপ >file, ড্রপ open(), ইত্যাদি এবং ব্যবহার stdout=PIPE, Timer(1, proc.terminate).start(); output = proc.communicate()[0]পরিবর্তে. এখানে সম্পূর্ণ উদাহরণ । আরও সমাধান: হ্যাং না করে পাইথনে প্রসেস আউটপুট পড়া বন্ধ করবেন? দ্রষ্টব্য: আপনার শিশু প্রক্রিয়াটি ম্যানুয়ালি শেষ করতে হবে এমন প্রশ্নের কোনও প্রয়োজন নেই - আপনি অন্যান্য সমস্যাগুলি সমাধান করতে পারেন যেমন, কোনও প্রক্রিয়া যদি তার স্টাডআউটটি টিটিটি হয় তবে এটি ভিন্ন বিষয় হতে পারে।
jfs

0

একটি আকর্ষণীয় কেস হ'ল অনুরূপ ফাইল যুক্ত করে কোনও ফাইল আপডেট করা। তারপরে একটির প্রক্রিয়াটিতে একটি নতুন ফাইল তৈরি করতে হবে না। এটি বিশেষত কার্যকর যেখানে ক্ষেত্রে একটি বড় ফাইল সংযোজন করা প্রয়োজন। পাইথন থেকে সরাসরি টেমিনাল কমান্ড লাইন ব্যবহার করার সম্ভাবনা এখানে।

import subprocess32 as sub

with open("A.csv","a") as f:
    f.flush()
    sub.Popen(["cat","temp.csv"],stdout=f)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.