6

I am trying to run sesu command in Unix server from Python with the help of Paramiko exec_command. However when I am running this command exec_command('sesu test'), I am getting

sh: sesu: not found

When I am running simple ls command it giving me desired output. Only with sesu command it is not working fine.

This is how my code looks like:

import paramiko

host = host
username = username
password = password
port = port

ssh=paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ip,port,username,password)
stdin,stdout,stderr=ssh.exec_command('sesu test')
stdin.write('Password')
stdin.flush()
outlines=stdout.readlines()
resp=''.join(outlines)
print(resp)
0

1 Answer 1

17

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):

  1. 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.

  2. Fix your startup scripts to set the PATH the same for both interactive and non-interactive sessions.

  3. Try running the script explicitly via login shell (use --login switch with common *nix shells):

    bash --login -c "sesu test"
    
  4. 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
    
  5. 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:

Sign up to request clarification or add additional context in comments.

1 Comment

You should probably recommend command -V instead of which. There aren't many systems where which is plain wrong anymore; but why risk it when there is a safe POSIX replacement?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.