how to make a variable case insensitive? - python

I want change the below code to run the command adb -s %s get-state"%(adb_id) such that the adb_id is made case-insensitive,it should work if the adb_id is 1281b6a1 or 1281B6A1 ?can anyone provide guidance on how to do that?
import subprocess
from subprocess import Popen, PIPE, STDOUT
#adb_id = '1281b6a1'
adb_id = '1281B6A1'
cmd = r"C:\adb -s %s get-state"%(adb_id)#cmd = os.getcwd() + "\\adb devices"
proc = subprocess.Popen(cmd.split(' '), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(output,error) = proc.communicate()
#Check if adb detects any devices
if error != '':
print "ERROR:%s"%error
else :
print "Provided Id is found in ADB as ", output
print str ( output ).strip()

You can't make adb case-insensitive, so if you want the user to be able to enter the device ID without worrying about case, you'll need to find the correct case of the device's name and pass that to adb.
And to do that you'll need to get the output of adb devices to find the device's actual name. Then find what the user entered in that device list using a case-insensitive search, and finally return the canonical device name from that.
devlist = subprocess.check_output("adb devices")
devname = "\r\n%s\t" % adb_id.lower() # device name is followed by tab
posn = devlist.lower().find(devname)
if posn + 1: # found
adb_id = devlist[posn+2:posn+2+len(adb_id)]
else:
print("that device is not connected")
Now adb_id is the case-corrected version of the device ID and can be passed via subprocess to adb.
A better solution is probably to use the output of adb devices to make a menu. That way the user doesn't have to type the full device name.

Related

Python Pexpect full output is not saved (How to deal with the "--More--" prompt?)

I am using Pexpect to run a command remotely on a server and saving the output in a file. However, it does not save the whole output as it's truncated due to --More-- . Is there a way to avoid --More--, so that the whole output is saved in the output file?
I have tried using child.setwinsize(1000,1000) but it didn't solve the issue.
Current code:
import pexpect
import time
child = pexpect.spawn('ssh username#ip_address')
time.sleep(1)
child.sendline('password')
time.sleep(1)
child.logfile = open("output.txt", "w")
child.sendline('command')
child.expect(pexpect.EOF)
print child.before, child.after
child.close
Not sure what command you're running but usually you can press SPACE when you see the --More-- prompt. For example:
import pexpect, sys
child = pexpect.spawn('more /etc/services')
child.logfile_read = sys.stdout
patterns = ['--More--', pexpect.EOF]
while True:
ret = child.expect(patterns)
if ret == 0:
child.send(' ')
elif ret == 1:
break
I found one more answer- just execute below command before actual command.
terminal length 0
After that suppose I entered some command like show ip interface. Then, This will show whole output. You don't need to press enter again and again. As,
child.sendline('terminal length 0')
child.expect('# ')
child.sendline('show ip interface') #write your command here
child.expect('# ')

python call shell command and check response

Trying to write a function that reads the output of a shell command before making a decision.. For example:
6 def getCreds():
7 global access_key, secret_key, yourName
8 access_key = raw_input("Enter Access Key: ")
9 secret_key = raw_input("Enter Secret Key: ")
10 infoCorrect = raw_input('Is this information correct? (y or n)')
11 if infoCorrect.lower() == "yes" or infoCorrect.lower() =="y":
12 call (["./somecommand -u %s -p %s -flags" % (access_key, secret_key) + tfdir],shell=True)
13 else:
The output of the shell command is either
"You have successfully logged in"
or
"you cannot log in"
So I dont know the right syntax to go :
if response = "You have successfully logged in" :
(some action)
elif:
(some action)
How to I read the response?
Thanks!
use Popen() method defined in subprocess and redirect your output to PIPE. try this code:
import subprocess
p = subprocess.Popen("ls", shell=True, stdout = subprocess.PIPE)
output,err = p.communicate()
print(output)
I dont think output of shell command can be returned. You could only check that whether the command is successful or returned an error.
Having said that you could redirect your output to a file and then examine its content.
f = open("outputFile","wb")
call (["./somecommand -u %s -p %s -flags" % (access_key, secret_key) + tfdir],shell=True,stdout=f)
If you want to avoid writing to file then you may want to look at StringIO module.

Enter an ssh password using the standard python library (not pexpect)

Related questions that are essentially asking the same thing, but have answers that don't work for me:
Make python enter password when running a csh script
How to interact with ssh using subprocess module
How to execute a process remotely using python
I want to ssh into a remote machine and run one command. For example:
ssh <user>#<ipv6-link-local-addr>%eth0 sudo service fooService status
The problem is that I'm trying to do this through a python script with only the standard libraries (no pexpect). I've been trying to get this to work using the subprocess module, but calling communicate always blocks when requesting a password, even though I supplied the password as an argument to communicate. For example:
proc = subprocess.Popen(
[
"ssh",
"{testUser1}#{testHost1}%eth0".format(**locals()),
"sudo service cassandra status"],
shell=False,
stdin=subprocess.PIPE)
a, b = proc.communicate(input=testPasswd1)
print "a:", a, "b:", b
print "return code: ", proc.returncode
I've tried a number of variants of the above, as well (e.g., removing "input=", adding/removing subprocess.PIPE assignments to stdout and sterr). However, the result is always the same prompt:
ubuntu#<ipv6-link-local-addr>%eth0's password:
Am I missing something? Or is there another way to achieve this using the python standard libraries?
This answer is just an adaptation of this answer by Torxed, which I recommend you go upvote. It simply adds the ability to capture the output of the command you execute on the remote server.
import pty
from os import waitpid, execv, read, write
class ssh():
def __init__(self, host, execute='echo "done" > /root/testing.txt',
askpass=False, user='root', password=b'SuperSecurePassword'):
self.exec_ = execute
self.host = host
self.user = user
self.password = password
self.askpass = askpass
self.run()
def run(self):
command = [
'/usr/bin/ssh',
self.user+'#'+self.host,
'-o', 'NumberOfPasswordPrompts=1',
self.exec_,
]
# PID = 0 for child, and the PID of the child for the parent
pid, child_fd = pty.fork()
if not pid: # Child process
# Replace child process with our SSH process
execv(command[0], command)
## if we havn't setup pub-key authentication
## we can loop for a password promt and "insert" the password.
while self.askpass:
try:
output = read(child_fd, 1024).strip()
except:
break
lower = output.lower()
# Write the password
if b'password:' in lower:
write(child_fd, self.password + b'\n')
break
elif b'are you sure you want to continue connecting' in lower:
# Adding key to known_hosts
write(child_fd, b'yes\n')
else:
print('Error:',output)
# See if there's more output to read after the password has been sent,
# And capture it in a list.
output = []
while True:
try:
output.append(read(child_fd, 1024).strip())
except:
break
waitpid(pid, 0)
return ''.join(output)
if __name__ == "__main__":
s = ssh("some ip", execute="ls -R /etc", askpass=True)
print s.run()
Output:
/etc:
adduser.conf
adjtime
aliases
alternatives
apm
apt
bash.bashrc
bash_completion.d
<and so on>

How to properly perform host or dig command in python

I want to process host or dig commands using python to check if a domain is blacklisted. I use these
surbl_result = os.system(host_str + ".multi.surbl.org")
#this works like performing a terminal command which is host johnnydeppsource.com.multi.surbl.org
It returns a response which is an integer 0 (which means it is listed in the blacklist) or 256(it is not listed)
if surbl_result == 0: #blacklisted in surbl
black_list = True
but sometimes, the host command fails and gives a serve fail response
Host johnnydeppsource.com.multi.surbl.org not found: 2(SERVFAIL)
And this returns a zero value permitting it to add the new domain even if it is blacklisted.. Are there other ways to perform this kind of thing? This is contained in my django 1.6 application. Any leads will help..
os.system(command) returns the exit_status after Executing the command (a string) in a subshell.
Better to use in the below manner:
from subprocess import Popen, PIPE
subproc = Popen(host_str + ".multi.surbl.org", stdout=PIPE, shell=True)
output, errorCode = subproc.communicate()
if errorCode == None:
black_list = True

Change DenyHosts report: Call external command from Python

To begin with, I don't know the first thing about Python ... so I can really use any pointers you have. I do know some Perl, Bash scripting and a bit C++.
I'm running DenyHosts (http://denyhosts.sourceforge.net/) which every now and then sends me a message through email that an IP address was added to /etc/deny.hosts. Eg.:
Added the following hosts to /etc/hosts.deny:
87.215.133.109 (unknown)
----------------------------------------------------------------------
So far so good, but I want to add the country of the IP address to this message. To do this I created a small Perl script that spits out the country:
/usr/local/bin/geo-ip.pl --short 87.215.133.109
Netherlands
So all I want to do is to call this Perl script from Python and then fill the result in the message string. I located the source code which I suspect I need to change, but as announced at the top of this message, I don't know the first thing about Python.
This is a sniplet from the main program calling a subroutine in report.py
deny_hosts.py:
#print deny_hosts
new_denied_hosts, status = self.update_hosts_deny(deny_hosts)
if new_denied_hosts:
if not status:
msg = "WARNING: Could not add the following hosts to %s" % self.__prefs.get('HOSTS_DENY')
else:
msg = "Added the following hosts to %s" % self.__prefs.get('HOSTS_DENY')
self.__report.add_section(msg, new_denied_hosts)
if self.__sync_server: self.sync_add_hosts(new_denied_hosts)
plugin_deny = self.__prefs.get('PLUGIN_DENY')
if plugin_deny: plugin.execute(plugin_deny, new_denied_hosts)
I think the change should go somewhere in here.
report.py defines the add_section:
def add_section(self, message, iterable):
self.report += "%s:\n\n" % message
for i in iterable:
if type(i) in (TupleType, ListType):
extra = ": %d\n" % i[1]
i = i[0]
else:
extra = ""
if self.hostname_lookup:
hostname = self.get_hostname(i)
debug("get_host: %s", hostname)
else: hostname = i
self.report += "%s%s\n" % (hostname, extra)
if self.use_syslog:
syslog.syslog("%s - %s%s" %(message, hostname, extra))
self.report += "\n" + "-" * 70 + "\n"
Please help me change the code in such a way that it'll spit out a message like:
Added the following hosts to /etc/hosts.deny:
87.215.133.109 (Netherlands, unknown)
----------------------------------------------------------------------
EDIT3:
This is how I solved it. The output is identical to the original message. After changing the sources, the daemon needs to be restarted (sudo /etc/init.d/denyhosts restart)
def add_section(self, message, iterable):
# added geo-ip
# moving this from statement to the top of the file makes pycheck generate
# a lot of errors, so I left it here.
from subprocess import Popen, PIPE
# end geo-ip hack import
self.report += "%s:\n\n" % message
for i in iterable:
if type(i) in (TupleType, ListType):
extra = ": %d\n" % i[1]
i = i[0]
else:
extra = ""
if self.hostname_lookup:
hostname = self.get_hostname(i)
debug("get_host: %s", hostname)
else: hostname = i
# self.report += "%s%s\n" % (hostname, extra)
# JPH: added geo-ip
geocmd = "/usr/local/bin/geo-ip.pl --short %s" % i
country = Popen( geocmd, shell=True, stdout=PIPE).communicate()[0]
country = country.strip()
self.report += "%s%s\n%s\n" % (hostname, extra, country)
# end geo-ip hack
if self.use_syslog:
syslog.syslog("%s - %s%s" %(message, hostname, extra))
self.report += "\n" + "-" * 70 + "\n"
Also help me understand what I change, so I can learn a bit Python today too.
EDIT2: For the sake of sharing a link to the geo-ip.pl script http://wirespeed.xs4all.nl/mediawiki/index.php/Geo-ip.pl
EDIT1: Recompilation is done automatically when the source changes, so that answers the question below.
The second problem I have with this is that I found two matching files on my system:
/usr/share/denyhosts/DenyHosts/report.py
/usr/share/denyhosts/DenyHosts/report.pyc
where the .py is the source code and I suspect .pyc actually being executed. So when I change the source code, I wouldn't be surprised nothing changes if I don't somehow compile it afterwards.
I'm only going to answer the specific part of your question about how to call your perl script via python and get the output. The part about where to slot in this info is a little too vague for me to guess from your snippets...
from subprocess import Popen, PIPE
hostIP = "87.215.133.109"
cmd = "/usr/local/bin/geo-ip.pl --short %s" % hostIP
output = Popen(cmd, shell=True, stdout=PIPE).communicate()[0]
## alternate form ##
# cmd = ["/usr/local/bin/geo-ip.pl, "--short", hostIP]
# output = Popen(cmd, stdout=PIPE).communicate()[0]
print output.strip()
# Netherlands
Update
Since I am doing a few things at once on that Popen line, and you are new to python (based on your comments below), I wanted to break down that line a bit for you...
# this call to Popen actually returns a
# Popen object with a number of methods and attributes
# to interact with the process that was just created
p = Popen(cmd, shell=True, stdout=PIPE)
# communicate() is a method of a Popen object which
# allows you to wait for the return output of the pipes
# that you named (or send data to stdin)
# It blocks until data is ready and returns a tuple (stdout, stderr)
stdout, stderr = p.communicate()
# We only wanted the stdout in this case, so we took the first index
output = p.communicate()[0]
# output is a string, and strings have the strip() method to remove
# surrounding whitespace
stripped_output = output.strip()
This could do the trick:
import subprocess
country = subprocess.check_output(
["/usr/local/bin/geo-ip.pl", "--short", "87.215.133.109"])

Categories