Join the Stack Overflow Community
Stack Overflow is a community of 6.6 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

The python script runs this command:

return_code = call("iw wlan0 scan | sed -e 's#(on wlan# (on wlan#g' | awk -f scan.awk > scan.txt", shell=True)

I want to proceed in my code only if the command goes well. But the return_code is always "0", even when the command fails.

More precisely the failure is represented by

command failed: Device or resource busy (-16)

How can I "capture" this message and avoid that the program continues? If there's the "command failed" error, I want to repeat the shell command but I don't know how to do that.

share|improve this question
    
docs.python.org/2/library/… – BlackBear Apr 18 '16 at 13:09
    
Check_call() and check_output() don't solve my problem. The execution of the command itself is always successful and therefore the return code is "0". The problem is that the "iw wlan0 scan" can return the command failed message which is a problem for my script because it thinks everything went well when it did not – user6204136 Apr 18 '16 at 13:30
    
Using check_output you can see whether the error message contains the failure message – BlackBear Apr 18 '16 at 13:32
    
Try checking your command directly on shell, like: iw wlan0 scan | sed -e 's#(on wlan# (on wlan#g' | awk -f scan.awk > scan.txt; echo $? – Danilo Muñoz Apr 18 '16 at 13:54
    
The issue is that bash does not propagate errors across pipes. There's a partial solution using named pipes: return_code = call('mkfifo pipe && iw wlan0 scan > pipe', shell=True) The problem is that this will block until you read from the pipe, which means you need threads. Which means you need to pass the status of the threaded call across a thread boundary. I leave that as an exercise to someone else. – Andrea Reina Apr 18 '16 at 15:29

You could do something like this:

import subprocess

cmd = "iw wlan0 scan | sed -e 's#(on wlan# (on wlan#g' | awk -f scan.awk > scan.txt"
cmd_err = "command failed: Device or resource busy"
output = cmd_err

while cmd_err in output:
    # maybe add a delay and a "max no. of retries" counter
    output = subprocess.check_output(cmd, shell=True)

# success - rest of your code

I can't write shell=True without mentioning that using it comes with certain security risks (code/command injection). Avoid using it when you can and never use it for untrusted input.

share|improve this answer

This depends on which part of your command you want the results of. What you should be getting is (I think - learning this stuff myself right now) the return code of "awk -f scan.awk > scan.txt".

I suspect that what you really want is to base whether to continue with the sed/awk component on the results of "iw wlan0 scan", so separate this into 2 sections to do the scan, check the result, and continue if return code is 0/output is not "command failed: Device or resource busy".

I'd love to provide a syntactically and programmatically perfect example of how to do that but I'm just learning too :)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.