2012-03-26 6 views
5

मेरे पास qsub का उपयोग कर कतार में सबमिट किए गए कुछ पायथन कोड को निष्पादित करने के लिए एक एसजीई स्क्रिप्ट है। पायथन लिपि में, मेरे पास कुछ प्रिंट स्टेटमेंट हैं (प्रोग्राम की प्रगति पर मुझे अपडेट करना)। जब मैं कमांड लाइन से पायथन स्क्रिप्ट चलाता हूं, तो प्रिंट स्टेटमेंट stdout पर भेजे जाते हैं। एसजी स्क्रिप्ट के लिए, मैं आउटपुट को फ़ाइल में रीडायरेक्ट करने के लिए -o विकल्प का उपयोग करता हूं। हालांकि, ऐसा लगता है कि पाइथन स्क्रिप्ट चलने के बाद स्क्रिप्ट केवल फाइल को ही भेज देगी। यह कष्टप्रद है क्योंकि (ए) अब मैं प्रोग्राम पर वास्तविक समय अपडेट नहीं देख सकता हूं और (बी) यदि मेरा काम सही तरीके से समाप्त नहीं होता है (उदाहरण के लिए यदि मेरा काम कतार से बाहर हो जाता है) तो कोई भी अपडेट मुद्रित नहीं होता है। मैं यह सुनिश्चित कैसे कर सकता हूं कि प्रत्येक बार जब मैं कुछ प्रिंट करना चाहता हूं, तो स्क्रिप्ट फ़ाइल को लिख रही है, क्योंकि अंत में इसे एक साथ लंपने के विरोध में?एसजीई स्क्रिप्ट: निष्पादन के दौरान फ़ाइल में प्रिंट करें (केवल अंत में नहीं)?

उत्तर

5

मुझे लगता है कि आप buffered आउटपुट के साथ किसी समस्या में भाग रहे हैं। पायथन अपने आउटपुट को संभालने के लिए लाइब्रेरी का उपयोग करता है, और लाइब्रेरी जानता है कि एक समय में एक ब्लॉक लिखना अधिक कुशल होता है जब वह टीटी से बात नहीं कर रहा है।

इस के आसपास काम करने के कुछ तरीके हैं। आपके पास अपनी स्क्रिप्ट की पहली पंक्ति के रूप में कुछ इस तरह के साथ, "-u" विकल्प (विवरण के लिए अजगर आदमी पृष्ठ देखें) के साथ अजगर चला सकते हैं उदाहरण के लिए,:

#! /usr/bin/python -u 

लेकिन यह अगर काम नहीं करता है आप "/ usr/bin/env" चाल का उपयोग कर रहे हैं क्योंकि आप नहीं जानते कि पाइथन कहाँ स्थापित है।

एक और तरीका है कुछ इस तरह के साथ stdout फिर से खोलना है:

import sys 
import os 

# reopen stdout file descriptor with write mode 
# and 0 as the buffer size (unbuffered) 
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) 

नोट os.fdopen की bufsize पैरामीटर 0 पर सेट किया जा रहा यह unbuffered होने के लिए मजबूर करने के लिए। आप sys.stderr के साथ कुछ ऐसा कर सकते हैं।

+0

धन्यवाद! यह नहीं पता था कि पाइथन के साथ इसका कोई संबंध नहीं था। यह पोस्ट भी उपयोगी पाया http://stackoverflow.com/questions/107705/python-output-buffering – miz

3

मुझे एसजीई के साथ एक ही समस्या का सामना करना पड़ा, और suggested method फ़ाइल को "अनबफर" करने के लिए फ़ाइल IO मेरे लिए काम नहीं कर रहा था। मुझे किसी भी आउटपुट को देखने के लिए प्रोग्राम निष्पादन के अंत तक इंतजार करना पड़ा।

मुझे जो कामकाज मिला वह एक कस्टम ऑब्जेक्ट में sys.stdout को लपेटना था जो "लिखने" विधि को फिर से लागू करता था। वास्तव में stdout को लिखने के बजाय, यह नई विधि उस फ़ाइल को खोलती है जहां आईओ रीडायरेक्ट किया जाता है, वांछित डेटा के साथ जोड़ता है, और फिर फ़ाइल को बंद कर देता है। यह थोड़ा बदसूरत है, लेकिन मैंने पाया कि यह समस्या हल हो गई है, क्योंकि फ़ाइल के वास्तविक उद्घाटन/समापन आईओ को इंटरैक्टिव होने के लिए मजबूर करता है।

import os, sys, time 

class RedirIOStream: 
    def __init__(self, stream, REDIRPATH): 
    self.stream = stream 
    self.path = REDIRPATH 
    def write(self, data): 
    # instead of actually writing, just append to file directly! 
    myfile = open(self.path, 'a') 
    myfile.write(data) 
    myfile.close() 
    def __getattr__(self, attr): 
    return getattr(self.stream, attr) 


if not sys.stdout.isatty(): 
    # Detect redirected stdout and std error file locations! 
    # Warning: this will only work on LINUX machines 
    STDOUTPATH = os.readlink('/proc/%d/fd/1' % os.getpid()) 
    STDERRPATH = os.readlink('/proc/%d/fd/2' % os.getpid()) 
    sys.stdout=RedirIOStream(sys.stdout, STDOUTPATH) 
    sys.stderr=RedirIOStream(sys.stderr, STDERRPATH) 


# Simple program to print msg every 3 seconds 
def main():  
    tstart = time.time() 
    for x in xrange(10): 
    time.sleep(3) 
    MSG = ' %d/%d after %.0f sec' % (x, args.nMsg, time.time()-tstart) 
    print MSG 

if __name__ == '__main__': 
    main() 
3

यह SGE अपनी प्रक्रिया के उत्पादन में बफरिंग है, यह है कि क्या उसके एक अजगर प्रक्रिया या किसी अन्य होता है:

यहाँ एक न्यूनतम उदाहरण है।

सामान्य रूप से आप इसे बदलकर और पुन: संकलित करके एसजीई में बफरिंग को कम या अक्षम कर सकते हैं। लेकिन यह करने के लिए एक बड़ी बात नहीं है, वह डेटा आपके समग्र प्रदर्शन को प्रभावित करने वाली डिस्क पर धीरे-धीरे लिखा जा रहा है।

0

यह मेरे लिए काम करता है:

class ForceIOStream: 
    def __init__(self, stream): 
     self.stream = stream 

    def write(self, data): 
     self.stream.write(data) 
     self.stream.flush() 
     if not self.stream.isatty(): 
      os.fsync(self.stream.fileno()) 

    def __getattr__(self, attr): 
     return getattr(self.stream, attr) 


sys.stdout = ForceIOStream(sys.stdout) 
sys.stderr = ForceIOStream(sys.stderr) 

और इस मुद्दे को NFS स्वामी के पास वापस डेटा समन्वयित नहीं हो रहा है जब तक एक फाइल बंद कर दिया है या fsync कहा जाता है के साथ क्या करना है।

4

जैसा कि अन्य लोगों ने उल्लेख किया है, यह टीटी से कनेक्ट नहीं होने पर हमेशा स्टडआउट लिखने के प्रदर्शन कारणों से बाहर है।

आप एक विशिष्ट बिंदु है जिस पर आप चाहते हैं stdout लिखे जाने की है, तो आप उस बिंदु पर

import sys 
sys.stdout.flush() 

का उपयोग करके कि मजबूर कर सकते हैं।

0

स्टडआउट की बजाय फ़ाइल पर प्रिंट क्यों नहीं करें?

outFileID = open('output.log','w') 
print(outFileID,'INFO: still working!') 
print(outFileID,'WARNING: blah blah!') 

और प्रयोग

tail -f output.log 
0

मैं आज इस एक ही समस्या मारा और बस मुद्रण के बजाय डिस्क को लिख कर इसे हल:

with open('log-file.txt','w') as out: 
    out.write(status_report) 
संबंधित मुद्दे