Python script to catch failed commands or warnings messages - python

I have a little script that telnets into a network switch and executes commands. It works fine but I need it stop and show an error message if any of the commands fail or network give a waning or something.
Here is the code:
import sys
import telnetlib
HOST = "10.10.10.1"
user = "Test"
password = "TestPW"
tn = telnetlib.Telnet(HOST)
tn.read_until("username: ")
tn.write(user + "\n")
tn.read_until("password: ")
tn.write(password + "\n")
n, match, previous_text = tn.expect([r'Login incorrect', r'\$'], 1)
if n == 0:
print "Invalid Credentials"
tn.close()
else:
tn.write("Term len 0\n")
#Reads data from commands.txt file and executes it line by line
with open("commands.txt") as commands:
singlecommand = commands.read()
tn.write(singlecommand)
print singlecommand
#Need exception/error checking to catch fail commands or warnings.
tn.write("exit\n")
tn.write("y\n")
print tn.read_all()
tn.close()
I want the script to stop executing more commands after a fail command or a warning from CLI that something maybe wrong. It already has the print function so it should display the error message and command that failed.
Here is a example of a failed command:
% Invalid input detected at '^' marker.
Here is an example warning message:
%Warning:

You can use Try/Except statements.
They're related to the Errors and Exceptions part of the Python docs.
Example:
try:
wrong_sum = "a" + 2
except ValueError:
print "You got a Value Error"
else:
break

you can extract the message based on key word appeared in failed command, then raise the exception.
for example:
try:
if '%Warning' == message[:8]:
raise Exception('Test')
except Exception:
print message

Related

Can not catch os error with subprocessing

Does anyone know if you can catch os errors in python. I am working on a script that is mapping network drives.
If the end user types the name of a path that does not exist no error shows up and that could become an issues.
I am using the subprocess module, with python version 3.6, along with the pycharm IDE.
If I map to a location that does not exist I get the following error "System error 53 has occurred. The network path was not found."
Lastly I have tried catching the error using OSError, Exception, and BaseException. Each one that I have used does not return any error message.
Here is an example of the script that I am running.
def StoreInfo():
receiving = input("Enter receiving: ")
try:
subprocess.call(r'net use y: \\' + receiving + '\\act\\rto\\transent', shell=True) #timeout=30
except OSError:
#print("An unexpected error:" , sys.exc_info()[0])
print(sending+"'s path does not exit!")
StoreInfo()
Python ยป Documentation Subprocess
try:
retcode = call("mycmd" + " myarg", shell=True)
if retcode < 0:
print >>sys.stderr, "Child was terminated by signal", -retcode
else:
print >>sys.stderr, "Child returned", retcode
except OSError as e:
print >>sys.stderr, "Execution failed:", e

How to parse a Linux terminal error message in Python?

I have written a small Python code to test it for a bigger project. The subprocess works great if everything's fine. But I want to parse the output error message for particular errors so I can figure out what the error is such as- IP not in network, or wrong username, wrong password.
Even the print at the end doesnt work. My interest in however not to print those. I was merely checking if the parsing works!
import sys
import subprocess
import os
ip = "192.168.1.20"
password = "password"
username = "sam"
ans = subprocess.check_output(['sudo','xfreerdp','-p',password, ip])
for line in ans.split('\n'):
if "protocol security negotiation" in line:
print "Not Windows!"
print "JUST TO test if this print works and it doesnt!!"
Try using try..except
import sys
import subprocess
import os
ip = "192.168.1.20"
password = "password"
username = "sam"
try:
ans = subprocess.check_output(['sudo','xfreerdp','-p',password, ip])
except subprocess.CalledProcessError as e:
ans = e.output
for line in ans.split('\n'):
if "protocol security negotiation" in line:
print "Not Windows!"
print "JUST TO test if this print works and it doesnt!!"
You need to redirect STDERR in order to check messages printed to it. Add:
subprocess.check_output(['sudo','xfreerdp','-p',password, ip], stderr=subprocess.STDOUT)

AttributeError: 'NoneType' object has no attribute 'sendline' yet module contains the attribute having tested it another way?

After importing the relevant libraries and creating a connect function using the pxssh library, I have created my main function to accept the arguments of 'host, 'user' and the filename that I give.
The program successfully reads the file and parses each password string into the s.login method and returns 'success' message after finding the password. This I assume means that the connection has been made with the ssh server. But from the point of 'con = connect' I get no print statement to say that [SSH connected...] further than that I get the command line prompt after it successfully finds the password but after entering a command I get an attribute error against con.sendline -
>ls -l
Traceback (most recent call last):
File "sshBruteFpw.py", line 60, in <module>
main()
File "sshBruteFpw.py", line 52, in main
con.sendline(command)
AttributeError: 'NoneType' object has no attribute 'sendline'
root#kali:~/Desktop/scripts#
I am at a loss as to why con.sendline has no attribute 'sendline' when I know that the library contains this method. I have tested this sendline method in other ways and it will work.
Any help on this much appreciated. Thanks in advance...
import pxssh
import argparse
import time
import sys
import getpass
def connect(host, user, password):
Fails = 0
try:
s = pxssh.pxssh()
s.login(host, user, password)
print '[+] password found! ' + password
return s
except Exception, e:
if Fails > 5:
print '[-] Too many Socket Timeouts!!'
sys.exit(1)
elif 'read_nonblocking' in str(e):
Fails += 1
time.sleep(5)
return connect(host, user, password)
elif 'synchronize with original prompt' in str(e):
time.sleep(1)
return connect(host, user, password)
return None
def main():
parser = argparse.ArgumentParser()
parser.add_argument('host', help='Specify Target Host')
parser.add_argument('user', help='Specify Target User')
parser.add_argument('file', help='Specify Password File')
args = parser.parse_args()
if args.host and args.user and args.file: #if these args are all true
with open(args.file, 'r') as infile: #open with and read only the specified file as 'infile'
for line in infile:
password = line.strip('\r\n')#read and strip each line
print "[+] testing passsword " + str(password) #print statement + the read PW being read from the file(converts all to str in case there is a numerical value as well)
con = connect(args.host, args.user, password)
if con: #if we get a connection
print "[+] [SSH Connected, Issue Commands (q or Q) to quit]" #just shows uset that they have made a connection and know how to quit
command = raw_input(">")
while command != 'q' and command != 'Q':
con.sendline(command)
con.prompt()
print con.before
command = raw_input(">")
else:
print parser.usage
sys.exit(1)
if __name__ == '__main__':
main()
Unless the indentation is very off, you are going into that branch of the code, even if you don't have con set up:
if con: #if we get a connection
print "[+] [SSH Connected, Issue Commands (q or Q) to quit]" #just shows uset that they have made a connection and know how to quit
command = raw_input(">")
while command != 'q' and command != 'Q':
con.sendline(command)
after the second line, there should be continue, if the connection failed, isn't it?

Need little assistance with pexpect module

Need assistance with the pexpect module
I have written a simple code which would clone a git repository from a server using ssh.
I'm facing couple of problems.
The password is shown in plain text.
I dont know a proper way to exit the program after the download. it throws out the following error...
Traceback (most recent call last):
File "ToDelete3.py", line 65, in <module>
# # if i == 1:
File "ToDelete3.py", line 36, in getRepository
i = p.expect([ssh_key,'password:',pexpect.EOF])
File "/usr/lib/python2.7/dist-packages/pexpect.py", line 1492, in interact
self.__interact_copy(escape_character, input_filter, output_filter)
File "/usr/lib/python2.7/dist-packages/pexpect.py", line 1520, in __interact_copy
data = self.__interact_read(self.child_fd)
File "/usr/lib/python2.7/dist-packages/pexpect.py", line 1510, in __interact_read
return os.read(fd, 1000)
OSError: [Errno 5] Input/output error
the code that I have written so far is :
command = 'git clone ssh://username#someserver/something.git'
ssh_key = 'Are you sure you want to continue connecting'
def gracefulExit():
print 'Password Incorrect !!!'
os._exit(1)
def getRepository():
p = pexpect.spawn(command,maxread=10000,timeout = 100)
p.logfile = sys.stdout # logs out the command
i = p.expect([ssh_key,'password:',pexpect.EOF])
if i == 0:
print 'Inside sshkey'
p.sendline('yes')
i = p.expect([ssh_key,'password:',pexpect.EOF])
if i == 1:
try:
p.sendline('mypassword') # this mypassword is shown in clear text on the console
p.interact()
p.logfile = sys.stdout
p.expect(pexpect.EOF)
except Exception,e:
print str(e)
gracefulExit()
if i == 2:
print 'Inside EOF block'
if p.isalive():
print '******************************************************'
print ' Closing the process of Download !!! '
print '******************************************************\n\n'
p.close()
Any inputs is highly appreciated..
Thanks.
-Vijay
There are few errors in the program:
p.interact()
This is used when we want to get back the control after having automatically supplied the password using pexpect module. You don't need to use that since you are automating the whole repository check out.
Also a few things can be improved, after passing the password, set a infinite timeout since it may take a while to copy a git repository.
p.expect(pexpect.EOF, timeout=None)
After that you can read all the execution output with the following command
output_lines = p.before
output_lines_list = output_lines.split('\r\n')
for line in output_lines: print line
you can also use the above to log the output to a file by directly writing to it
Using p.logifile = sys.stdout is not good since it will record pexpect operation from start including passing of password.
After this there is no need to close, you are not running a interactive program. Remove all these lines:
if i == 2:
print 'Inside EOF block'
if p.isalive():
print '******************************************************'
print ' Closing the process of Download !!! '
print '******************************************************\n\n'
p.close()
The issue is that some where you have to store the password and use it with p.sendline. How ever, you store password, it is going to be insecure. You can also take the input at the start for the password, this way you will not be storing the password within your program but that defeats automation. I don't see a way out but for taking password input, you can do:
import getpass
getpass.getpass("please provide your password")
To get rid of the password being echo'd to stdout, use the following when redirecting output -
p.logfile_read = sys.stdout # logs out the command
I have tried this myself and seems to be working. Here is the reference for this revelation.

Python file not found error when the file clearly exists

I have been working on a project that takes a MySQL dump and restores a database with the information that a user provides. I keep getting a file can not be found error then my custom error for debugging stating that. OS command has failed.
try:
username = self.username.get()
password = self.password.get()
database = self.database.get()
file = self.filename
print str(username)
print str(file)
test = os.system("mysql -u" + username + " -p" + password + " " + database + " <" + file)
if (test != 0):
print "OS COMMAND FAILED"
else:
print "pass"
print test
except:
print "fail"
print "Unexpected error:", sys.exc_info()[0]
raise
I will also continue to do research just in case I find the solution. I have been looking at the os.system command but the problem goes away if I specify the file name right in the command instead of retrieving it from a variable.
All the variables are pulled from entry boxes. There is no way for a user to type the file name incorectly as the program populates the filename based on a openfiledialog box and does not allow for the user to edit that box.
Error text:
C:/Documents and Settings/XPMUser/Desktop/src/database.sql
root
The system cannot find the file specified.
OS COMMAND FAILED
1
If there is a space in the filename, that will cause the kind of problem you describe. The shell will parse the space as being a delimiter. You may want to do something like
import pipes
...
database + " < " + pipes.quote(filename)
Better yet, use the subprocess module
test = subprocess.call(['mysql', '-u', username, '-p', password, database],
stdin=open(file))

Categories