Some Unix commands fail with “<command> not found”, when executed using Python Paramiko exec_command

假装没事ソ 提交于 2019-11-26 02:25:43

问题


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)

回答1:


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 (particularly for non-interactive sessions, .bash_profile is not sourced), than in your regular interactive SSH session. 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?


See also:

  • Environment variable differences when using Paramiko
  • Certain Unix commands fail with "... not found", when executed through Java using JSch


来源:https://stackoverflow.com/questions/55419330/some-unix-commands-fail-with-command-not-found-when-executed-using-python-p

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!