How to provide inputfilefile(-iL) option in python nmap? - python

In nmap command line, we can provide list of hosts in file and the file can be provided as an input using -iL parameter. I am not sure how to replicate the same function using python nmap. Python nmap documentation is not covering all examples. So requiring help in it.

You can use the -iL option as given below. It worked for me.
nm.scan(arguments='-iL /tmp/hosts.txt')
Full program given below
import sys
import os
import nmap # import nmap.py module
try:
nm = nmap.PortScanner() # instantiate nmap.PortScanner object
except nmap.PortScannerError:
print('Nmap not found', sys.exc_info()[0])
sys.exit(1)
except:
print("Unexpected error:", sys.exc_info()[0])
sys.exit(1)
nm.scan(arguments='-iL /tmp/hosts.txt')
for host in nm.all_hosts():
print('----------------------------------------------------')
print('Host : %s (%s)' % (host, nm[host].hostname()))
print('State : {0}'.format(nm[host].state()))
# print result as CSV
print(nm.csv())

I don't think that python-nmap supports target lists out of the box. You will probably need to use python to open and parse the list yourself, and then execute the scans in a loop. I will probably look something like this:
import nmap
nm = nmap.PortScanner()
port_range='22'
with open('./path/to/list', 'r') as targets:
for target in targets:
nm.scan(target, port_range)
# Do something with results

Related

how to use netstat -nb in python

I want to use netstat -nb in python but every code that i write i get the same msg: "The requested operation requires elevation."
The last code that i try is
import os
output_command = os.popen("netstat -nb").readlines()
and i try also
import subprocess
program_list = subprocess.run(["netstat", "-nb"], stdout=subprocess.PIPE).stdout.decode("utf-8")
program_list = program_list.split("\r\n")
import os
a=os.popen('netstat -nb').read()
print("\n Connections ",a )
try this, it's working!

python - print output

I have created this below script and it works fine. But the output is not friendly (see below). I want the first line to display only the hostname and IP and remove (,'[], please suggest
('testhostname', [], ['10.10.10.10'])
cannot resolve hostname: 10.10.10.11
import socket
pfile = open ('C:\\Python27\\scripts\\test.txt')
while True:
IP = pfile.readline()
if not IP:
break
try:
host = socket.gethostbyaddr(IP.rstrip())
print host
except socket.herror, err:
print "cannot resolve hostname: ", IP
pfile.close()
Rather than printing all of the host tuple that is returned by gethostbyaddr, I suggest unpacking into separate variables that you can then print as you see fit:
hostname, alias_list, ip_addr_list = gethostbyaddr(IP.rstrip())
print hostname, ip_addr_list # or ip_addr_list[0] if you only want the one IP
If you want more control over the formatting, I suggest using the str.format method:
print "hostname: {}, IP(s): {}".format(hostname, ", ".join(ip_addr_list))
Also, a few other code suggestions (not directly related to your main question):
Use a with statement rather than manually opening and closing your file.
Iterate on the file object directly (with for IP in pfile:), rather than using while True: and calling pfile.readline() each time through.
Use the syntax except socek.herror as err rather than the older form with commas (which is deprecated in Python 2 and no longer exists in Python 3).

python argparse: use arguments as values for a list

I've google'd quite a bit, and read the argparse documentation that I think suggests using something with vars(). I get the Namespace violation as expected, I just cant figure out the path around this issue.
Essentially, I would like to take an argparse multi-value argument and create a list from those values so I can run a for-loop through them. This is to interface with our VNX array to reset the data snapshot on all the Developer environments.
When I run the command I can see the argparse is getting the values correctly, but its throwing the Namespace exception and not actually using the values for the argument.
Much appreciation for any guidance, even a link to some better docs that will explain my problem better. I know the issue, and how I want to fix it, I'm just not sure what to even read(or google) to get around this syntax-wise?
This is what I get when i run the code:
[root#robot.lipsum.com tmp]# ./envrestore.py -e dev1 dev2 dev3
Namespace(myenv=['dev1', 'dev2', 'dev3'])
Traceback (most recent call last): File "./envrestore.py", line 43, in
run_create_snap() File "./envrestore.py", line 36, in run_create_snap
for e in myenv: TypeError: 'Namespace' object is not iterable
[root#robot.lipsum.com tmp]#
#!/usr/bin/env python
import pexpect, sys, datetime, argparse, time
from fabric.api import *
parser = argparse.ArgumentParser()
parser.add_argument('-e', '--myenv', nargs='*', type=str)
print parser.parse_args()
array = "vnx.lipsum.com"
seckey = "/opt/Navisphere/blah"
myenv = parser.parse_args()
dbhosts = ['mongo01', 'mysql01']
# !! DO NOT CHANGE IDs !!
lunpnum = "0000000"
mongo_plunid = "3"
mysql_plunid = "4"
def delete_snap(env=myenv, host=dbhosts):
child = pexpect.spawn('naviseccli -secfilepath %s -h %s snap -destroy -id %s-%s-snap' % (seckey, array, host, env))
print child
child.logfile = sys.stdout
child.expect('Are you sure you want to perform this operation\?\(y\/n\):')
child.sendline('n')
def create_snap(env=myenv, host=dbhosts, lunid=''):
print "naviseccli -secfilepath %s -h %s snap -create -res %s -name %s-%s-snap -allowReadWrite yes" % (seckey, array, lunid, host, env)
def run_delete_snap():
for e in myenv:
for h in dbhosts:
delete_snap(env=e, host=h)
def run_create_snap():
for e in myenv:
for h in dbhosts:
if "mysql" in h:
create_snap(env=e, host=h, lunid=mysql_plunid)
elif "mongo" in h:
create_snap(env=e, host=h, lunid=mongo_plunid)
run_create_snap()
I believe the problem is in what you are passing as myenv:
myenv = parser.parse_args()
I think you mean
myenv = parser.parse_args().myenv
Cheers!
myenv is the argparse.Namespace instance itself. To get the values in the option named myenv, use myenv.myenv.
for e in myenv.myenv:
print(e)
Or, to make the code clearer, name the Namespace something else:
args = parser.parse_args()
for e in args.myenv:
...

Appending the pid number to unix filename using python

In shell script I create a filename with $$ extension like filename.$$ to append the pid no. I want to acheive the same in python.
How to create a filename.$$ in python ?
try:
os.remove('/tmp/update_pid.ksh')
except OSError:
pass
try:
os.remove('/tmp/rollbackfile_pid.ksh')
except OSError:
pass
fo = open('/tmp/update_pid.ksh','a')
fi = open('/tmp/rollback_pid.ksh','a')
In place of "pid" I want the pid number.
Thanks !!!
Like this:
os.remove('/tmp/update_%d.ksh' % os.getpid())

How to get a variable from the shell in python?

I'm writing a script that needs to take advantage of a Java daemon via the local dbus of the linux machines it will run on. This daemon in particular will return an array of tuples which I want so that I can parse through/use the information in later in my code. I want this code to take this value from multiple machines at once, but the problem is the only way I see to really take return/exit values from a terminal which I am ssh'ed into is by parsing stdout's output. I don't want to do this, I'd much prefer to get the actual variable. Right now I have this:
import os
message = "import dbus, sys\nbus=dbus.SystemBus()\nremote_object=bus.get_object('daemon.location', '/daemon')\ncontroller=dbus.Interface(remote_object, 'daemon.path')\nsys.exit(controller.getValue())"
x = os.system('echo \-e "%s" \| ssh %s python' %(message, ip))
In this example when I run "controller.getValue()" it returns an array of tuples. I'm trying to figure out a way to get that array. When using something like popen it pipes the output in stdout into a file and returns it to you, that way you get a string equivalent of the array. What I'm trying to figure out is how to get the actual array. As if to pass the variable returned when exiting the ssh tty into my code. Any ideas?
You can't avoid serialization if there is no shared memory. There are only bytes on the wire.
You could use a library that hides it from you e.g., with execnet module:
#!/usr/bin/env python
import execnet
gw = execnet.makegateway("ssh=user#host")
channel = gw.remote_exec("""
import dbus, sys
bus = dbus.SystemBus()
remote_object = bus.get_object('daemon.location', '/daemon')
controller = dbus.Interface(remote_object, 'daemon.path')
channel.send(controller.getValue())
""")
tuple_ = channel.receive()
print tuple_
print tuple_[0]
But it easy to parse simple tuple values yourself using ast.literal_eval() from stdlib:
#fabfile.py
import ast
from fabric.api import run
def getcontroller():
"""Return controller value."""
cmd = """
import dbus, sys
bus = dbus.SystemBus()
remote_object = bus.get_object('daemon.location', '/daemon')
controller = dbus.Interface(remote_object, 'daemon.path')
print repr(controller.getValue())
""" #NOTE: you must escape all quotation marks
output = run('python -c "%s"' % cmd)
tuple_ = ast.literal_eval(output)
print tuple_[0]
Example: $ fab getcontroller -H user#host
Here I've used fabric to run the command on remote host.
You could use JSON as a serialization format if the other end doesn't produce Python literals:
>>> import json
>>> t = (1, "a")
>>> json.dumps(t)
'[1, "a"]'
>>> json.loads(_)
[1, u'a']
>>>
Why not use popen?
lines = os.popen("your command here").readlines()
If you just want a shell variable then you could do this
$ FOO="myFOO"
$ export FOO
$ cat x.py
#!/usr/bin/python
import os
print os.environ['FOO']
$ ./x.py
myFOO
$
If you want the return code of a program:
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, e:
print >>sys.stderr, "Execution failed:", e
If you could probably explain you requirement a little better, you might get better help

Categories

Resources