1

I have a below python script where in I am executing a remote SSH command using expect. Here, even the target file contains the string "error" or not, the exit code is returned as success always as the ssh connectivity is what only checked. How can I get the status of the grep command?

#! /usr/bin/python

import subprocess

def execute(cmd):
    proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    _output, _error = proc.communicate()
    _code = proc.returncode
    return _output, _error, _code

host = "localhost"
passwd = "kube"

cmd="/usr/bin/expect -c 'spawn ssh "+host+" \"cat /home/kube/f1 | grep -qi error\"; expect \"password:\" { send \""+passwd+"\r\"} ;interact' "
_output, _error, return_code = execute(cmd)
print cmd + "\n" + _output + "\n" + _error

if (return_code == 0):
    print "no error"
else:
    print "contains error"
Ibrahim Quraish
  • 3,889
  • 2
  • 31
  • 39
  • And what do you have in `_output` and `_error` after running this? – zvone Jan 13 '21 at 20:37
  • 1
    There are specialized libraries which are made for remote subprocess over SSH. [paramiko](https://stackoverflow.com/questions/3586106/perform-commands-over-ssh-with-python), or I use [Fabric](http://www.fabfile.org/) to do this. Also, password and ssh is missing the point of ssh somewhat, IMHO. – JL Peyret Jan 13 '21 at 20:57
  • `zvone` no error only output `spawn ssh localhost cat /home/kube/f1 | grep -qi error kube@localhost's password:` – Ibrahim Quraish Jan 13 '21 at 21:01

1 Answers1

1

Option 1:

Let the remote command output something which indicates success/failure for you. E.g.:

ssh user@host "/some/command | grep -q some-string && echo MAGIC-SUCCESS || echo MAGIC-FAILURE"

And in Python you can get the output and parse it.

Option 2:

According to man expect:

  • wait [args]

    [...] wait normally returns a list of four integers. The first integer is the pid of the process that was waited upon. The second integer is the corresponding spawn id. The third integer is -1 if an operating system error occurred, or 0 otherwise. If the third integer was 0, the fourth integer is the status returned by the spawned process. If the third integer was -1, the fourth integer is the value of errno set by the operating system. [...]

So your Expect code can check the wait result and then exit with different values and Python code can get the exit status.

For Expect part it's like this:

spawn ...
...
expect eof
set result [wait]
exit [lindex $result 3]
pynexj
  • 19,215
  • 5
  • 38
  • 56
  • I added those lines in my `expect` command string `cmd="/usr/bin/expect -c 'spawn ssh "+host+" \"cat /home/kube/f1 | grep -qi error\"; expect \"password:\" { send \""+passwd+"\r\"} ;expect eof; set result [wait]; exit [lindex result 3]' "` but it always returns 0 (whether error string present or unavailable) – Ibrahim Quraish Jan 14 '21 at 08:52
  • 1
    there was typo. just fixed. `lindex result 3` ==> `lindex $result 3` – pynexj Jan 14 '21 at 08:57
  • by the way python has its own [tag:pexpect]. may be a bit easier than running Expect in python. – pynexj Jan 14 '21 at 10:07