问题
I am using paramiko for SSH with my remote devices.
and I am make communication with them using paramiko shell (invoke_shell()
method) for interactivity.
The main problem with paramiko shell (as I've read in many answers here) is that there is no guarantee that paramiko SSHClient methods which indicates that the server finished writing such as recv_exit_status()
and exit_status_ready()
will behave as expected.
So I created mechanism that will read the last line of the output from the shell and determine if this line contains only shell's prompt in such case the command execution was finished.
This is works in case there is no changes in prompt.
Now I've read here Wait until task is completed on Remote Machine through Python that 'exec_command()' method return tuple 'stdin, stdout, stderr' and preforming stdout.channel.recv_exit_status()
will block channel until it is done.
My question is if I will create such a tuple and will preform stdout.channel.recv_exit_status()
with stdout
that I will get when I am open on each interactive command (meaning I will do 'shell_chan.send('something')' and then will do stdout.channel.recv_exit_status()
) will it do the job? will it return only when interactive command has finished?
回答1:
SSHClient.recv_exit_status
signals that the channel has closed.
The "shell" channel closes only when the shell closes. A "shell" is a black box with an input and output. Nothing else. There's no way SSH, let only Paramiko, will be able to tell anyhow, when individual commands in the shell has finished. shell_chan.send('something')
is not a signal to SSH to execute a command. It simply sends an arbitrary input to the "shell". Nothing else. It's totally at the shell disposition how the input is interpreted. All that the SSH/Paramiko gets back is an arbitrary unstructured output. Paramiko cannot interpret it anyhow for you.
If you need to be able to tell when a command has finished, you need to use "exec" channel (SSHClient.exec_command method in Paramiko). You should not use the "shell" channel, unless you are implementing an interactive SSH terminal client, like PuTTY (or in rare cases, when you talk to an limited SSH server that does not implement the "exec" channel, as it often the case with dedicated devices, such as routers, switches, etc).
For related questions, see:
- Execute multiple dependent commands individually with Paramiko and find out when each command finishes
- Use the same SSH object to issue "exec_command()" multiple times in Paramiko
- Execute (sub)commands in secondary shell/command on SSH server in Paramiko
- Invoke multiple commands inside a process in interactive ssh mode
- Executing command using Paramiko exec_channel on device is not working
来源:https://stackoverflow.com/questions/57643574/combining-interactive-shell-and-recv-exit-status-method-using-paramiko