সঙ্গে সঙ্গে ফাইল করার জন্য পাইথন স্টাডাউট লিখুন


51

পাইথন স্ক্রিপ্ট থেকে একটি পাঠ্য ফাইল ( python script.py > log) -তে stdout লেখার চেষ্টা করার সময়, কমান্ড শুরু হওয়ার সাথে সাথে পাঠ্য ফাইলটি তৈরি করা হয়, তবে পাইথন স্ক্রিপ্ট শেষ না হওয়া পর্যন্ত আসল সামগ্রী লিখিত হয় না। উদাহরণ স্বরূপ:

script.py:

import time
for i in range(10):
    print('bla')
    time.sleep(5)

python script.pyযখন কল করা হবে তখন প্রতি 5 সেকেন্ডে প্রসারিত প্রিন্ট করা হয় , তবে আমি যখন কল করি তখন python script.py > logস্ক্রিপ্ট শেষ না হওয়া অবধি লগ ফাইলের আকার শূন্য থাকে। আপনি সরাসরি স্ক্রিপ্টের অগ্রগতি অনুসরণ করতে পারেন (যেমন ব্যবহার করে tail) লগ ফাইলটিতে সরাসরি লেখা সম্ভব ?

সম্পাদনা করুন এটি সক্রিয় যে python -u script.pyকৌশলটি করে, আমি স্টাডআউট বাফারিং সম্পর্কে জানতাম না।


1
@ জেজম্যাক, আমি প্রশ্নটি ভুল বুঝতে পারতাম।
zyxue

উত্তর:


64

এটি ঘটছে কারণ সাধারণত যখন প্রক্রিয়া STDOUT টার্মিনাল ব্যতীত অন্য কোনও দিকে পুনঃনির্দেশিত করা হয়, তখন আউটপুটটি কয়েকটি ওএস-নির্দিষ্ট-আকারের বাফারে (সম্ভবত 4 কে বা 8 কে অনেক ক্ষেত্রে) বাফার হয়। বিপরীতে, টার্মিনালে আউটপুট দেওয়ার সময়, STDOUT লাইন-বাফার হবে বা মোটেও বাফার হবে না, সুতরাং আপনি প্রতিটি \nবা প্রতিটি চরিত্রের পরে আউটপুট দেখতে পাবেন ।

আপনি সাধারণত stdbufইউটিলিটি সহ STDOUT বাফারিং পরিবর্তন করতে পারেন :

stdbuf -oL python script.py > log

এখন আপনি যদি tail -F logপ্রতিটি লাইন আউটপুট উত্পন্ন করার সাথে সাথেই দেখতে পান।


প্রতিটি মুদ্রণের পরে আউটপুট স্ট্রিমের বিকল্পভাবে স্পষ্ট ফ্লাশিং একই অর্জন করা উচিত। sys.stdout.flush()পাইথনে এটি অর্জন করা উচিত বলে মনে হচ্ছে । আপনি পাইথন 3.3 অথবা ঊর্ধ্বতন সংস্করণ ব্যবহার করেন, তাহলে printফাংশনটি একটি হয়েছে flushশব্দ যে এই আছে: print('hello', flush=True)


8
ধন্যবাদ, আমি বাফারিং সম্পর্কে জানতাম না! তা জেনে গুগল খুব তাড়াতাড়ি আমাকে বলেছিল যে python -u script.pyকৌশলটি করে। এতগুলি উত্তর একবারে সম্পাদনা করুন, আমি আপনাকে গ্রহণ করেছি যেহেতু এটি আমাকে বাফারিংয়ের দিকে নির্দেশ করেছে।
বার্ট

1
@ জুলব্রা কুল, হ্যাঁ আমি জানতাম না পাইথনেরও সেই বিকল্প ছিল। কিছু কম্যান্ড-লাইন প্রোগ্রাম এছাড়াও অনুরূপ বিকল্প ব্যবহার করতে পারেন - যেমন --line-bufferedজন্য grep, কিন্তু কিছু অন্যদের না। stdbufযা না হয় তাদের মোকাবেলা করার জন্য সাধারণ ক্যাচল ইউটিলিটি।
ডিজিটাল ট্রমা

@ ডিজিটালট্রামা: stdbuf -o0 python script.py > logএই ধরণের দৃ determined় পরিস্থিতিতে যেমন কোন বাফারিং ব্যবহার করা ভাল না ?
হিমাইল 22

@ হেইমাইল -oLএকটি আপস। সাধারণভাবে বৃহত্তর বাফারগুলি কোথাও পুনঃনির্দেশ করার সময় আরও ভাল পারফরম্যান্স সরবরাহ করবে (কম সিস্টেম কল এবং কম I / O ক্রিয়াকলাপ)। তবে যদি প্রতিটি চরিত্রকে আউটপুট হিসাবে দেখা একেবারেই প্রয়োজন হয় তবে হ্যাঁ, -o0প্রয়োজন হবে।
ডিজিটাল ট্রমা

@ পল দয়া করে উত্তরের মধ্যে অনুলিপি কাস্ট করা বিষয়গুলি এড়ান, বা বেরি কমপক্ষে মূল লেখকগুলির উল্লেখ করুন যা সামগ্রী সরবরাহ করেছে।
বাকুরিউ

44

এটি কাজ করা উচিত:

import time, sys
for i in range(10):
    print('bla')
    sys.stdout.flush()
    time.sleep(5)

পাইথন যেভাবে stdoutডিফল্টরূপে বাফার করবে , আমি এখানে sys.stdout.flush()বাফারটি ফ্লাশ করার জন্য ব্যবহার করেছি ।

আর একটি সমাধান -uহ'ল (অসমাপ্ত) স্যুইচটি ব্যবহার করা python। সুতরাং, নিম্নলিখিতগুলিও এটি করবে:

python -u script.py >> log

11

আনফারড আউটপুটটির জন্য পাইথনের নিজস্ব বিকল্পটি ব্যবহারের থিমের মধ্যে পার্থক্য হ'ল #!/usr/bin/python -uপ্রথম লাইন হিসাবে।

এই #!/usr/bin/env pythonঅতিরিক্ত যুক্তি দিয়ে কাজ হবে না, সুতরাং বিকল্পভাবে, কেউ PYTHONUNBUFFERED=1 ./my_scriipt.py > output.txtদুটি পদক্ষেপে এটি চালাতে বা করতে পারে :

$ export PYTHONUNBUFFERED=1
$ ./myscript.py

10

আপনার flush=Trueএই printফাংশনে পাস করা উচিত :

import time

for i in range(10):
    print('bla', flush=True)
    time.sleep(5)

ডকুমেন্টেশন অনুসারে, ডিফল্টরূপে, printফ্লাশিং সম্পর্কে কোনও কিছুই প্রয়োগ করে না:

আউটপুট বাফার করা হয় কিনা তা সাধারণত ফাইল দ্বারা নির্ধারিত হয় তবে flushকীওয়ার্ড যুক্তিটি সত্য হলে, স্ট্রিমটি জোর করে চাপানো হয়।

এবং sysএর স্ট্রিমগুলির জন্য ডকুমেন্টেশন বলছে:

ইন্টারেক্টিভ যখন, স্ট্যান্ডার্ড স্ট্রিমগুলি লাইন-বাফার হয়। অন্যথায়, তারা নিয়মিত পাঠ্য ফাইলের মতো ব্লক-বাফার হয়। -uকমান্ড-লাইন বিকল্পের সাহায্যে আপনি এই মানটি ওভাররাইড করতে পারেন ।


আপনি যদি পাইথনের প্রাচীন সংস্করণটির সাথে আটকে থাকেন তবে আপনাকে স্ট্রিমের flushপদ্ধতিটি কল করতে হবে sys.stdout:

import sys
import time

for i in range(10):
    print('bla')
    sys.stdout.flush()
    time.sleep(5)

1
ফ্লাশ = সত্য যুক্তিটি পাইথন ৩.৪.২ নিয়ে দুর্দান্তভাবে কাজ করে, প্রকৃতপক্ষে পাইথন ২.7.৯-এর সাথে কাজ করে না
বার্ট

এই উত্তরটি একই জিনিসটি প্রস্তাব করে যা DigitalTrauma10 ঘন্টা আগে বলেছিল। আপনার তাঁর পোস্টটি উর্ধ্বতন করা উচিত, আবার একই জিনিস পোস্ট করা উচিত নয়।
dotancohen

4
@ ডটানকোহেন আসলে তৃতীয় পক্ষের একজন লেখক আমার পরেprint(flush=True) উত্তরটির অংশটি যুক্ত করেছিলেন । আমার উত্তর থেকে বিষয়বস্তুগুলি বিনা withoutণে অন্যকে দেওয়ার জন্য এটি ছিঁড়ে ফেলা আমার খারাপ স্বাদ বলে মনে হয়। আমি আমার উত্তরটি কেবল যুক্ত করার সিদ্ধান্ত নিয়েছি কারণ কোনও উত্তর পাইপথনের নতুন সংস্করণগুলিতে ওপি কী চেয়েছিল তা অর্জনের সহজতম পদ্ধতির কোনও উল্লেখ দেয়নি, এবং আমি সম্পূর্ণতার জন্য "পুরাতন উপায়" যুক্ত করেছি। পরের বার দয়া করে মন্তব্য করার আগে বা ডাউনভোট করার আগে সংশোধন ইতিহাস পরীক্ষা করে দেখুন।
বাকুরিউ 13

@ বাকুরিউ: আমি তখন দুঃখিত! ডাউনটাটিংয়ের সময় কেন সর্বদা পোস্ট করার জন্য এটি ভাল কারণ দেখায় । আপনি কি দয়া করে পোস্টটি কিছুটা সম্পাদনা করতে পারেন যাতে আমি আমার ডাউনটাতে একটি উঁচুতে পরিবর্তন করতে পারি? ধন্যবাদ!
dotancohen

এটা তোলে পাইথন 2.7 সঙ্গে কাজ করা উচিত যদি আপনি না __future__আমদানি: from __future__ import print_function। তবে হ্যাঁ, এটি কেবল পাইথন 3 এর সাথে সামঞ্জস্যের জন্য
সের্গেই কলডিয়াজহনি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.