telnet with pexpect lib in python - python

i want run telnet in python with pexpect lib and i want if telnet password is true, print true and wrong, print wrong...
now my code is:
import pexpect
ip="192.168.1.1"
password="admin"
child = pexpect.spawn("telnet "+ip+" -l admin", timeout=2)
child.expect ("Password:")
child.sendline ("admin")
child.expect(b"> ")
child.sendline ("ls")
child.close()
result = child.signalstatus
if result == 1:
print ("Success")
else:
print ("Bad Result")
in top code, when password is true, script work good and display "success" but when password is wrong, script not display "bad result" and just display a lot of error..
how can i do it?

When you entered bad password, you are not handling it gracefully so it raises a timeout exception and the child.close() was never executed. The errors you see are only the exception related print messages.
Solution:
You can pass a list of expectations and handle them accordingly
child = pexpect.spawn("telnet "+ip+" -l admin", timeout=2)
child.expect ("Password:")
child.sendline ("admin")
result = child.expect(["> ", pexpect.TIMEOUT])
if result == 0: #means prompt was caught successfully i.e. password was correct
child.sendline ("ls")
print ("Success")
elif result == 1:
print ("Bad Result")
child.close()
In fact, this can be made a function, where you can handle more exceptions and special scenarios as per your use-case.

Related

Python not catching exceptions

I have this script:
#!/usr/bin/env python
#import needed modules
import telnetlib
import time
#define variables
HOST = "xxxxxx"
user = "xxxxxx"
password = "xxxxxx"
#open telnet connection
tn = telnetlib.Telnet(HOST, 10800)
time.sleep(2)
#check for initial screen and press enter to go to login
tn.read_until("Device")
tn.write("\r\n")
time.sleep(2)
#Wait for username prompt and enter user/pass
try:
tn.read_until("User Name:",5)
except:
#Timeout looking for Username prompt
print "CRITICAL: User Name prompt never arrived"
exit(2)
tn.write(user + "\r\n")
tn.read_until("Password :")
tn.write(password + "\r\n")
time.sleep(2)
#wait for logout prompt
try:
tn.read_until("7<Logout >",5)
except:
#Timeout looking for successful login
print "CRITICAL: Did not login successfully"
exit(2)
#Logout and close connection
tn.write("7\r")
tn.close()
#Exit with success
print "OK: Test login to MWA Succeeded"
exit(0)
No matter what I do, no exceptions are caught. I changed the read_until looking for "User Name:" to just some garbage characters and it still just gets to the end of the code. I'm hoping I'm just doing something very stupid and not an issue with telnetlib.
Thanks!
Per the docs:
Read until a given string, expected, is encountered or until timeout
seconds have passed.
When no match is found, return whatever is available instead, possibly
the empty string. Raise EOFError if the connection is closed and no
cooked data is available.
Check the return value in the try block, and if this value does not match your expectations, raise on your own to trigger the except case.

Running commands on remote server and saving the result to a string variable in a Python script [duplicate]

This question already has answers here:
Python how to read output from pexpect child?
(8 answers)
Closed 6 years ago.
How can I run commands on the remote server to which I login to, using pexpect and store the result in the form of a string into a variable?
I made a connection to the server in the following way:
COMMAND_PROMPT = '[#$] '
TERMINAL_PROMPT = '(?i)terminal type\?'
TERMINAL_TYPE = 'vt100'
SSH_NEWKEY = '(?i)are you sure you want to continue connecting'
child = pexpect.spawn('ssh -l %s %s'%(loginuser, servername))
i = child.expect([pexpect.TIMEOUT, SSH_NEWKEY, COMMAND_PROMPT, '(?i)password'])
if i == 0: # Timeout
print('ERROR! could not login with SSH. Here is what SSH said:')
print(child.before, child.after)
print(str(child))
sys.exit (1)
if i == 1: # In this case SSH does not have the public key cached.
child.sendline ('yes')
child.expect ('(?i)password')
if i == 2:
# If a public key was setup to automatically login
pass
if i == 3:
child.sendline(password)
# Now we are either at the command prompt or
# the login process is asking for our terminal type.
i = child.expect ([COMMAND_PROMPT, TERMINAL_PROMPT])
if i == 1:
child.sendline (TERMINAL_TYPE)
child.expect (COMMAND_PROMPT)
Now suppose I want to execute the following command on the server I logged in to and save the result to a string in my python script itself:
ps -ef|grep process1
How can this be done?
I think this might help you.
import subprocess
import sys
url="http://www.anyurlulike.any"
# Ports are handled in ~/.ssh/config since we use OpenSSH
COMMAND="uname -a"
ssh = subprocess.Popen(["ssh", "%s" % url, COMMAND],
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
result = ssh.stdout.readlines()
if result == []:
error = ssh.stderr.readlines()
print >>sys.stderr, "ERROR: %s" % error
else:
print result
You can use read() function, it will give you the entire output.
result = child.read()

subprocess function displaying odd output

I've got a function def tldomaint that executes the Tasklist command via a subprocess call_checkout. All is working as expected but I'm getting odd output from TaskList. I'm not sure if it's due to my error capturing or if its just an oddity of Tasklist. I'm hoping someone can help pin-point the issue.
Output example:
Attempting to make remote connections and gather data:
Targeted User: xpuser
ERROR: The RPC server is unavailable.
1
WARNING: User credentials cannot be used for local connections
ERROR: The RPC server is unavailable.
1
The 1 in the output is the oddity I'm referring to.
Below is the function.
def tldomaint(serverlist, domain, username, password, targetuser):
nlist = serverlist
print "\nAttempting to make remote connections and gather data:\n"
print "Targeted User: {0}\n" .format(targetuser)
for serverl in nlist:
try:
out = subprocess.check_output(["tasklist", "/V", "/S", serverl, "/U", domain + "\\" + username, "/P", password, "/FO", "List", "/FI", "USERNAME eq %s\\%s" % (domain, targetuser)])
users = [item for item in out.split() if domain in item and targetuser in item]
sortedl = set(users)
for name in sortedl:
if name in sortedl != '':
print "Targeted User Found On {0}\n" .format(serverl)
print name
else:
print "User Not Found"
except CalledProcessError as e:
print(e.returncode)
return sortedl
You are printing the process return code:
except CalledProcessError as e:
print(e.returncode)
From the subprocess.check_output() documentation:
If the return code was non-zero it raises a CalledProcessError.
When an error occured, the tasklist writes an error message to stderr, and sets the exit code to 1. subprocess.check_output() then raises the CalledProcessError exception (as documented) and you catch that exception and then print the return code.
Remove the print() statement and your mysterious 1s will go away.
If you wanted to handle the problem in Python, redirect stderr to stdout; the exception will still be raised but you can read the output still:
out = subprocess.check_output(["tasklist", "/V", "/S", serverl, "/U",
domain + "\\" + username, "/P", password, "/FO", "List",
"/FI", "USERNAME eq %s\\%s" % (domain, targetuser)],
stderr=subprocess.STDOUT)
and in your exception handler:
except CalledProcessError as e:
errormessage = e.output
# do something with the error message

python pexpect & pxssh with sudo and EOF

I make ssh login with this script:
import pxssh
import pexpect
s = pxssh.pxssh()
hostname = 'localhost'
username = 'py_worker'
password = 'nicejob'
s.login (hostname, username, password)
print "logged in"
Then I want to run some program which in some case may require sudo password and in some case may not require. So I want a scrip which could provide sudo password in those cases when required and just run the program if sudo is not asked.
I thought this code could handle:
s.sendline('sudo apt-get check')
i=s.expect(['password', pexpect.EOF])
if i==0:
print "I give password"
s.sendline("nicejob")
s.prompt()
elif i==1:
print "EOF cought"
s.prompt()
print s.before
Could someone help with code lines which could handle sudo correctly?
thanks for asking this, it helped me.
youll probably need to flesh out the exceptions and re for the rootprompt but here you go.
def sudo(s,password):
rootprompt = re.compile('.*[$#]')
s.sendline('sudo -s')
i = s.expect([rootprompt,'assword.*: '])
if i==0:
print "didnt need password!"
pass
elif i==1:
print "sending password"
s.sendline(password)
j = s.expect([rootprompt,'Sorry, try again'])
if j == 0:
pass
elif j == 1:
raise Exception("bad password")
else:
raise Exception("unexpected output")
s.set_unique_promp

How to get out of a try/except inside a while? [Python]

I'm trying this simple code, but the damn break doesn't work... what is wrong?
while True:
for proxy in proxylist:
try:
h = urllib.urlopen(website, proxies = {'http': proxy}).readlines()
print 'worked %s' % proxy
break
except:
print 'error %s' % proxy
print 'done'
It's supposed to leave the while when the connection work, and go back and try another proxy if it didn't
ok, here is what I'm doing
I'm trying to check a website and if it changed, it has to break out of the while to continue to the rest of the script, but when the proxy doesn't connect, I get error from the variable, as it's null, so what I want is this for work as loop to try a proxy, and if it work, continue the script, and the end of the script, go back and try the next proxy, and if the next doesn't work, it will be back to the beginning to try the third proxy, and so on....
I'm trying something like this
while True:
for proxy in proxylist:
try:
h = urllib.urlopen(website, proxies = {'http': proxy})
except:
print 'error'
check_content = h.readlines()
h.close()
if check_before != '' and check_before != check_content:
break
check_before = check_content
print 'everything the same'
print 'changed'
You just break out of for loop -- not while loop:
running = True
while running:
for proxy in proxylist:
try:
h = urllib.urlopen(website, proxies = {'http': proxy}).readlines()
print 'worked %s' % proxy
running = False
except:
print 'error %s' % proxy
print 'done'
You can use a custom exception and then catch it:
exit_condition = False
try:
<some code ...>
if exit_conditon is True:
raise UnboundLocalError('My exit condition was met. Leaving try block')
<some code ...>
except UnboundLocalError, e:
print 'Here I got out of try with message %s' % e.message
pass
except Exception, e:
print 'Here is my initial exception'
finally:
print 'Here I do finally only if I want to'
You break out of the for loop only, so you never leave the while loop and restart iterating over the proxylist over and over again. Just omit the surrounding while loop, I actually don't understand why you enclosed the code in a while True in the first place.
break is breaking the innermost loop, which is the for loop in your case. To break from more than one loop you have few options:
Introduce a condition
Create a sub and use return
but in your case you actually don't need the outer while loop at all. Just remove it.

Categories

Resources