tags:

views:

99

answers:

4

Hello,

I have a program that logs into a server and issues commands. The results are printed out at the end of the script. The below code shows the script I have created to pass commands through ssh.

import pexpect

ssh_newkey = 'Are you sure you want to continue connecting'
# my ssh command line
p=pexpect.spawn('ssh [email protected]')

i=p.expect([ssh_newkey,'password:',pexpect.EOF])
if i==0:
    print "I say yes"
    p.sendline('yes')
    i=p.expect([ssh_newkey,'password:',pexpect.EOF])
if i==1:
    print "I have entered the password. I will now flip camera through ",
    p.sendline("user")
    i=p.expect('user@hol-NA:')
    p.sendline("cd /opt/ad/bin")
    i=p.expect('user@hol-NA:')
    p.sendline("./ptzflip")
    i=p.expect('user@hol-NA:')
elif i==2:
    print "I either got key or connection timeout"
    pass
results = p.before # print out the result

print results

The results that the program prints out is:

Value = 1800
Min = 0
Max = 3600
Step = 1

I want to capture the values that are printed out.

In reponse to the questions below. I want to capture eg. 'Value' as a variable and '1800' as its value. I have tried to separate it in a dictionary as mentioned below but I get an error. When I enter:

results_dict = {} 
for line in results: 
    name, val = line.split(' = ') 
    results_dict[name] = val

I get an error:

Traceback (most recent call last):
  File "ptest.py", line 30, in <module>
    name, val = line.split(' = ') 
ValueError: need more than 1 value to unpack

When I check this code in Python it stores these values as a string. It stores it as:

'/opt/ad/bin$ ./ptzflip\r\nValue = 1800\r\nMin = 0\r\nMax = 3600\r\nStep = 1\r\n'

Can anyone help in this problem. Thanks

+1  A: 

do you mean save it to a file?? then try this

open("output.txt","w").write(results)

or when you run the script on the command line:

$ python script.py > output.txt

otherwise, define what you mean by "capture"

ghostdog74
+1  A: 

Are Value = 1800 etc. the contents of results? And you want to "capture" that?

Do you mean you want to parse those results? Or execute them as python?

If the former you could do something like (untested, unclean, doesn't deal carefully with whitespace):

results_dict = {}
for line in results.splitlines():
    try:
        name, val = line.split(' = ')
    except ValueError:
        continue
    results_dict[name] = val

This gives you a python dictionary that you can use. If you know that the values are always numbers, you could convert them with int(val) or float(val)... (The try...except ignores lines of the incorrect form; there may be more robust ways to do this, such as if " = " in line)

If you actually want to end up with a variable named Value with the value 1800, you could use eval(results) [or a safer alternative], although this would need to remove lines without the right format first.

Andrew Jaffe
+1  A: 

After each call to p.expect returns, whatever the child process emitted just before the matched part (any number of lines), and the matched part itself, are accessible as the before and after properties of p -- that's your "capture" for you!

I.e., as the docs put it:

After each call to expect() the before and after properties will be set to the text printed by child application. The before property will contain all text up to the expected string pattern. The after string will contain the text that was matched by the expected pattern. The match property is set to the re MatchObject.

The example code in the docs right after this part can be helpful to understand this -- after establishing an FTP session with the interactive ftp client,

   child.sendline('ls /pub/OpenBSD/')
   child.expect('ftp> ')
   print child.before   # Print the result of the ls command.
Alex Martelli
A: 

Whenever this happens to me, it's because the string I'm splitting does not have the value I expected. Why not look at it directly?

for line in results:
    print line
    name, val = line.split(' = ') 
    results_dict[name] = val

If it were what you think it is, this would work (now in the interpreter):

>>> 'Value = 1800'.split(' = ')
['Value', '1800']
telliott99
The problem is that in my solution I had forgotten the ".splitlines()" required to make lines from `results`.
Andrew Jaffe