Some Unix commands fail with command not found, when executed using Python Paramiko exec_command
The SSHClient.exec_command
by default does not run shell in "login" mode and does not allocate a pseudo terminal for the session. As a consequence a different set of startup scripts is (might be) sourced, than in your regular interactive SSH session (particularly for non-interactive sessions, .bash_profile
is not sourced). And/or different branches in the scripts are taken, based on an absence/presence of TERM
environment variable.
Possible solutions (in preference order):
Fix the command not to rely on a specific environment. Use a full path to
sesu
in the command. E.g.:/bin/sesu test
If you do not know the full path, on common *nix systems, you can use
which sesu
command in your interactive SSH session.Fix your startup scripts to set the
PATH
the same for both interactive and non-interactive sessions.Try running the script explicitly via login shell (use
--login
switch with common *nix shells):bash --login -c "sesu test"
If the command itself relies on a specific environment setup and you cannot fix the startup scripts, you can change the environment in the command itself. Syntax for that depends on the remote system and/or the shell. In common *nix systems, this works:
PATH="$PATH;/path/to/sesu" && sesu test
Another (not recommended) approach is to force the pseudo terminal allocation for the "exec" channel using the
get_pty
parameter:stdin,stdout,stderr = ssh.exec_command('sesu test', get_pty=True)
Using the pseudo terminal to automate a command execution can bring you nasty side effects. See for example 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?
You may have a similar problem with LD_LIBRARY_PATH
and locating shared objects.
See also:
- Environment variable differences when using Paramiko
- Certain Unix commands fail with "... not found", when executed through Java using JSch
Command executed with Paramiko does not produce any output
If you get no output on stdout
, it is usually because the command fails to start.
Read stderr
to check for any errors.
print(stderr.readlines())
Quite often the error is "<command> not found". For that see
Some Unix commands fail with "<command> not found", when executed using Python Paramiko exec_command
If you are connecting to a device, see also Executing command using Paramiko exec_command on device is not working.
how can I run python file in remote server using Paramiko?
Source of the issue:
There are different types of shell sessions that get run depending on how you connect to a remote (or local) machine. These different shell types "source" (or execute) different configuration files when they are launched. When you ssh into the remote server from your terminal, you connect to what's called an "interactive login shell"—it's "interactive" because you can interactively run and interrupt commands, and it's a "login shell" because it's the first shell launched after you logged in1.
Interactive Bash login shells source various files that typically (among other things) make additional commands available to you by adding directories containing executables to your $PATH
. You mentioned conda
, for example—when you install conda
, it automatically adds some code to your .bash_profile
to make it available when that file is sourced, which it is for interactive login shells2.
However, when you send a command over ssh the way you're doing with paramiko, that command is by default invoked in a noninteractive (non-login) shell. In this case, your configuration files are not sourced3, which is why the commands you expect to be available are not.
How to fix it:
The easiest way would be to simply change cli.exec_command(<command>)
to cli.exec_command('/bin/bash -lc "<command>"')
. The -l
flag causes bash
to behave as though it were invoked in a login shell, meaning it will source all the same configuration files it does when you ssh in from your terminal.
If you need an interactive shell, you could instead use cli.get_pty()
and cli.invoke_shell()
, but this isn't necessary for just running a Python script.
Finally, I highly recommend taking a look at spurplus
. It's built on top of spur
, which is in turn built on top of paramiko
, and it adds some nice extra features in addition to being much easier to use.
1this is true for Linux systems. On MacOS, subsequent interactive shells you launch are also login shells.
2there are also interactive non-login shells, which instead source your .bashrc
. Again, some of this is slightly different for non-Linux machines, as well as other shells like Zsh.
3unless you've specified a $BASH_ENV
file.
Running database script with Paramiko fails with exit code
If a command does not work, when executed using Paramiko, debug it by reading its error output.
Use stderr.readlines()
for that.
If the same command works in regular shell, but not in Paramiko, the problem is usually related to a different environment used by the SSH "exec" channel, which is used by SSHClient.exec_command
. See:
- Some Unix commands fail with "<command> not found", when executed using Python Paramiko exec_command
- Environment variable differences when using Paramiko
SSHClient.exec_command() reported command not found
Based on your latest comments you should use the absolute path to mmdf
when running the command:
client.exec_command("/the/path/to/mmdf mmfs1 --block-size auto")
To find out where mmdf
is, manually login to the server and run:
which mmdf
# or
type -P mmdf
Related Topics
How to Define a Threshold Value to Detect Only Green Colour Objects in an Image with Python Opencv
"Getaddrinfo Failed", What Does That Mean
How to Search Directories and Find Files That Match Regex
Why Are Scripting Languages (E.G. Perl, Python, and Ruby) Not Suitable as Shell Languages
Python Linux Dmidecode, How to Obtain Hw Info by Parsing
Name This Python/Ruby Language Construct (Using Array Values to Satisfy Function Parameters)
Pickled File Won't Load on MAC/Linux
How to Make a Cross-Module Variable
Extract Text from Xml Documents in Python
Str' Object Does Not Support Item Assignment
Basic Python Hello World Program Syntax Error
How to Create a Reference to a Variable in Python
How to Directly Send a Python Output to Clipboard
Show Default Value for Editing on Python Input Possible
R and Python in One Jupyter Notebook
How to Convert the Background Color of Image to Match the Color of Pygame Window