Is there a simple way to get rid of junk values that come when you SSH using Python's Paramiko library and fetch output from CLI of a remote machine?
It's not a junk. These are ANSI escape codes that are normally interpreted by a terminal client to pretty print the output.
If the server is correctly configured, you get these only, when you use an interactive terminal, in other words, if you requested a pseudo terminal for the session (what you should not, if you are automating the session).
The Paramiko automatically requests the pseudo terminal, if you used the SSHClient.invoke_shell
, as that is supposed to be used for implementing an interactive terminal. See also How do I start a shell without terminal emulation in Python Paramiko?
If you automate an execution of remote commands, you better use the SSHClient.exec_command
, which does not allocate the pseudo terminal by default (unless you override by the get_pty=True
argument).
stdin, stdout, stderr = client.exec_command('ls')
Or as a workaround, see How can I remove the ANSI escape sequences from a string in python.
Though that's rather a hack and might not be sufficient. You might have other problems with the interactive terminal, not only the escape sequences.
You particularly are probably not interested in the "Last login" message and command-prompt (cli@BENU>
) either. You do not get these with the exec_command
.
If you need to use the "shell" channel due to some specific requirements or limitations of the server, note that it is technically possible to use the "shell" channel without the pseudo terminal. But Paramiko SSHClient.invoke_shell
does not allow that. Instead, you can create the "shell" channel manually. See Can I call Channel.invoke_shell() without calling Channel.get_pty() beforehand, when NOT using Channel.exec_command().
And finally the u
is not a part of the actual string value (note that it's outside the quotes). It's an indication that the string value is in the Unicode encoding. You want that!
How do I start a shell without terminal emulation in Python Paramiko?
Paramiko SSHClient.invoke_shell
opens "shell" SSH channel. What is basically only a shorthand for executing user's default shell. Otherwise it does not differ to what SSH "exec" channel (used by SSHClient.exec_command
) does.
Both "shell" and "exec" SSH channels can be started with or without the terminal emulation. It's only that Paramiko SSHClient.invoke_shell
method does not offer that option (while SSHClient.exec_command
does – via its get_pty
parameter).
There are two alternatives:
Use
SSHClient.exec_channel
to start the shell explicitly, likessh.exec_command("/bin/bash")
On Linux servers, you may even be able to avoid hard-coding the shell path by using the
SHELL
environment variable:ssh.exec_command("$SHELL")
Similar might be done on Windows using
%CMDSPEC%
(untested).Or re-implement
SSHClient.invoke_shell
to support execution without the terminal emulation.If you look at
SSHClient.invoke_shell
implementation, it does:chan = self._transport.open_session()
chan.get_pty(term, width, height, width_pixels, height_pixels)
chan.invoke_shell()All you need, is to do the same, just remove the
Channel.get_pty
call:chan = ssh.get_transport().open_session()
chan.invoke_shell()
Though note that there's a reason, why SSHClient.invoke_shell
always uses the terminal emulation. The only purpose of SSH "shell" channel is implementing an interactive SSH terminal client (like PuTTY). A terminal client without the terminal emulation makes no sense.
That you want to use "shell" channel without the terminal emulation indicates, that you are abusing it for purposes for which it was not designed. Think twice, if there's not a better solution to what you are trying to do!
Only pwd command succeeds in Paramiko, others fail with ksh: ...: cannot execute - No such file or directory
pwd
is probably built in to your shell, whereas all the other commands you're running are not. ls
is not found because $PATH
is not set, so you can either set the PATH
environment variable, or use a full path when invoking commands, such as /bin/ls
.
Related Topics
Quoting Backslashes in Python String Literals
Typeerror: Can't Convert 'Int' Object to Str Implicitly
Convert Excel Style Date with Pandas
Multiprocessing.Pool: When to Use Apply, Apply_Async or Map
Convert Integer to String in Python
Difference Between _Getattr_ and _Getattribute_
How to Add an Extra Column to a Numpy Array
How to Add Property to a Class Dynamically
How to Remove \Xa0 from String in Python
Catch a Thread's Exception in the Caller Thread
How to Use a Python Script in the Command Line Without Cd-Ing to Its Directory? Is It the Pythonpath
How to Efficiently Parse Fixed Width Files
Why Do I Get a Syntaxerror for a Unicode Escape in My File Path
Getting "Permission Denied" When Running Pip as Root on My MAC