চলমান প্রোগ্রামে জোর করে আউটপুট বাফার ফ্লাশ করুন


20

আমার একটি দীর্ঘকালীন অজগর স্ক্রিপ্ট রয়েছে যা পর্যায়ক্রমে এমন স্ট্যান্ডার্ড আউটপুটে ডেটা আউটপুট করে যা আমি এরকম কিছু দিয়েছি:

python script.py > output.txt

এই স্ক্রিপ্টটি কিছু সময়ের জন্য চলছে এবং আমি এটি Ctrl+ দিয়ে থামাতে চাই Cতবে এর কোনও আউটপুট হারাতে চাই না। দুর্ভাগ্যক্রমে আমি যখন স্ক্রিপ্টটি বাস্তবায়িত করেছি তখন আউটপুট প্রতিটি লাইন পরে বাফার ফ্লাশ করতে ভুলে গিয়েছিলাম sys.stdout.flush()( আউটপুট ফ্লাশিংয়ের জন্য আগে প্রস্তাবিত সমাধান), সুতরাং Ctrl+ Cএখনই অনুরোধ করা আমার সমস্ত আউটপুট হারাতে বাধ্য করবে।

যদি ভাবছেন যে এটির আউটপুট বাফারটি ফ্লাশ করতে বাধ্য করার জন্য কোনও চলমান অজগর স্ক্রিপ্টের (বা আরও সাধারণভাবে একটি চলমান প্রক্রিয়া) কোনওভাবেই যোগাযোগ করার উপায় আছে কিনা। আমি স্ক্রিপ্টটি কীভাবে সম্পাদনা করব এবং এটি পুনরায় চালাতে হবে তা সঠিকভাবে ফ্লাশ করার জন্য জিজ্ঞাসা করছি না - এই প্রশ্নটি একটি চলমান প্রক্রিয়াটির সাথে ইন্টারঅ্যাক্ট করার বিষয়ে (এবং, আমার ক্ষেত্রে আমার বর্তমান কোড এক্সিকিউশন থেকে আউটপুট হারানো নয়) is

উত্তর:


18

যদি কেউ সত্যই ডেটা চাইছিল, আমি জিডিবি ডিবাগরের সাথে পাইথন ইন্টারপ্রেটার সংযুক্ত করার পরামর্শ দেব , মুহূর্তের মধ্যে টাস্ক বন্ধ করে, কল fsync(1)( স্টাডআউট ) করা, এটি থেকে বিচ্ছিন্ন হওয়া (প্রক্রিয়াটি পুনরায় শুরু করা) এবং আউটপুট ফাইলটি অনুধাবন করা উচিত।

অল্পক্ষণের /proc/$(pidof python)/fdবৈধ ফাইল বর্ণনাকারী দেখতে। $(pidof x)' x' নামক প্রক্রিয়াটির পিআইডি প্রদান করে ।

# your python script is running merrily over there.... with some PID you've determined.
#
# load gdb
gdb
#
# attach to python interpreter (use the number returned by $(pidof python))
attach 1234
#
# force a sync within the program's world (1 = stdout, which is redirected in your example)
call fsync(1)
#
# the call SHOULD have returned 0x0, sync successful.   If you get 0xffffffff (-1), perhaps that wasn't stdout.  0=stdin, 1=stdout, 2=stderr
#
# remove our claws from poor python
detach
#
# we're done!
quit

আমি এই পদ্ধতিটি কাজ করার ডিয়ারগুলি পরিবর্তন করতে, উড়ে যাওয়ার সেটিংগুলি টুইট করার জন্য ব্যবহার করেছি ... অনেক কিছুই। হায়রে, আপনি কেবল চলমান প্রোগ্রামে সংজ্ঞায়িত ফাংশনগুলি কল করতে পারেন, fsyncযদিও দুর্দান্তভাবে কাজ করে।

(gdb কমান্ড ' info functions' সমস্ত উপলব্ধ ক্রিয়াকলাপের তালিকা প্রদর্শন করবে। তবে সাবধানতা অবলম্বন করুন। আপনি একটি প্রক্রিয়াতে লাইভ পরিচালনা করছেন ))

এছাড়াও কমান্ডটি রয়েছে peekfd( psmiscদেবিয়ান জেসি এবং অন্যান্যদের প্যাকেজে পাওয়া যায় ) যা আপনাকে কোনও প্রক্রিয়াটির বাফারগুলিতে কী লুকিয়ে রয়েছে তা দেখার অনুমতি দেয়। আবার, /proc/$(pidof python)/fdআপনাকে পিকফিডে যুক্তি হিসাবে বৈধ ফাইল বর্ণনাকারী দেখিয়ে দেবে।

আপনি মনে করতে না পারেন -uপাইথন, আপনি সর্বদা একটি কম্যান্ড পূর্বে ভী করতে stdbuf(ইন coreutilsইতিমধ্যে ইনস্টল,) সেটে stdin / stdout- এ / দ্বারা stderr unbuffered, লাইন বাফার অথবা অবরোধ পছন্দসই হিসাবে বাফার করুন:

stdbuf -i 0 -o 0 -e 0 python myscript.py > unbuffered.output

অবশ্যই, man pagesআপনার বন্ধু, আরে! সম্ভবত একটি উপনাম এখানে দরকারী হতে পারে।

alias python='python -u'

এখন আপনার অজগরটি সর্বদা আপনার -uসমস্ত কমান্ড লাইন প্রচেষ্টার জন্য ব্যবহার করে !


5

প্রথমে আপনার কাছে পাইথনের (অথবা কমপক্ষে গ্লিবসি) ডিবাগিং প্রতীক রয়েছে তা নিশ্চিত করুন। উপর ফেডোরা 1 আপনি তাদের সঙ্গে ইনস্টল করতে পারেন:

dnf debuginfo-install python

তারপরে চলমান স্ক্রিপ্টের সাথে জিডিবি সংযুক্ত করুন এবং নিম্নলিখিত কমান্ডগুলি চালান:

[user@host ~]$ pidof python2
9219
[user@host ~]$ gdb python2 9219
GNU gdb (GDB) Fedora 7.7.1-13.fc20
...
0x00007fa934278780 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:81
81  T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
(gdb) call fflush(stdout)
$1 = 0
(gdb) call setvbuf(stdout, 0, 2, 0)
$2 = 0
(gdb) quit
A debugging session is active.

    Inferior 1 [process 9219] will be detached.

Quit anyway? (y or n) y
Detaching from program: /usr/bin/python2, process 9219

এটি স্টডআউট ফ্লাশ করবে এবং বাফারিং অক্ষম করবে । 2থেকে setvbufকলের মান _IONBFআমার সিস্টেমে। আপনার নিজের কী আছে তা খুঁজে বের করতে হবে (একটি grep _IONBF /usr/include/stdio.hকৌশলটি করা উচিত)।

আমি যা বাস্তবায়ন দেখা উপর ভিত্তি করে PyFile_SetBufSizeএবং PyFile_WriteStringCPython 2.7, এটা বেশ ভাল কাজ করা উচিত, কিন্তু আমি কোনো নিশ্চয়তা দিতে পারিনা।


1 ফেডোরার মধ্যে একটি বিশেষ ধরণের আরপিএম অন্তর্ভুক্ত থাকে যার নাম ডিবাগিনফো আরপিএমএস । এই স্বয়ংক্রিয়ভাবে তৈরি আরপিএমগুলিতে প্রোগ্রাম ফাইলগুলি থেকে ডিবাগিং তথ্য থাকে তবে একটি বাহ্যিক ফাইলে স্থানান্তরিত হয়।


আমি অজগর ২.7 চেষ্টা করেছিলাম এবং একই ফলাফল দিয়ে শেষ করেছি। আপনার পোস্ট করা ডিবাগিং আপডেটটি একবার দেখে নেব।
ডার্কহার্ট

এটির জন্য মূল্যবান, সিপিথন 3.5 এর আইও / আই ( fileobject.c) এর 2.7 এর চেয়ে আলাদা বাস্তবায়ন করেছে । কাউকে ioমডিউলটি খনন করতে হবে ।
ক্রিশ্চিয়ান সিউপিতু

@DarkHeart তোমার মতোই একটি সহজ প্রোগ্রামের সাথে প্রথম টেস্ট করতে চাইতে পারেন এই এক
ক্রিশ্চিয়ান Ciupitu

4

আপনার তাত্ক্ষণিক সমস্যার কোনও সমাধান নেই। যদি আপনার স্ক্রিপ্টটি ইতিমধ্যে শুরু হয়েছে, আপনি সত্যের পরে বাফারিং মোড পরিবর্তন করতে পারবেন না। এগুলি সবই ইন-মেমোরি বাফার এবং স্ক্রিপ্ট শুরু হওয়ার সাথে সাথে ফাইল হ্যান্ডলগুলি খোলা থাকে, পাইপ তৈরি হয় ইত্যাদি সমস্তই সেট আপ হয় etc.

লং-শট হিসাবে, যদি এবং কেবল যদি প্রশ্নে বাফারিংয়ের কিছু বা সমস্ত আউটপুট আইও পর্যায়ে করা হয়, আপনি একটি syncআদেশ করতে পারেন ; তবে এটি সাধারণত এই ক্ষেত্রে অসম্ভব।

ভবিষ্যতে আপনি পাইথন এর ব্যবহার করতে পারেন -uবিকল্প * স্ক্রিপ্ট চালাতে সমস্যা। সাধারণভাবে, অনেক কমান্ডের স্ট্যান্ডিন / স্টডআউট বাফারিং অক্ষম করার জন্য কমান্ড-নির্দিষ্ট বিকল্প রয়েছে এবং প্যাকেজ unbufferথেকে প্রাপ্ত কমান্ডের সাথে আপনার কিছু সাধারণ সাফল্যও থাকতে পারে expect

বাফারিংটি পাইথন নিজেই না করে এবং + এর সাথে নিজের বাফারগুলি ফ্ল্যাশ করার জন্য যুক্তি প্রয়োগ না করে, যদি প্রোগ্রামটি বাধাগ্রস্ত হয় তখন এ Ctrl+ Cসিস্টেম সিস্টেম স্তরের বাফারগুলি ফ্লাশ করার কারণ ঘটায় । একটি স্থগিতাদেশ, ক্র্যাশ, বা হত্যা এত দয়া করে না।CtrlC

* স্টিডিন, স্টডআউট এবং স্ট্ডারকে পুরোপুরি অবিরাম হতে বাধ্য করুন।


2

পাইথন ২.7. Document ডকুমেন্টেশন, বিভাগ "পাইথন সেটআপ এবং ব্যবহার", উপধারা ১. কমান্ড লাইন এবং পরিবেশ এই পাইথনের যুক্তি বর্ণনা করে:

-u

স্টিডিন, স্টডআউট এবং স্ট্ডারকে পুরোপুরি অবিরাম হতে বাধ্য করুন। যে সিস্টেমে এটি গুরুত্বপূর্ণ সেখানে স্টিন, স্টডআউট এবং স্ট্ডারকে বাইনারি মোডে রাখুন।

নোট করুন যে file.readlines () এবং ফাইল অবজেক্টস (sys.stdin লাইনে জন্য) এর অভ্যন্তরীণ বাফারিং রয়েছে যা এই বিকল্প দ্বারা প্রভাবিত নয়। এটির কাজ করার জন্য, আপনি 1: লুপের মধ্যেই ফাইল ড্রেডলাইন () ব্যবহার করতে চান।

এবং এই পরিবেশ পরিবর্তনশীল:

PYTHONUNBUFFERED

যদি এটি একটি খালি খালি স্ট্রিংয়ে সেট করা থাকে তবে এটি -u বিকল্পটি নির্দিষ্ট করার সমান।


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

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

ঠিক আছে, জেনে রাখা ভাল যে কোনও সমাধান হতে পারে না। আমার প্রশ্নের মতামত হিসাবে, আমি জানি কীভাবে পাইথনে বাফারগুলি ফ্লাশ করতে হয় (আমি ব্যবহার করতাম sys.stdout.flush()তবে আপনার -uবিকল্পটি আরও সহজ মনে হয়) তবে আমার কোডটি চাওয়ার সময় তা করতে ভুলে গিয়েছিলেন। ইতিমধ্যে আমার কোডটি এক সপ্তাহেরও বেশি সময় ধরে চালিয়ে যাওয়ার পরে আমি আশা করছিলাম যে আরও একটি সপ্তাহের জন্য কোডটি পুনরায় চালানোর প্রয়োজন ছাড়াই আমার আউটপুট পাওয়ার কোনও উপায় ছিল।
josliber

একটি প্রাসঙ্গিক পদ্ধতি, যদি আপনি কীভাবে ডেটা দেখতে দেখতে জানেন তবে প্রসেস এক্সপ্লোরার ব্যবহার করে প্রক্রিয়াটির একটি সম্পূর্ণ মেমরি ডাম্প নেওয়া হয় , তারপরে ফাইলের স্ট্রিংগুলি অনুসন্ধান করুন। এটি প্রক্রিয়াটি শেষ করবে না, সুতরাং আপনি এখনও অন্যান্য পদ্ধতি চেষ্টা করতে পারেন।
harrymc

আমি লিনাক্সে আছি - সেই সফ্টওয়্যারটির লিনাক্স সমতুল্য রয়েছে?
জোস্লিবার

2

দেখে মনে হচ্ছে যে আমি সিটিআরএল-সি চালানোর পরে বাফার আউটপুট হারাতে গিয়ে অতিরিক্ত সতর্ক হয়েছি; এই পোস্ট অনুসারে আমার আশা করা উচিত যে আমার প্রোগ্রামটির যদি একটি সাধারণ প্রস্থান থাকে তবে বাফারটি ফ্লাশ হয়ে যাবে, আমি যদি সিটিআরএল-সিতে আঘাত করি তবে এটি হবে। অন্যদিকে, আমি যদি স্ক্রিপ্ট বা অনুরূপ সাথে স্ক্রিপ্টটি হত্যা করি তবে আমি বাফার আউটপুটটি হারাব।


আপনি এটি চেষ্টা করতে হবে। Ctrl-C নিম্ন স্তরের আইও বাফারগুলি ফ্লাশ করে দেবে। যদি পাইথন নিজস্ব বাফারিং করে তবে সিটিটিএল-সি কেবল তখনই ফ্লাশ করবে যদি পাইথন যদি যুক্তি প্রয়োগ করতে যথেষ্ট দয়া করে। আশা করি পাইথন একটি চাকা পুনর্নবীকরণ না করার সিদ্ধান্ত নিয়েছে এবং সিস্টেমের স্বাভাবিক স্তরের বাফারিংয়ের উপর নির্ভর করে। বিষয়টি যদি হয় তবে আমার কোনও ধারণা নেই। তবে সতর্ক হতে হবে।
জেসন সি

ওএস কখনই প্রোগ্রামটির মেমোরি স্পেসে রয়েছে তা খুঁজে বের করতে পারে না। সিস্টেম মেমোরিতে থাকা ডেটাটি যা ফ্লাশ হয় তা হ'ল সিস্টেম কল ব্যবহার করে প্রোগ্রামের দ্বারা ইতিমধ্যে লিখিত ডেটা। ত্রুটি থেকে বেরিয়ে যাওয়ার ক্ষেত্রে, এমনকি এই সিস্টেমের বাফারগুলি বাতিল করা হয়। সংক্ষেপে, পাইথন দ্বারা এখনও লিখিত না ডেটা ফ্লেশ করা যাবে না এবং সব ক্ষেত্রে এটি হারিয়ে যায়।
harrymc

0

আমি মনে করি যে আরও একটি সম্ভাব্য সমাধান হ'ল প্রক্রিয়াটিকে জোর করে চাপানো কোর দিয়ে ফেলে দেওয়া এবং তারপরে মরণোত্তর মেমরির সামগ্রী বিশ্লেষণ করা যেতে পারে।

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