Search code examples
pythonpython-2.7zabbix

get output from os.system-Zabbix trapper


With this code I'm sending data to zabbix using trapper:

def zabbix_sender(key, output):
    server = "1.2.2.4"
    hostname = "host"
    cmd = "zabbix_sender -z " + server + " -s " + hostname + " -k " + key +\
            " -o \"" + output +"\""
    print os.system(cmd)

It outputs this to the screen

info from server: "processed: 1; failed: 0; total: 1; seconds spent: 0.000041"
sent: 1; skipped: 0; total: 1

I need to output above to variable so, if failed: 1 I can create error handling.

Currently I'm getting 0 as output when calling this function:

r = zabbix_sender (key,"failed")
                print  r

output:0

Tried with subprocesses:

r=subprocess.check_output(zabbix_sender (key,"failed"),shell=False) 
print r

TypeError:None object is not iterable


Solution

  • The return value from os.system() is not the output from the command. You want to use subprocess.run() instead.

    from subprocess import run, PIPE
    
    def zabbix_sender(key, output):
        server = "1.2.2.4"
        hostname = "host"
        cmd = ["zabbix_sender", "-z", server, "-s",  hostname,
            "-k", key, "-o",  output]
        result = run(cmd, stdout=PIPE, stderr=PIPE
            universal_newlines=True, check=True)
        return result.stdout, result.stderr
    

    Notice also how you don't want quoting around the option argument for -o when you are not using shell=True, and how your original function would print instead of return the result.

    I speculate that the output you want is on stderr, not stdout; but I leave this up to you to establish.

    If zabbix_sender is at all correctly implemented, it will return a non-zero exit code if it fails; you should handle this instead of examine its human-readable output. With check=True an exception will be raised if the called process returns a failure status.

    def zabbix_sender(key, output):
        server = "1.2.2.4"
        hostname = "host"
        try:
            result = run(["zabbix_sender", "-z", server, "-s", hostname,
                "-k", key, "-o", output],
                stdout=PIPE, stderr=PIPE,
                universal_newlines=True, check=True)
             return result.stdout, result.stderr
        except CalledProcessError:
             # your zabbix error handling here
             # then probably
             return None
    

    If you are stuck on Python before 3.5 you can try subprocess.check_output and friends. More information at Running Bash commands in Python.