We have implemented a python shell for our hardware devices that solely consists of the python cmd module on embedded linux. Our (non-root) user’s shell is set to the path of this python shell in /etc/passwd and /etc/shadow. Code example below:
#!/usr/bin/env python import cmd class OurCmdProcessor(cmd.Cmd, object): def __init__(self): cmd.Cmd.__init__(self) ... def cmdloop(self, intro = None): """Command loop. Overrides cmd class cmdloop() method. """ signal.signal(signal.SIGINT, self._sigint_handler) try: cmd.Cmd.cmdloop(self, intro = intro) except: print("{} v2 exception!".format(branding)) #traceback.print_exc(file=sys.stdout) sys.stdout.flush() # This *exits* the cmd shell on exception self.do_EOF() def do_help(self): print("Here is some help text!") etc...
Previously, one of our clients had used SSH.NET to issue command line commands using that library’s RunCommand function, which sets up a standard SSH ‘exec’ request to go over the SSH connection, and then parses the output and return value. (i.e. request channel, channel success, send command, etc..)
Now, that call doesn’t work, presumably because we’ve switched from /bin/sh to this python shell. What does work is using that library’s SSH Shell object to send commands over by putting the command text followed by a newline, then scanning the output.
What I’m asking is, is it possible to implement something in that shell to handle the standard SSH ‘exec’ command this library is issuing, or does part of the shell output that is received upon executing a command AFTER issuing an SSH shell request include the exit value already? We don’t want to include exit values as part of the command printable output.
We are using dropbear SSH server on our embedded linux device.
Advertisement
Answer
To work in this mode, your Python script should be able to parse its command-line arguments in the same way it parses arguments given interactively to your Cmd
instance.
That is:
./yourpython -c "some command"
should work identically to:
./yourpython <<EOF some command EOF
…and should have an exit status that reflects whether the last command to be executed succeeded.
This is equivalent to how ssh hostname 'some command'
runs "${SHELL:-sh}" -c 'some command'
on the remote host.