Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用paramiko向具有交互元素的打开shell发送命令_Python_Ssh_Paramiko - Fatal编程技术网

Python 使用paramiko向具有交互元素的打开shell发送命令

Python 使用paramiko向具有交互元素的打开shell发送命令,python,ssh,paramiko,Python,Ssh,Paramiko,我正在尝试在Oracle ZFS阵列上执行远程脚本。他们设计CLI的方式是,您可以通过SSH向其发送javascript“脚本”。这个脚本应该在第一行中有“script”一词,它将调用一个子shell,在执行之前在它自己的行上等待一段时间 例如: script run('shares'); var projects = list(); dump(projects); . 如果你这样使用它: $ ssh array < above_script 问题是它永远不会回来,它只是坐在那里。我甚

我正在尝试在Oracle ZFS阵列上执行远程脚本。他们设计CLI的方式是,您可以通过SSH向其发送javascript“脚本”。这个脚本应该在第一行中有“script”一词,它将调用一个子shell,在执行之前在它自己的行上等待一段时间

例如:

script
run('shares');
var projects = list();
dump(projects);
.
如果你这样使用它:

$ ssh array < above_script
问题是它永远不会回来,它只是坐在那里。我甚至不能按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
"script\n                            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.163\r\r\n\r\x1b[1mciczfsa:>\x1b[m\x0f \x1b[m\x0fscript\n\r\r("." to run)> \x1b[m\x0f                            run(\'shares\');\n\r\r("." to run)> \x1b[m\x0f                            var projects = list();\n\r\r("." to run)> \x1b[m\x0f                            dump(projects);\n\r\r("." to run)> \x1b[m\x0f                            .\n\r[\'Project1\', \'Project_PoolA_2\', \'RBR_PROJECT\', \'SAS_501\', \'TestProject\', \'default\', \'reptest\', \'testproj1\', \'testproj2\']\r\n\r\x1b[1mciczfsa:>\x1b[m\x0f \x1b[m\x0f                            '

这里没有太多帮助,因为它显然不是结构化的。理想情况下,我希望将脚本发送到shell,并接收对脚本的结构化响应,我可以将其解析为JSON。

来自原始海报:

解决办法是,我需要在每一条“新行”中发送一条新行(很有趣):


我不知道这是否重要,但以防万一:假设
ssh.exec_命令('script')
返回的
w
的行为类似于标准文件,
w.write
不会在字符串的末尾写换行符。也许可以尝试在用
w.write
编写的字符串中添加一个换行符。沃伦,这正是我需要的。。。有关(愚蠢的)修复,请参见上文。您可以将
line.lstrip().rstrip()
替换为
line.strip()
。另外,您是否尝试过在一次调用中将整个字符串
get_projects
发送到
w.write
,而不是单独编写每一行?
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
"script\n                            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.163\r\r\n\r\x1b[1mciczfsa:>\x1b[m\x0f \x1b[m\x0fscript\n\r\r("." to run)> \x1b[m\x0f                            run(\'shares\');\n\r\r("." to run)> \x1b[m\x0f                            var projects = list();\n\r\r("." to run)> \x1b[m\x0f                            dump(projects);\n\r\r("." to run)> \x1b[m\x0f                            .\n\r[\'Project1\', \'Project_PoolA_2\', \'RBR_PROJECT\', \'SAS_501\', \'TestProject\', \'default\', \'reptest\', \'testproj1\', \'testproj2\']\r\n\r\x1b[1mciczfsa:>\x1b[m\x0f \x1b[m\x0f                            '
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))