2

I'm a software tester, trying to verify that the log on a remote QNX (a BSD variant) machine will contain the correct entries after specific actions are taken. I am able to list the contents of the directory in which the log resides, and use that information in the command to read (really want to use tail -n XX <file>) the file. So far, I always get a "(No such file or directory)" when trying to read the file.

We are using Froglogic Squish for automated testing, because the Windows UI (that interacts with the server piece on QNX) is built using Qt extensions for standard Windows elements. Squish uses Python 2.7, so I am using Python 2.7.

I am using paramiko for the SSH connection to the QNX server. This has worked great for sending commands to the simulator piece that also runs on the QNX server.

So, here's the code. Some descriptive names have been changed to avoid upsetting my employer.

import sys
import time
import select

sys.path.append(r"C:\Python27\Lib\site-packages")
sys.path.append(r"C:\Python27\Lib\site-packages\pip\_vendor")
import paramiko

# Import SSH configuration variables
ssh_host    = 'vvv.xxx.yyy.zzz'
thelog_dir  = "/logs/the/"
ssh_user    = 'un'
ssh_pw      = 'pw'


def execute_Command(fullCmd):

    outptLines = []
    #
    # Try to connect to the host.
    # Retry a few times if it fails.
    #
    i = 1
    while True:

        try:
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh.connect(ssh_host, 22, ssh_user, ssh_pw)
            break
        except paramiko.AuthenticationException:
            log ("Authentication failed when connecting to %s" % ssh_host)
            return 1
        except:
            log ("Could not SSH to %s, waiting for it to start" % ssh_host)
        
        i += 1
        time.sleep(2)

        # If we could not connect within time limit
        if i == 30:
            log ("Could not connect to %s. Giving up" % ssh_host)
            return 1

    # Send the command (non-blocking?)
    stdin, stdout, stderr = ssh.exec_command(fullCmd, get_pty=True)

    for line in iter(stdout.readline, ""):
    outptLines.append(line)

    #
    # Disconnect from the host
    #
    ssh.close()

    return outptLines


def get_Latest_Log():
    fullCmd = "ls -1 %s | grep the_2" %thelog_dir

    files = execute_Command(fullCmd)

    theFile = files[-1]
    return theFile


def main():
    numLines = 20

    theLog = get_Latest_Log()
    print("\n\nThe latest log is %s\n\n" %theLog)

    fullCmd = "cd /logs/the; tail -n 20 /logs/the/%s" %theLog
    #fullCmd = "tail -n 20 /logs/the/%s" %theLog
    print fullCmd
    logLines = execute_Command(fullCmd)

    for line in logLines:
        print line


if __name__ == "__main__":
    # execute only if run as a script
    main()

I have tried to read the file using both tail and cat. I have also tried to get and open the file using Paramiko's SFTP client.

In all cases, the response of trying to read the file fails -- despite the fact that listing the contents of the directory works fine. (?!) And BTW, the log file is supposed to be readable by 'world'. Permissions are -rw-rw-r--.

The output I get is:

"C:\Users\xsat086\Documents\paramikoTest>python SSH_THE_MsgChk.py

The latest log is the_20210628_115455_205.log

cd /logs/the; tail -n 20 /logs/the/the_20210628_115455_205.log

(No such file or directory)the/the_20210628_115455_205.log"

The file name is correct. If I copy and paste the tail command into an interactive SSH session with the QNX server, it works fine.

Is it something to do with the 'non-interactive' nature of this method of sending commands? I read that some implementations of SSH are built upon a command that offers a very limited environment. I don't see how that would impact this tail command.

Or am I doing something stupid in this code?

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

1 Answers1

0

I cannot really explain completely, why you get the results you get.

But in general a corrupted output is a result of enabling and not handling terminal emulation. You enable the terminal emulation using get_pty=True. Remove it. You should not use the terminal emulation, when automating command execution.

Related question:
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