Environment variable differences when using Paramiko

10,737

Solution 1

Working with the Channel object instead of the SSHClient object solved my problem.

chan=ssh.invoke_shell()
chan.send('echo $PATH\n')
print (chan.recv(1024))

For more details, see the documentation

Solution 2

The SSHClient.exec_command by default does not allocate a pseudo terminal for the session. As a consequence a different set of startup scripts is (might be) sourced (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.


To emulate the default Paramiko behavior with the ssh, use the -T switch:

ssh -T myuser@host

See the ssh man:

-T Disable pseudo-tty allocation.


Contrary, to emulate the default ssh behavior with Paramiko, set the get_pty parameter of the exec_command to True:

def exec_command(self, command, bufsize=-1, timeout=None, get_pty=False):

Though rather than working around the issue by allocating the pseudo terminal in Paramiko, you should better fix your startup scripts to set the same PATH for all sessions.

For that see Some Unix commands fail with "<command> not found", when executed using Python Paramiko exec_command.

Share:
10,737
Uri Goren
Author by

Uri Goren

Linkedin: http://goren.ml/linkedin GitHub: http://goren.ml/github Vimrc: http://goren.ml/vim

Updated on June 21, 2022

Comments

  • Uri Goren
    Uri Goren almost 2 years

    I am connecting to SSH via terminal (on Mac) and run a Paramiko Python script and for some reason, the two sessions seem to behave differently. The PATH environment variable is different in these cases.

    This is the code I run:

    import paramiko
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect('host', username='myuser',password='mypass')
    stdin, stdout, stderr =ssh.exec_command('echo $PATH')
    print (stdout.readlines())
    

    Any idea why the environment variables are different?

    And how can I fix it?

  • Martin Prikryl
    Martin Prikryl over 8 years
    While this indeed helps, the answer fails to explain why. It's not about Channel vs. SSHClient. The SSHClient uses the Channel internally. The difference is that your original code uses an "exec" channel, which by default does not allocate pseudo terminal. While your new code uses a "shell" channel, which by default allocates a pseudo terminal. Using shell for executing commands is not good practice. And again, it's generally a bad practice to have your account configured to use a different PATH for interactive and non-interactive terminals.
  • Aseem
    Aseem almost 6 years
    I tried your code coz exec_command did not import modules like pandas even though i have them in my ec2. Even small py files that just wrote a new file did not work with your code. how can I get back errors from above method