Using console commands in python - 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

Related

Create a python script and use grep command?

I'm creating a script wherein I want to grep all a specific address based on the list?
before what I usually do run a grep 1 by 1 using this command ex. grep "192.168.1.1" *
Now I'm creating a script.
Example of the output.
print(i) output.
192.168.1.0
192.168.1.1
192.168.1.2
192.168.1.3
but how to call the list and put into loop under os.system so I can grep all the list?
Thanks
import ipaddress
import os
#Ask the ipaddress in CIDR format
ip = input("Enter the IP/CIDR: ")
os.chdir("/rs/configs")
print("pwd=%s" % os.getcwd())
for i in ipaddress.IPv4Network(ip):
print (i)
os.system("grep $i '*') #<--Grep from list and run to all directory *
The basic answer is "grep {} '*'".format(ip) but there are a number of problems with your script.
To improve usability, I would suggest you change the script so it accepts a list of IP addresses as command-line arguments instead.
You want to avoid os.system() in favor of subprocess.run()
There is no need to cd to the directory which contains the files you want to examine.
Finally, there is no need really to run grep, as Python itself is quite capable of searching a set of files.
import ipaddress
import glob
ips = set([ipaddress.IPv4Network(ip) for ip in sys.argv[1:]])
for file in glob.glob('/rs/configs/*'):
with open(file) as lines:
for line in lines:
if any(x in line for x in ips):
print("{0}:{1}".format(file, line))
This should be significantly more efficient by way of examining the files only once.
It's not entirely clear what you hope to gain by using ipaddress here if you are grepping for individual IP addresses anyway.

How do I find the result of a find, in this script for sending by email

How do I find the result of a find, in this script for sending by email ??
I've tried this way
How do I put the result within the email.
The result of find
mailx -s "result of find " support#systems.com
You need to "pipe" it.
find /bin | mailx -s "result of find in /bin" support#systems.com
Pipes allow you to transfer the output of a shell command into input of another command. They are very convenient and widely use in the linux/unix systems.
You should look into it.
Something like this would meet your needs:
find /path_to_examine -type f -print | mailx -s "Find Results" support#systems.com
mailx expects its input from STDIN; either read from the initiating terminal (and terminated with a control-D sequence); or redirected; or piped. The example chosen uses a pipe. You could also redirect an already created file, thusly:
mailx -s "Find Results" support#systems.com < myresults

Python linux script (whois error)

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.)

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"

Storing value from a parsed ping

I'm working on some code that performs a ping operation from python and extracts only the latency by using awk. This is currently what I have:
from os import system
l = system("ping -c 1 sitename | awk -F = 'FNR==2 {print substr($4,1,length($4)-3)}'")
print l
The system() call works fine, but I get an output in terminal rather than the value storing into l. Basically, an example output I'd get from this particular block of code would be
90.3
0
Why does this happen, and how would I go about actually storing that value into l? This is part of a larger thing I'm working on, so preferably I'd like to keep it in native python.
Use subprocess.check_output if you want to store the output in a variable:
from subprocess import check_output
l = check_output("ping -c 1 sitename | awk -F = 'FNR==2 {print substr($4,1,length($4)-3)}'", shell=True)
print l
Related: Extra zero after executing a python script
os.system() returns the return code of the called command, not the output to stdout.
For detail on how to properly get the command's output (including pre-Python 2.7), see this: Running shell command from Python and capturing the output
BTW I would use Ping Package https://pypi.python.org/pypi/ping
It looks promising
Here is how I store output to a variable.
test=$(ping -c 1 google.com | awk -F"=| " 'NR==2 {print $11}')
echo "$test"
34.9

Categories