I am trying to test if a file exists over SSH using pexpect. I have got most of the code working but I need to catch the value so I can assert whether the file exists. The code I have done is below:
def VersionID():
ssh_newkey = 'Are you sure you want to continue connecting'
# my ssh command line
p=pexpect.spawn('ssh service@10.10.0.0')
i=p.expect([ssh_newkey,'password:',pexpect.EOF])
if i==0:
p.sendline('yes')
i=p.expect([ssh_newkey,'password:',pexpect.EOF])
if i==1:
p.sendline("word")
i=p.expect('service@main-:')
p.sendline("cd /opt/ad/bin")
i=p.expect('service@main-:')
p.sendline('[ -f email_tidyup.sh ] && echo "File exists" || echo "File does not exists"')
i=p.expect('File Exists')
i=p.expect('service@main-:')
assert True
elif i==2:
print "I either got key or connection timeout"
assert False
results = p.before # print out the result
VersionID()
Thanks for any help.
When you as user type something in ssh, the shell will echo the characters back. That is happening now as well.
So, doing:
Will result in an input of:
Doing:
Will then always result in i==0, because "File exists" is present in the first line that is received back.
An alternative where the original send line, does not have the expected sentence:
Or more like the original:
I was having some issues with this where every time I ran my program, it would change the output. e.g. If I was looking for
/bin/bash
, it would sometimes return that it was found and other times it would return that it was missing.I got the following code to work consistently for files and folders by preceding what I expected with
\r\n
or
Hope this helps you.
Edit: Also noticed that when ssh'ing into Windows (cygwin) and trying to see if a file exists, the file must be quoted. On Linux, this is optional. So the
%s
inhost.sendline
was changed to%r
.If the server accepts sftp sessions, I wouldn't bother with pexpect, but instead use the paramiko SSH2 module for Python:
The code opens an SFTPClient connection to the server, on which you can use stat() to check for the existance of files and directories.
sftp.stat will raise an IOError ('No such file') when the file doesn't exist.
If the server doesn't support sftp, this would work:
SSHClient.exec_command returns a triple (stdin,stdout,stderr). Here we just check for the presence of any output. You might instead vary the command or check stderr for any error messages instead.
I don't have any pexpect experience but looking at their web page it looks like you can call the expect method with multiple values and it returns the index of the one that it matches (this is based purely on me just looking at this example).
Actually, you're already using that functionality at the top.
So you want to catch whether the file exists or not?...
Try this...
Why not take advantage of the fact that the return code of the command is passed back over SSH?
This way, you can just check the return code without needing to capture output.
I have worked the solution that will do me. The code is below:
This extracts the value from 'p' in a string format. I then split the string up to get the string 'File Exists' into a list and compare it to the response I am looking for. If the File does not exists the test will fail.
Thanks for all the help.