2010-09-29 14 views
9

मैं stdout और stderr के आउटपुट को गठबंधन करने की कोशिश कर रहा हूं। मेरा विश्वास यह है कि यह एक चैनल ऑब्जेक्ट के set_combine_stderr() के साथ किया जा सकता है।paramiko stdout और stderr गठबंधन

Error: Channel closed.

: जब मैं परिणाम (पिछले रेखा से ऊपर, chan.makefile()) स्टोर करने के लिए कोशिश मैं निम्नलिखित त्रुटि मिलती है,

SSH = paramiko.SSHClient() 
#I connect and everything OK, then: 
chan = ssh.invoke_shell() 
chan.set_combine_stderr(True) 
chan.exec_command('python2.6 subir.py') 
resultado = chan.makefile('rb', -1.) 

हालांकि:

यह मैं क्या कर रहा हूँ है

किसी भी मदद की बहुत सराहना की जाएगी

उत्तर

2

@AaronMcSmooth: मैं उस कंप्यूटर के stdout और stderr का जिक्र कर रहा हूं जिसे मैं कनेक्ट कर रहा हूं (एसएसएच के माध्यम से)।

मैं यह कर समाप्त हो गया: अपने आवेदन के प्रयोजन के लिए

stdin, stdout, stderr = ssh.exec_command(...) 

output = stdin.read().strip() + stdout.read().strip() 

, यह stdout और stderr के बीच अंतर करना कोई फर्क नहीं पड़ता है, लेकिन मुझे लगता है कि दो गठबंधन करने के लिए सबसे अच्छा तरीका है नहीं लगता है ।

SSHClient.exec_command() का कोड (paramiko के स्रोत कोड देख) है:

def exec_command(self, command, bufsize=-1): 
    chan = self._transport.open_session() 
    chan.exec_command(command) 
    stdin = chan.makefile('wb', bufsize) 
    stdout = chan.makefile('rb', bufsize) 
    stderr = chan.makefile_stderr('rb', bufsize) 
    return stdin, stdout, stderr 

मैं लेकिन चैनल पर एक ही कार्यों का निष्पादन कर रहा हूँ चैनल प्राप्त बंद त्रुटि है।

14

हालांकि यह सच है कि set_combine_stderrstdout धारा को stderr ओर मोड़ देता है, यह अराजक क्रम में ऐसा नहीं करता है, तो आप परिणाम आप शायद चाहते हैं, अर्थात्, लाइनों के क्रम में संयुक्त लिखा, जैसे कि आप चल रहे थे नहीं मिलता स्थानीय टर्मिनल विंडो में कमांड। इसके बजाय, get_pty का उपयोग करें। इससे सर्वर को छद्म-टर्मिनल के माध्यम से लाइनों को चलाने का कारण बनता है, जो उन्हें कालक्रम क्रम में रखता है।

यहां एक परीक्षण कार्यक्रम है, outerr.py, जो stdout और stdin पर वैकल्पिक लाइनें लिखता है। मान लें कि यह llmps @ meerkat2 की होम निर्देशिका में बैठा है।

#!/usr/bin/env python 

import sys 

for x in xrange(1, 101): 
    (sys.stdout, sys.stderr)[x%2].write('This is line #%s, on std%s.\n' % 
       (x, ('out', 'err')[x%2])) 

अब यह दूर से चलाने के लिए निम्नलिखित कोड का प्रयास करें:

#!/usr/bin/env python 

import paramiko 

def connect(): 
    ssh = paramiko.SSHClient() 
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
    ssh.connect('meerkat2', username='llmps', password='..') 
    return ssh 

def runTest(ssh): 
    tran = ssh.get_transport() 
    chan = tran.open_session() 
    # chan.set_combine_stderr(True) 
    chan.get_pty() 
    f = chan.makefile() 
    chan.exec_command('./outerr.py') 
    print f.read(), 

if __name__ == '__main__': 
    ssh = connect() 
    runTest(ssh) 
    ssh.close() 

आप ऊपर चलाते हैं, तो आप क्रम में 100 लाइनों देखना चाहिए के रूप में लिखा। यदि, इसके बजाय, आप chan.get_pty() कॉल पर टिप्पणी करते हैं और chan.set_combine_stderr(True) कॉल को असम्बद्ध करते हैं, तो आपको stdout और stderr लाइनों को यादृच्छिक रूप से रन से चलाने के लिए छेड़छाड़ की जाएगी।

0

ठीक है, मुझे पता है कि यह एक पुराना विषय है, लेकिन मैं एक ही समस्या में भाग गया और मुझे एक (शायद नहीं-तो-) सुंदर समाधान मिला। बस stderr को stdout पर रीडायरेक्ट करने वाले रिमोट सर्वर पर कमांड को कॉल करें और फिर हमेशा stdout से पढ़ें। उदाहरण के लिए:

client = paramiko.SSHClient() 
client.load_system_host_keys() 
client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
client.connect('hostname', username='user', password='pass') 

stdin,stdout,stderr = client.exec_command('python your_script.py 2> \&1') 
print stdout.read() 
संबंधित मुद्दे