12

stdout と stderr の出力を結合しようとしています。私の考えでは、これは Channel オブジェクトの set_combine_stderr() で行うことができます。

これは私がやっていることです:

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.)

ただし、結果を保存しようとすると、次のエラーが発生します (上記の最後の行、 chan.makefile() )。

エラー: チャネルが閉じられました。

どんな助けでも大歓迎です

4

3 に答える 3

18

set_combine_stderrストリームに迂回stderrするのは事実ですがstdout、混沌とした順序で迂回するため、ローカル ターミナル ウィンドウでコマンドを実行しているかのように、書かれた順序で結合された行というおそらく必要な結果が得られません。 . 代わりに、を使用してget_ptyください。これにより、サーバーは疑似端末を介して行を実行し、それらを時系列に保ちます。

これは、 と に交互に行をouterr.py書き込むテスト プログラムです。llmps@meerkat2 のホーム ディレクトリにあるとします。stdoutstdin

#!/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)の塊が得られます。stdoutstderr

于 2011-11-08T03:53:13.523 に答える
5

わかりました、これはかなり古いトピックであることは知っていますが、同じ問題に遭遇し、(それほどではないかもしれませんが)かなりの解決策を得ました。標準エラー出力を標準出力にリダイレクトするリモート サーバーでコマンドを呼び出すだけで、常に標準出力から読み取ることができます。例えば:

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()
于 2016-09-23T15:01:27.457 に答える
3

@AaronMcSmooth: (SSH 経由で) 接続しているコンピューターの stdout と stderr を参照しています。

私はこれをやってしまった:

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

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

私のアプリケーションの目的では、stdout と stderr を区別することは問題ではありませんが、2 つを組み合わせるのが最善の方法だとは思いません。

のコード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

チャネルで同じアクションを実行していますが、Channel is closed エラーが表示されます。

于 2010-09-30T00:31:51.023 に答える