snmpwalk with python scrypt - python

I tried to build a python script to get temperature from snmp sensor.
If I use this command line with a Linux terminal
snmpwalk 10.100.2.21 -On -v 1 -c public .1.3.6.1.4.1.28507.14.1.3.1.1.2.2
Output is correct :
.1.3.6.1.4.1.28507.14.1.3.1.1.2.2 = INTEGER: 225
In fact it return temperature :-) 22.5 °C
But I must use a python script :
#!/usr/bin/python
# -*- coding: latin-1 -*-
import netsnmp
#oid = '.1.3.6.1.4.1.28507.14.1.3.1.1.2.2'
oid = netsnmp.VarList(netsnmp.Varbind('.1.3.6.1.4.1.28507.14.1.3.1.1.2.2'))
print ("Hello !!!")
res = netsnmp.snmpwalk(oid, Version=1, DestHost='10.100.2.21', Community='public')
print res
I don't know why, my script return only :
"()"
Have you some ides ?
thanks

The constructs for netsnmp don't work that way. As far as I know, you need to open a snmp session before making queries.
I usually do:
session=netsnmp.Session(DestHost=myip, Version=2, Community='public', RemotePort=161)
Then you can check if you got a proper session:
if session:
continue
else:
print sys.exc_info()
exit(1)
Finally:
myoid=netsnmp.VarList('.1.3.6.1.4.1.28507.14.1.3.1.1.2.2')
res=snmp.walk(myoid)
for i in res:
print i
I am using a for loop, because you chose snmp.walk(), that could potentially return many rows of values. You could use snmp.get() instead

Related

python - Using a variable as part of a class method/function

I'm sure this is a simple problem, but I'm an amateur so here i am.
Trying to use the obd python library to communicate with my vehicle. I have a bluetooth OBDII adapter and on it's own i can send single commands as outlined in the basic usage section of the readme and get responses.
My problem is that i have a list of commands that i want to send. I'm trying to use a for loop to go through each command and print the responses on screen.
import os
import time
import obd
def clear_Screen():
os.system('cls' if os.name == 'nt' else 'clear')
connection = obd.OBD("COM7")
pids = [ 'RPM' , 'ENGINE_LOAD' , 'COOLANT_TEMP' , 'RUN_TIME' ]
try:
while True:
time.sleep(1)
clear_Screen()
for i in pids:
cmd = "obd.commands." + i
response = connection.query(cmd)
print i , ": " , (response.value)
except KeyboardInterrupt:
exit()
there's a problem with how I'm building the cmd variable because the response i get from each query is that the command isn't supported but i know they are.
if i print cmd instead of trying to use the command.query(cmd) it prints exactly like it would be if i specified it i.e. obd.commands.RPM so I don't understand why this doesn't work.
In your question you stated:
there's a problem with how I'm building the cmd variable
Indeed, in your way, cmd is only a string. So instead if you want the actual evaluated attitude, you should use getattr instead:
cmd = getattr(obd.commands,i)
eval() and exec() are both unsafe so you should never use those.
Try wrapping what you're assigning to cmd in eval():
cmd = eval("obd.commands." + i)

Python - How to find UUID of computer and set as variable

I have been looking all over the internet for a way to find a way to get UUID for a computer and set it as a variable in python.
Some of the ways I tried doing didn't work.
Original idea:
import os
x = os.system("wmic diskdrive get serialnumber")
print(x)
However this does not work, and only returns 0.
I am wondering if their is a way i can find a unique Harddrive ID or any other type of identifier in python.
The os.system function returns the exit code of the executed command, not the standard output of it.
According to Python official documentation:
On Unix, the return value is the exit status of the process encoded in the format specified for wait().
On Windows, the return value is that returned by the system shell
after running command.
To get the output as you want, the recommended approach is to use some of the functions defined in the subprocess module. Your scenario is pretty simple, so subprocess.check_output works just fine for it.
You just need to replace the code you posted code with this instead:
import subprocess
x = subprocess.check_output('wmic csproduct get UUID')
print(x)
If the aim is to get the serial number of the HDD, then one can do:
In Linux (replace /dev/sda with the block disk identifier for which you want the info):
>>> import os
>>> os.popen("hdparm -I /dev/sda | grep 'Serial Number'").read().split()[-1]
In Windows:
>>> import os
>>> os.popen("wmic diskdrive get serialnumber").read().split()[-1]
for windows i do work with this one and it works perfectly:
import subprocess
UUID = str(subprocess.check_output('wmic csproduct get UUID'),'utf-8').split('\n')[1].strip()
print(UUID)
For windows:
import wmi
import os
def get_serial_number_of_system_physical_disk():
c = wmi.WMI()
logical_disk = c.Win32_LogicalDisk(Caption=os.getenv("SystemDrive"))[0]
partition = logical_disk.associators()[1]
physical_disc = partition.associators()[0]
return physical_disc.SerialNumber
For Linux try this:
def get_uuid():
dmidecode = subprocess.Popen(['dmidecode'],
stdout=subprocess.PIPE,
bufsize=1,
universal_newlines=True
)
while True:
line = dmidecode.stdout.readline()
if "UUID:" in str(line):
uuid = str(line).split("UUID:", 1)[1].split()[0]
return uuid
if not line:
break
my_uuid = get_uuid()
print("My ID:", my_uuid)

Open a Python port from Erlang: no reply messages

Based on Chapter 12 of the OTP in Action book and Cesarini's book I wrote this Erlang code:
Erlang:
p(Param) ->
?DBG("Starting~n", []),
Cmd = "python test.py",
Port = open_port({spawn,Cmd}, [stream,{line, 1024}, exit_status]),
?DBG("Opened the port: ~w~n", [Port]),
Payload = term_to_binary(list_to_binary(integer_to_list(Param))),
erlang:port_command(Port, Payload),
?DBG("Sent command to port: ~w~n", [Payload]),
?DBG("Ready to receive results for command: ~w~n", [Payload]),
receive
{Port, {data, Data}} ->
?DBG("Received data: ~w~n", [Data]),
{result, Text} = binary_to_term(Data),
Blah = binary_to_list(Text),
io:format("~p~n", [Blah]);
Other ->
io:format("Unexpected data: ~p~n", [Other])
end.
Python:
import sys
def main():
while True:
line = sys.stdin.readline().strip()
if line == "stop-good":
return 0
elif line == "stop-bad":
return 1
sys.stdout.write("Python got ")
sys.stdout.write(line)
sys.stdout.write("\n")
sys.stdout.flush()
if __name__ == "__main__":
sys.exit(main())
The Erlang code suspends at the recieve clause - it never gets any message.
I have also checked Python from a regular Linux shell - it prints out every user input (1 - "Python got 1").
Where is the mistake here? Why doesn't my Erlang code get anything back?
There are two points:
make sure that Python does not buffer your output, try running python -u in open_port
using term_to_binary/1 and binary_to_term/1 won't work, since they assume that Python is able to encode/decode Erlang External Term Format, which does not seem to be the case. If you want to go this route, check out ErlPort
Does your Param contain the command limiter for Python? (in this case I assume newline, "\n"). Also, list_to_binary/1 and then a term_to_binary/1 feels kinda wrong. term_to_binary/1 directly (including the newline) should be sufficient.

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

Call the Python interactive interpreter from within a Python script

Is there any way to start up the Python interpreter from within a script , in a manner similar to just using python -i so that the objects/namespace, etc. from the current script are retained? The reason for not using python -i is that the script initializes a connection to an XML-RPC server, and I need to be able to stop the entire program if there's an error. I can't loop until there's valid input because apparently, I can't do something like this:
#!/usr/bin/python -i
# -*- coding: utf-8 -*-
import xmlrpclib
# Create an object to represent our server.
server_url = str(raw_input("Server: "))
while not server = xmlrpclib.Server(server_url):
print 'Unable to connect to server. Please try again'
else:
print 'Xmlrpclib.Server object `__main__.server\' of URL `', server_url, "' created"
break
# Python interpreter starts...
because:
% chmod u+x ./rpcclient.py
% ./rpclient.py
Traceback (most recent call last):
File "./rpcclient.py", line 8
while not server = xmlrpclib.Server(server_url):
^
SyntaxError: invalid syntax
>>>
Unfortunately, python -i starts the interpreter just after it prints out the traceback, so I somehow have to call the interactive interpreter - replacing the execution of the script so it retains the server connection - from within the script
Have you tried reading the error message? :)
= is assignment, you want the comparison operator == instead.
Well, I finally got it to work.
Basically, I put the entire try/except/else clause in a while True: loop, with the else suite being a break statement and the end of the except suite being a continue statement. The result is that it now continually loops if the user puts in an address that doesn't have a fully compliant XML-RPC2 server listening. Here's how it turned out:
#!/usr/bin/python -i
# -*- coding: utf-8 -*-
import xmlrpclib, socket
from sys import exit
# Create an object to represent our server.
#server = xmlrpclib.Server(server_url) and print 'Xmlrpclib.Server object `__main__.server\' of URL `', server_url, "' created"
server_url = str(raw_input("Server: "))
server = xmlrpclib.ServerProxy(server_url)
while True:
try:
server.system.listMethods()
except xmlrpclib.ProtocolError, socket.error:
print 'Unable to connect to server. Please try again'
server_url = str(raw_input("Server: "))
server = xmlrpclib.ServerProxy(server_url)
continue
except EOFError:
exit(1)
else:
break
print 'Xmlrpclib.Server object `__main__.server\' of URL `', server_url, "' created"
# Python interpreter starts...
Thank you very much!
...and I have to wait another day to accept this...

Categories

Resources