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