Python linux script (whois error) - python

I'm trying to create a python script on linux that does a 'whois' command on every connected/connecting IP Address that is parsed from the 'netstat' command.
I am get an error saying "sh: 1: Syntax error: Unterminated quoted string"
and the whois usage options posted below that.
Can anyone explain to me what's wrong the script? I believe it's something to do with the for loop and the way it executes the whois command I just cant seem to find a solution. Below is the script in question:
#!/usr/bin/python
from os import system
answer = [system("netstat -alpntu46 |grep 'ESTABLISHED\|SYN_RECV' | awk '{print $5 }' |cut -d: -f1'")]
for i in answer:
system('whois')
EDIT So my original problem is completely fixed, I'm getting no errors. However, now all the script does is list the IP Addresses and underneath that it lists the whois usage examples:
-h HOST, --host HOST connect to server HOST
-p PORT, --port PORT connect to PORT
-H hide legal disclaimers
--verbose explain what is being done
--help display this help and exit
--version output version information and exit"
So it seems to be running the answer variable but not being able to run the whois command on each address.

Your command string (inside de system() command) has one ' more than needed (at the end of the string). Here it is corrected:
#!/usr/bin/python
from os import system
answer = [system("netstat -alpntu46 |grep 'ESTABLISHED\|SYN_RECV' | awk '{print $5 }' |cut -d: -f1")]
for i in answer:
system('whois')
EDIT (your second question):
When you do for i in answer in python you are looping through all items in your answer, that is correct, however for each IP address you are looping on you are executing only a 'whois' command, without passing any parameters. You should add the parameter to the string, as in:
for i in answer:
system('whois %s' % i)
that is assuming the variable i holds the ip string.

Please check the edit on my first answer (posting this just so you get notified.)

Related

Python Subprocess with double quotes

I've got a Docker Service Log that takes in NiFi Actions and I want to capture only Log Entries that include "Successfully sent" and "Failed to process session" (and nothing more). They should be captured in a directory called "nifi_logs" in the present working directory. I need to do all of this using Python.
This is what I got so far:
docker_log = 'docker service logs nifi | grep -e "Successfully sent" -e "Failed to process session" >> $PWD/nifi_logs/nifi1.log'
subprocess.Popen(docker_log, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
I believe subprocess.Popen() is having difficulty with the double quotes used in the grep, as nifi1.log is completely empty. If the first command looks like the following:
docker_log = 'docker service logs nifi | grep session >> $PWD/nifi_logs/nifi1.log'
The Python code works just fine and captures all log entries with "session" in nifi1.log. As I explained above though, I need to grep for 2 kinds of Log Entires and both include multiple words, meaning I need to use quotes.
If I were to just run this command on the Terminal without Python:
docker service logs nifi | grep -e "Successfully sent" -e "Failed to process session" >> $PWD/nifi_logs/nifi1.log
The log generates the entries just fine, so I know the Docker Service command is written correctly.
I've tried switching the single and double quotes around, I've tried using \" instead of " within the single quotes ... nifi1.log continues to be empty.
I also tried using os.system() instead of subprocess.Popen(), but I run into the same problem (and I believe os.system() is somewhat deprecated).
Any ideas what I'd need to do to change what docker_log equals so that it will properly grep for the 2 search criteria? So you're aware: this question is not asking HOW I generate the log entries (I know what Docker Services I'm looking for, they generate properly), just what I need to do to get Python Subprocess Popen to accept a command with quotes in it.
Thank you for your assistance #David. Looking at your example, I found a solution: I removed stdout=subprocess.PIPE from subprocess.Popen and now it accepts double quotes just fine!
docker_log = 'docker service logs nifi | grep -e "Successfully sent" -e "Failed to process session" >> $PWD/nifi_logs/nifi1.log'
subprocess.Popen(docker_log, shell=True, stderr=subprocess.STDOUT)

Using console commands in python

I am using console commands in python, however, it is not outputting the value I want.
The path is:
#ifconfig -a | grep "HWaddr"
From this command I get:
eth0 Link encap:Ethernet HWaddr 30:9E:D5:C7:1z:EF
eth1 Link encap:Ethernet HWaddr 30:0E:95:97:0A:F0
I need to use console commands to retrieve that value, so this is what I have so far for code:
def getmac():
mac=subprocess.check_output('ifconfig -a | grep "HWaddr"')
print "%s" %(mac)
I basically only want to retrieve the hardware address which is 30:0E:D5:C7:1A:F0. My code above doesn't retrieve that. My question is how do I use console commands to get the value I want.
Thanks in advance.
The most robust and easy way in Linux to get the MAC address is to get it from sysfs, mounted on /sys.
For interface etho, the location would be /sys/class/net/eth0/address; Similarly for eth1, it would be /sys/class/net/eth1/address.
% cat /sys/class/net/eth0/address
74:d4:35:XX:XX:XX
So, you could just read the file in python too:
with open('/sys/class/net/eth0/address') as f:
mac_eth0 = f.read().rstrip()
Quoting from here.
Python 2.5 includes an uuid implementation which (in at least one version) needs the mac address. You can import the mac finding function into your own code easily:
from uuid import getnode as get_mac
mac = get_mac()
The return value is the mac address as 48 bit integer.
import subprocess
def getmac(command):
return subprocess.check_output(command, shell=True)
command = "ifconfig -a | grep HWaddr"
print "%s" %(getmac(command).split()[9])
# or print out the entire list to see which index your HWAddr corresponds to
# print "%s" %(getmac(command).split())
Or as per user heemayl,
command = "cat /sys/class/net/eth1/address"
print "%s" %(getmac(command))
Note:
1. Using shell=True isn't recommended as per Python docs
2. This isn't as efficient compared to the normal ways of reading a file in Python.
You could have also returned
subprocess.check_output(command)
However, in the above case, you might get an OSError or a CalledProcessError(retcode, cmd, output=output) depending on whether you passed your commands as a list, which can be solved if you explicitly mention your python path as per this

Using python subprocess.Popen to set iptables where proto is gre

I'm facing a weird issue. I am trying to do the following in the output chain of my mangle table
iptables -t mangle -D OUTPUT -p gre -d 2.2.2.0/24 -j MARK --set-mark <somemark>
When I execute the above command from shell, it goes though fine and adds above rule to the output chain in the mangle table.
However, when I am trying to achieve the same using the subprocess module, I do not get any error but the rule is not added in the output chain in the mangle table.
Code:
p = subprocess.Popen(["iptables", "-t", "mangle", "-I",
"OUTPUT", "--dst", "2.2.2.0/24",
"-p", "gre", "-j", "MARK",
"--set-mark", "0x04"])
p.wait()
The other thing that is flipping me is that when I change the protocol to tcp/udp/esp it works fine. I face this ONLY when the protocol is gre. I tried using GRE, 47 and gre.
Could anyone please let me know what I am missing?
Just an update the same rule when I add to POSTROUTING chain, it gets added. I am not sure what is so special about adding proto 47 to OUTPUT chain?

How to use python to run a list from one file through another script

Alright, so I am being tasked with a large task of auditing the use of our IPs in my office because we are running low. So I am trying to write a basic script that takes a list of the IPs I need to verify , and tun them against another script that verifies the IP's use. I have it working in Bash, but I want to use Python so that I can make some adjustments the way I like.
So I have a file called "iprange" and I have a perl file a former coworker made that no longer works here, and it takes an IP and checks it, verifies what is using it, and then outputs it back. Here is example of what "works" for me in Bash.
cat iprange | xargs -I % checkIP.pl -s % > ipresults.txt 2>&1
The problem is, This gives me an output that looks like this.
"This IP is free"
"This IP is free"
"This IP is used by XPNSE43525"
There are two problems. 1) There are thousands of IPs, so I need to find a way to have it so it looks more like this.
10.4.8.5
"This IP is free"
OR
checkIP.pl -s 10.4.8.5
"This IP is free"
Since this does not seem possible with bash, I am hoping to get this hammered out with Python. But have no idea how to get python to launch the script and output it the same way I do with bash.
You could always write a small wrapper script that is invoked by xargs and which in turn displays the IP address and then invokes checkIP.pl.
checkIP.sh
#!/usr/bin/env sh
echo -n "$1 : "
checkIP.pl -s $*
Then you can call it like this:
cat iprange | xargs -I % checkIP.sh % > ipresults.txt 2>&1
and expect to see output like this:
10.4.8.5 : This IP is free
10.1.1.1 : This IP is free
192.168.1.1 : This IP is used by XPNSE43525
8.8.8.8 : This IP is used by Google DNS
What #squiguy said is correct. You probably need to modify the PERL script.
grep "This IP is free" checkIP.pl
grep "This IP is used by" checkIP.pl
Find the lines in the file where the lines are on in the script by running a couple of greps
Then assuming the script used 'Getopt::Std qw(getopts);' the variable that the -s' parameter should be attached to is "$opt_s"
Change the lines to
"$opt_s: This IP is free"
"$opt_s: This IP is used by"

Run command using rsh on a remote computer

I am trying to run a python script, and I need to Rsh a command from the script, the command I want to run is : df -Pk|grep "sd\|md"|gawk '{print $2}'
and I do it as -
cmd2='df -Pk|grep \\\"sd\|md\\\"|gawk \'{print $2}\''
process = subprocess.Popen(['rsh',ip,cmd2],stdout=subprocess.PIPE)
output = process.communicate()[0]
However when I do run the script,I get nothing in output.
I am new to python and as far as I know, its a problem with the escape characters.
Any help would be great.
Note:
I have to use Rsh only and cannot use ssh
Thanks
Enclose the command, with proper shell quoting, in triple quote marks:
"""df -Pk|grep "sd\|md"|gawk '{print $2}'"""
See also the Python tutorial's bit on strings.

Categories