我正在使用paramiko在python中执行远程命令。我想将完整的远程命令行详细信息记录到日志文件中。
e.g。就像在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。
client = paramiko.SSHClient()
client.load_system_host_keys()
client.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
client.set_missing_host_key_policy(AllowAllKeys())
client.connect(HOST, username=USER, password=PASSWORD)
channel = client.invoke_shell()
channel.send("ls -l\n")
while not channel.recv_ready():
time.sleep(2)
results += channel.recv(1024)
但有人可以帮助我获取stdout,stderr并返回代码(退出状态)吗?
我在调用shell后尝试使用recv_stderr和recv_exit_status。但是当我尝试打印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; exit \ n'替换为'ls -al file_not_exist;退出\ 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()
我需要打印每个命令的返回码。你能帮我解决一下如何解决这个问题吗?
答案 0 :(得分:3)
从paramiko.SSHClient文档看起来,您可以使用recv_ready和recv返回shell / channel的结果。例如,这对我有用:
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()
答案 1 :(得分:0)
以下是如何使用fabric
(paramiko
以及更高级别的高级包装器)捕获远程执行命令的输出:
#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.
logfile.txt
包含ls
,w
,who
命令的输出。