1

I'm trying to execute a remote script on an Oracle ZFS array. The way they've designed the CLI is that you can send it a javascript "script" via SSH. This script is supposed to have the word "script" in the first line which will invoke a sub-shell which waits for a period on it's own line before executing

Example:

script
run('shares');
var projects = list();
dump(projects);
.

which if you use it like this:

$ ssh array < above_script

outputs a nice list of the projects in a JSON readable format.

I'd like to get this to work with paramiko ssh in a python script but so far I'm not having much luck. After successfully connecting and getting an SSHClient instance I'm trying this:

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

The problem is that it never returns, it just sits there. I can't even ctrl-c stop it, I have to ctrl-z and kill it.

If I remove the attempts to read stderr, and stdout it returns but nothing is captured, so it seems like there's an issue reading from the socket:

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

Any insights would be appreciated.


small update (this is going to look ugly): Invoking the Channel with ssh.invoke_shell() allowed me to send the script and then running shell.recv(1024) returned the messy output below:

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                            '

Not a TON of help here because it's obviously not structured. Ideally I'd like to send the script to the shell, and receive the structured response to I can parse it as JSON.

4

1 に答える 1