我试图在Oracle ZFS数组上执行远程脚本。他们设计CLI的方式是,你可以通过SSH向它发送一个javascript"脚本"。这个脚本应该在第一行有"script"这个词,它将调用一个子shell,在执行
之前在它自己的行上等待一段时间。的例子:
script
run('shares');
var projects = list();
dump(projects);
.
如果你像这样使用
$ ssh array < above_script
输出一个JSON可读格式的项目列表。
我想让这个工作与paramiko ssh在一个python脚本,但到目前为止,我没有太多的运气。在成功连接并获得SSHClient实例后,我正在尝试:
try:
get_projects = """run('shares');
var projects = list();
dump(projects);"""
w, r, e = ssh.exec_command('script')
for line in get_projects.split('n'):
w.write(line)
w.write('.')
pp.pprint(e.readlines())
pp.pprint(r.readlines())
except paramiko.SSHException, e:
logger.exception("Couldn't execute script on array %s: %s" % (array.name, e))
问题是它永远不会返回,它只是呆在那里。我甚至不能按ctrl-c停止它,我必须按ctrl-z结束它。
如果我删除读取stderr和stdout的尝试,它返回但没有捕获任何内容,因此似乎从套接字读取有问题:
INFO:paramiko.transport:Authentication (publickey) successful!
INFO:root:Not none
DEBUG:paramiko.transport:[chan 1] Max packet in: 34816 bytes
DEBUG:paramiko.transport:[chan 1] Max packet out: 32768 bytes
INFO:paramiko.transport:Secsh channel 1 opened.
DEBUG:paramiko.transport:[chan 1] Sesch channel 1 request ok
DEBUG:paramiko.transport:EOF in transport thread
请赐教。
小更新(这看起来很难看):使用ssh.invoke_shell()调用通道允许我发送脚本,然后运行shell.recv(1024)返回下面混乱的输出:
INFO:paramiko.transport:Authentication (publickey) successful!
>>> shell = ssh.invoke_shell()
DEBUG:paramiko.transport:[chan 1] Max packet in: 34816 bytes
DEBUG:paramiko.transport:[chan 1] Max packet out: 32768 bytes
INFO:paramiko.transport:Secsh channel 1 opened.
DEBUG:paramiko.transport:[chan 1] Sesch channel 1 request ok
DEBUG:paramiko.transport:[chan 1] Sesch channel 1 request ok
>>> get_projects = """script
... run('shares');
... var projects = list();
... dump(projects);
... .
... """
>>> get_projects
"scriptn run('shares');n var projects = list();n dump(projects);n .n "
>>> shell.send(get_projects)
203
>>> shell.recv(1024)
'Last login: Fri Mar 1 02:26:58 2013 from 10.91.134.163rrnrx1b[1mciczfsa:>x1b[mx0f x1b[mx0fscriptnrr("." to run)> x1b[mx0f run('shares');nrr("." to run)> x1b[mx0f var projects = list();nrr("." to run)> x1b[mx0f dump(projects);nrr("." to run)> x1b[mx0f .nr['Project1', 'Project_PoolA_2', 'RBR_PROJECT', 'SAS_501', 'TestProject', 'default', 'reptest', 'testproj1', 'testproj2']rnrx1b[1mciczfsa:>x1b[mx0f x1b[mx0f '
没有太多的帮助,因为它显然不是结构化的。理想情况下,我想将脚本发送到shell,并接收结构化响应,以便我可以将其解析为JSON。
原海报:
修复是,我需要发送一个换行与每个"新行"(有趣的是):
try:
get_projects = """run('shares');
var projects = list();
dump(projects);
."""
w, r, e = ssh.exec_command('script')
for line in get_projects.split('n'):
w.write(line.lstrip().rstrip())
w.write('n')
pp.pprint(r.readline())
except paramiko.SSHException, e:
logger.exception("Couldn't execute script on array %s: %s" % (array.name, e))