Unable to get the gateway IP of wlan interface using python code

Cameron Simpson cs at cskk.id.au
Mon Nov 12 21:00:55 EST 2018


On 12Nov2018 21:17, MRAB <python at mrabarnett.plus.com> wrote:
>On 2018-11-12 19:37, srinivasan wrote:
>>When I use the subprocess I see the below issue:
>>     def get_gateway_ip(self):
[...]
>>         p = subprocess.Popen('ip route show 0.0.0.0/0 dev wlp1s0 | 
>>         cut -d\
>>-f3', stdout=subprocess.PIPE)
[...]
>>root:~/qa/test_library# python3 wifi.py
>>Enabling wifi
>>Verify wifi connectivity
>>True
>>Get gateway wifi ip
>>Traceback (most recent call last):
>>   File "wifi.py", line 134, in <module>
>>     print(m.get_gateway_ip())
>>   File "wifi.py", line 76, in get_gateway_ip
>>     p = subprocess.Popen('ip route show 0.0.0.0/0 dev wlp1s0 | cut -d\
>>-f3', stdout=subprocess.PIPE)
>>   File "/usr/lib/python3.5/subprocess.py", line 676, in __init__
>>     restore_signals, start_new_session)
>>   File "/usr/lib/python3.5/subprocess.py", line 1289, in _execute_child
>>     raise child_exception_type(errno_num, err_msg)
>>FileNotFoundError: [Errno 2] No such file or directory: 'ip route show
>>0.0.0.0/0 dev wlp1s0 | cut -d\\  -f3'
>>root:~/qa/test_library#
>>
>>As I am stuck with this issue from past 2 days, wondering for any 
>>clues
>>
>'Popen' thinks that the string you gave it is the path to a command.
>It's not; it's a command line with arguments.
>You can tell it that the string is a command line by also passing the 
>keyword argument 'shell=True':
>
>p = subprocess.Popen(r'ip route show 0.0.0.0/0 dev wlp1s0 | cut -d\ 
>-f3', stdout=subprocess.PIPE, shell=True)

But as someone (Chris?) mentioned, it is _better_ to use a command path.

Although using shell=True lets you take a shell command you've worked 
out at the command prompt and use it directly in a Popen call, because 
such commands must include shell punctuation and may also include some 
string insertion, they are easy to get subtle wrong, often in ways that 
can be subverted by bad insertion.

I want to repeat Chris' recommendation to run things like the "ip" 
command directly:

  p = subprocess.Popen(['ip', 'route', 'show', '0.0.0.0/0', 'dev', 'wlp1s0'], ...)

because it bypasses the shell entirely and lets you insert any string 
(such as the interface name above) directly.

Then do the logic which the "cut" command is providing directly in 
Python: it is more debuggable and more flexible.

Cheers,
Cameron Simpson <cs at cskk.id.au>



More information about the Python-list mailing list