我可以在python的日志文件中捕获远程执行的命令及其输出吗?

我可以在python的日志文件中捕获远程执行的命令及其输出吗?,python,Python,我使用paramiko在python中执行远程命令。我想将完整的远程命令行详细信息记录到日志文件中 e、 与在perl中使用Expect一样,我们可以将以下命令及其输出记录到日志文件中 samir@ssahoo-ub-in:~$ cat logfile.txt samir@ssahoo-ub-in:~$ ls Desktop Documents Downloads examples.desktop getskype-linux-beta-ubuntu-64 Music Pic

我使用paramiko在python中执行远程命令。我想将完整的远程命令行详细信息记录到日志文件中

e、 与在perl中使用Expect一样,我们可以将以下命令及其输出记录到日志文件中

samir@ssahoo-ub-in:~$ cat logfile.txt
samir@ssahoo-ub-in:~$ ls
Desktop  Documents  Downloads  examples.desktop  getskype-linux-beta-ubuntu-64  Music      Pictures  Public  Templates  Videos  VirtualBox VMs
samir@ssahoo-ub-in:~$ hostname
ssahoo-ub-in
samir@ssahoo-ub-in:~$ w
 09:11:12 up 10:26,  6 users,  load average: 0.05, 0.05, 0.06
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
samir    tty7     :0               22:45   10:26m 12:51   0.23s gnome-session     --session=classic-gnome
samir    pts/0    :0.0             22:46   10:24m 32.80s 14.34s gnome-terminal
samir    pts/1    :0.0             23:49    1:03m  0.57s  0.57s bash
samir    pts/2    :0.0             07:42    1:22m  0.48s  0.09s vim ../projects    /test/test_cases/common/TestHostname.py
samir    pts/3    :0.0             08:11    0.00s  0.57s  0.01s w
samir    pts/4    :0.0             08:24   46:08   0.21s  0.04s python
samir@ssahoo-ub-in:~$ who
samir    tty7         2011-11-10 22:45 (:0)
samir    pts/0        2011-11-10 22:46 (:0.0)
samir    pts/1        2011-11-10 23:49 (:0.0)
samir    pts/2        2011-11-11 07:42 (:0.0)
samir    pts/3        2011-11-11 08:11 (:0.0)
samir    pts/4        2011-11-11 08:24 (:0.0)
samir@ssahoo-ub-in:~$ 
我通过使用paramiko.invoke_shell()解决了上述问题 e、 g

但是有人能帮我在这里获取stdout、stderr和返回码(退出状态)吗

调用shell后,我尝试使用recv_stderr和recv_exit_状态。但当我试图打印stderr和退出状态时,它没有打印任何内容。以下是我的代码:

import paramiko, time
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
ssh.connect('localhost', username='sam', password='mypassword')
channel = ssh.invoke_shell()
results = ''
results2 = ''
password = 'my_root_password'
try:
    channel.send("su -\n")
    while not channel.recv_ready():
        print "Waiting for root challenge..."
        time.sleep(2)
    results += channel.recv(1024)
    channel.send("%s\n" % password)
    while not channel.recv_ready():
        print "Authenticating..."
        time.sleep(2)
    results += channel.recv(1024)

    channel.send("ls file_doesnt_exist\n") # Here I am sending a wrong command to fail
    if channel.exit_status_ready():
        result3 = channel.recv_exit_status(1024)
    print "exit status is:", results3            # It doesnt return anything
    if channel.recv_stderr_ready():
        result2 = channel.recv_stderr(1024)
    print results2                                # Doesn't print error

except Exception, e:
    print e
我在下面的返回代码中发现了一些不一致之处。可能是我没有用正确的方法。每次我打印返回代码时,它都打印与第一个返回的代码相同的代码。我是否需要重置返回代码。我的意思是,在下面的示例中,两个命令的返回代码都是2。现在,当我交换这两个命令时,我的意思是替换'ls-al;退出时\n“ls-al文件”不存在;退出\n'或反之亦然,它将打印返回代码0。每次打印与第一个返回的返回代码相同的返回代码时

channel = client.invoke_shell()
channel.send('ls -al file_not_exist;exit\n') #Sending to list a file which doesn't exist
time.sleep(3)
print "My 1st command exit status is: ",channel.exit_status_ready()
print "My 1st command return code is: ", channel.recv_exit_status()

channel.send('ls -al;exit\n')
time.sleep(3)
print "My 2nd command exit status is: ",channel.exit_status_ready()
print "My 2nd command return code is: ",channel.recv_exit_status()
我需要打印每个命令的返回码。您能帮我解决这个问题吗?

从文档中看,您可以使用recv_ready并返回shell/频道的结果。例如,这对我很有用:

client = SSHClient()
lient.load_system_host_keys()
client.set_missing_host_key_policy(AllowAllKeys())
client.connect(HOST,username=USERNAME,password=PASSWORD)
channel = client.invoke_shell()
channel.send('ls\n')
while channel.recv_ready():
    channel.recv(1024)

channel.send('exit\n')
if channel.exit_status_ready():
    print channel.recv_exit_status()

下面是如何使用(围绕
paramiko
和更多内容的高级包装器)捕获远程执行命令的输出:

例子
logfile.txt
包含来自
ls
w
who
命令的输出。

谢谢Sebastian。但是我需要用paramiko来做。谢谢亚当。我尝试使用recv_stderr和recv_exit_status,但它没有返回任何内容。在查找存在状态之前,请尝试发送“exit”。此外,如果通信中出现问题,而不是命令中出现错误,则将发送recv_stderr。由于它是一个shell,它将发送一个响应,由您来解释它。(因此,像“foobar”这样的错误命令在系统上是一个错误,但是shell会正确响应该错误的文本,因此不会作为recv_stderr)谢谢Adam。起初,当我在Ubuntu11.04和rhel6上进行验证时,它对我不起作用。但当我睡2秒钟的时候,它就起作用了。也许我们可以设置一个while循环,等待channel.exit\u status\u ready()准备就绪。:)无论如何,再次感谢您。如下所示-虽然'ls file\u doesnu\u exist\n'是一个错误的命令,但它不是shell通信中的错误。您必须使用recv()并解释结果。
client = SSHClient()
lient.load_system_host_keys()
client.set_missing_host_key_policy(AllowAllKeys())
client.connect(HOST,username=USERNAME,password=PASSWORD)
channel = client.invoke_shell()
channel.send('ls\n')
while channel.recv_ready():
    channel.recv(1024)

channel.send('exit\n')
if channel.exit_status_ready():
    print channel.recv_exit_status()
#file: fabfile.py
import functools
import logging
import sys

from fabric.api import run, hide

def do_stuff():
    for cmd in ['ls', 'w', 'who']:
        run(cmd)

# configure logging
logger = logging.getLogger("logged")
logger.setLevel(logging.INFO)
logger.addHandler(logging.FileHandler('logfile.txt'))

def logged(func):
    """Logging decorator."""
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        with hide('output'):
            output = func(*args, **kwargs)
        logger.info(output)
        return output
    return wrapper
run = logged(run)
$ fab do_stuff -H localhost
[localhost] Executing task 'do_stuff'
[localhost] run: ls
[localhost] run: w
[localhost] run: who

Done.
Disconnecting from localhost... done.