Check file on ssh

I am trying to check if a file exists via SSH using pexpect. Most of the code works for me, but I need to catch the value so that I can state if the file exists. The code I made 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.

+4
source share
6 answers

If the server accepts sftp sessions, I will not worry about pexpect, but instead use the paramiko SSH2 module for Python:

 import paramiko transport=paramiko.Transport("10.10.0.0") transport.connect(username="service",password="word") sftp=paramiko.SFTPClient.from_transport(transport) filestat=sftp.stat("/opt/ad/bin/email_tidyup.sh") 

The code opens an SFTPClient connection to a server on which you can use stat () to check for files and directories.

sftp.stat will raise an IOError ("There is no such file") when the file does not exist.

If the server does not support sftp, this will work:

 import paramiko client=paramiko.SSHClient() client.load_system_host_keys() client.connect("10.10.0.0",username="service",password="word") _,stdout,_=client.exec_command("[ -f /opt/ad/bin/email_tidyup.sh ] && echo OK") assert stdout.read() 

SSHClient.exec_command returns a triple (stdin, stdout, stderr). Here we just check for any output. Instead, you can change the command or check stderr for any error messages.

+3
source

Why not take advantage of the fact that the command return code is sent back through SSH?

 $ ssh victory 'test -f .bash_history' $ echo $? 0 $ ssh victory 'test -f .csh_history' $ echo $? 1 $ ssh hostdoesntexist 'test -f .csh_history' ssh: Could not resolve hostname hostdoesntexist: Name or service not known $ echo $? 255 

That way, you can just check the return code without requiring capture of the output.

+9
source

I had some problems with this, when every time I ran my program, it would change the result. for example, If I were looking for /bin/bash , it would sometimes return that it was found, and in other cases it would return to the fact that it was absent.

I got the following code to work continuously for files and folders before I expected with \r\n

 # returns 0 if the file is missing and 1 if the file exists # if ( hostFileExists( host, '/bin/sh/' ) == 1 ): echo "File exists!" def hostFileExists( host, theFile ): host.sendline( '[ ! -e %r ] && echo NO || echo YES' % theFile ) return host.expect( ["\r\nNO", "\r\nYES"] ) 

or

 # provide the host, the command, and the expectation # command = '[ ! -e "/bin/sh" ] && echo NO || echo YES' # expecting = ['NO', 'YES'] # i = hostExpect( host, command, expecting ) # if ( i == 1 ): echo "File exists!" def hostExpect( host, command, expect ): newExpect = [] for e in expect: newExpect.append( "\r\n%s" % e ) host.sendline( command ) return host.expect( newExpect ) 

Hope this helps you.

Edit: Also noticed that when ssh'ing on Windows (cygwin) and trying to see if the file exists, the file must be specified. On Linux, this is optional. Thus, %s in host.sendline been changed to %r .

+2
source

I have no pexpect experience, but looking at their webpage seems like you can call a wait method with multiple values ​​and it returns the index of the one it matches (this is based solely on me, just looking at this example).

 child.expect('password:') child.sendline (my_secret_password) # We expect any of these three patterns... i = child.expect (['Permission denied', 'Terminal type', '[#\$] ']) if i==0: print 'Permission denied on host. Can't login' child.kill(0) elif i==2: print 'Login OK... need to send terminal type.' child.sendline('vt100') child.expect ('[#\$] ') elif i==3: print 'Login OK.' print 'Shell command prompt', child.after 

In fact, you are already using this functionality at the top.

So you want to catch if the file exists or not? ...

Try it...

  p.sendline('[ -f email_tidyup.sh ] && echo "File exists" || echo "File does not exists"') file_exists = {0: True, 1: False}[p.expect(('File Exists', 'File does not exists'))] 
0
source

When you as a user enter something into ssh, the shell will repeat the characters back. This is happening now.

So by doing:

 p.sendline('test -f email_tidyup.sh && echo "File exists" || echo "File does not exist"') 

Result:

 service@main- : test -f email_tidy.sh && echo "File exists" || echo "File does not exists" File does not exist 

Performance:

 i = p.expect(['File exists', 'File does not exist']) 

Will always lead to i == 0, because "File exists" is present in the first line received back.

An alternative where the original submit line does not have the expected offer:

 p.sendline('test -f email_tidyup.sh; echo result: $?') i = p.expect('result: 0', 'result: 1') 

Or more like the original:

 p.sendline('[ -f email_tidyup.sh ] && echo "File exists" || echo "File does not exist"') i = p.expect(['\nFile exists', '\nFile does not exist']) 
0
source

I worked on a solution that will make me. Code 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(' service@main- :') assert True elif i==2: print "I either got key or connection timeout" assert False results = p.before # print out the result print results value = results.split('"')[8] split_value = value.split('\r\n')[1:-1] self.assertEquals(split_value, ['File exists']) 

This extracts the value from 'p' in string format. Then I split the line to get the "File Exists" line in the list and compare it with the answer I'm looking for. If the file does not exist, the test will fail.

Thanks for the help.

0
source

Source: https://habr.com/ru/post/1300177/


All Articles