2009-06-10 17 views
11

में आउटपुट को रीडायरेक्टिंग (F2PY के माध्यम से कहा जाता है) मैं कुछ फ़ोरट्रान कोड से आउटपुट को रीडायरेक्ट करने का तरीका जानने के लिए प्रयास कर रहा हूं जिसके लिए मैंने F2PY का उपयोग कर पाइथन इंटरफ़ेस उत्पन्न किया है। मैं कोशिश की है:पायथन

from fortran_code import fortran_function 
stdout_holder = sys.stdout 
stderr_holder = sys.stderr 
sys.stdout = file("/dev/null","w") 
fortran_function() 
sys.stdout.close() 
sys.stderr.close() 
sys.stdout = stdout_holder 
sys.stderr = stderr_holder 

यह अजगर में उत्पादन पुन: निर्देशित होने वास्तविक तरीका है, लेकिन यह इस मामले (जैसे कि, उत्पादन वैसे भी प्रदर्शित किया जाता है) में काम करने के लिए प्रतीत नहीं होता।

मुझे a mailing list post from 2002 मिला और कहा कि "पीटीएस उपकरणों से संदेशों को पढ़ना संभव है, उदाहरण के लिए ttysnoop यह करता है"। Ttysnoop पर जानकारी ऑनलाइन ढूंढना बहुत मुश्किल लगता है (मुझे नहीं लगता कि इसे कुछ सालों में अपडेट किया गया है; उदाहरण के लिए, the first result on Google for "ttysnoop" में टैरबॉल, आरपीएम और .deb के लिए केवल मृत लिंक हैं), और this request for a port to OS X को प्रतिक्रिया मिली " कोई भाग्य नहीं है, इसके लिए कुछ लिनक्स विशिष्ट utmp फ़ंक्शंस की आवश्यकता है जिन्हें मैं नहीं बना सकता। "

मैं आउटपुट को रीडायरेक्ट करने के तरीके के बारे में किसी भी सुझाव के लिए खुला हूं (इसे ttysnoop का उपयोग नहीं करना है)।

धन्यवाद!

+1

क्या आप वाकई fortran उत्पादन stdout के बजाय stderr करने के लिए नहीं जा रहा है कर रहे हैं? –

+0

हाँ, मैंने अभी भी इसे पुनर्निर्देशित करने का प्रयास किया है, और एक ही परिणाम मिला है। – srunni

उत्तर

17

सी साझा पुस्तकालय द्वारा stdin और stdout fds विरासत में प्राप्त किया जा रहा है।

from fortran_code import fortran_function 
import os 

print "will run fortran function!" 

# open 2 fds 
null_fds = [os.open(os.devnull, os.O_RDWR) for x in xrange(2)] 
# save the current file descriptors to a tuple 
save = os.dup(1), os.dup(2) 
# put /dev/null fds on 1 and 2 
os.dup2(null_fds[0], 1) 
os.dup2(null_fds[1], 2) 

# *** run the function *** 
fortran_function() 

# restore file descriptors so I can print the results 
os.dup2(save[0], 1) 
os.dup2(save[1], 2) 
# close the temporary fds 
os.close(null_fds[0]) 
os.close(null_fds[1]) 

print "done!" 
+0

क्या यह दबाने वाला स्टडर भी होगा? यदि नहीं, तो यह कैसे पूरा किया जा सकता है? – srunni

+0

@aberration: dunno, क्या आपने इसे किसी भी किलेर प्रोग्राम के साथ परीक्षण किया है जो stderr को लिखता है? – nosklo

+0

मैंने इसे आजमाया, और ऐसा लगता है कि यह stderr को लिखा गया टेक्स्ट प्रदर्शित करता है। – srunni

4

यहाँ, एक context manager है कि मैं हाल ही में लिखा था और उपयोगी पाया है क्योंकि मैं distutils.ccompiler.CCompiler.has_function के साथ एक समान समस्या हो रही थी, जबकि pymssql पर काम कर रहा। मैंने फ़ाइल डिस्क्रिप्टर दृष्टिकोण का भी उपयोग किया लेकिन मैंने context manager का उपयोग किया। कारण है कि मैं बनाया इस this blog post पर है के लिए संदर्भ

import contextlib 


@contextlib.contextmanager 
def stdchannel_redirected(stdchannel, dest_filename): 
    """ 
    A context manager to temporarily redirect stdout or stderr 

    e.g.: 


    with stdchannel_redirected(sys.stderr, os.devnull): 
     if compiler.has_function('clock_gettime', libraries=['rt']): 
      libraries.append('rt') 
    """ 

    try: 
     oldstdchannel = os.dup(stdchannel.fileno()) 
     dest_file = open(dest_filename, 'w') 
     os.dup2(dest_file.fileno(), stdchannel.fileno()) 

     yield 
    finally: 
     if oldstdchannel is not None: 
      os.dup2(oldstdchannel, stdchannel.fileno()) 
     if dest_file is not None: 
      dest_file.close() 

: यहाँ है कि मैं क्या के साथ आया है। आपके जैसा ही मुझे लगता है।

मैं एक setup.py में इस तरह इसका इस्तेमाल:

with stdchannel_redirected(sys.stderr, os.devnull): 
    if compiler.has_function('clock_gettime', libraries=['rt']): 
     libraries.append('rt')