2

Successfully able to create an SSH connection between my windows machine and an QNX (~linux) system.

Only command that gets any output (stdout) is 'pwd`.

# SSH Connection stuff

stdin, stdout, stderr = client.exec_command('pwd')
output = stdout.readlines()
error = stderr.readlines()
readback = [output, error]

for index, val in enumerate(readback):
    readback = '\n'.join(val)
    print("%s:\t%s") %(index, readback)

Sample output of 'pwd':

0: /home/rxm
1:

When I change the command from pwd to ls:

0:  
1:  ksh: ls: cannot execute - No such file or directory

I get this same error when trying other simple commands, e.g. pidin, ifconfig, etc.

All the necessary commands works when I use PuTTY and create an SSH connection.

Has anyone seen this behavior. Didn't have a whole luck when going the invoke.shell route either. Thanks.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992

2 Answers2

3

pwd is probably built in to your shell, whereas all the other commands you're running are not. ls is not found because $PATH is not set, so you can either set the PATH environment variable, or use a full path when invoking commands, such as /bin/ls.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
3

For the Paramiko session, PATH environment variable obviously does not contain paths to common tools.

The "exec" channel in the Paramiko (rightfully) does not allocate a pseudo terminal (PTY) for the session. As a consequence a different set of startup scripts is (might be) sourced (particularly for non-interactive sessions, .bash_profile and similar are not sourced). And/or different branches in the scripts are taken, based on absence/presence of the TERM environment variable. So the environment might differ from the interactive session, you use with your SSH client.

So, in your case, the PATH is probably set differently; and consequently the ls executable cannot be found. The pwd is probably a built-in command of your shell, so it does not need any path.

To verify that this is the root cause, disable the pseudo terminal allocation in your SSH client. For example in PuTTY, it's Connection > SSH > TTY > Don't allocate a pseudo terminal. Then, go to Connection > SSH > Remote command and enter your ls command. Check Session > Close window on exit > Never and open the session. You should get the same "ksh: ls: cannot execute - No such file or directory" error.


Ways to fix this, in preference order:

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

  2. Fix the command not to rely on a specific environment. Use a full /bin/ls in the command.

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

     bash --login -c "ls"
    
  4. Another (not recommended) approach is to force the pseudo terminal allocation for the "exec" channel using the get_pty argument:

     stdin, stdout, stderr = client.exec_command('ls', 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?

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992