user2921139
user2921139

Reputation: 1789

How to split up the command here for using subprocess.Popen()

ip = subprocess.Popen(["/sbin/ifconfig $(/sbin/route | awk '/default/ {print $8}') | grep \"inet addr\" | awk -F: '{print $2}' | awk \'{print $1}\'"], stdout=subprocess.PIPE)

I am not sure where to put the commas to separate them to use this command using subprocess.Popen. Does anyone know?

Upvotes: 0

Views: 3317

Answers (3)

xscorp7
xscorp7

Reputation: 311

Quoting the official documentation of subprocess.Popen here

It may not be obvious how to break a shell command into a sequence of arguments, especially in complex cases. shlex.split() can illustrate how to determine the correct tokenization for args:

import shlex, subprocess
command_line = input()

args = shlex.split(command_line)
print(args)

p = subprocess.Popen(args) # Success!

shlex is included in standard library so you need not to install it.

Writing it in a single line like str.split() should look like:

import shlex
import subprocess 

command = "ls -l"
proc = subprocess.Popen(shlex.split(command) , stdout = subprocess.PIPE , stderr = subprocess.PIPE)
output , errors = proc.communicate()
print(output , errors)

Upvotes: 1

tdelaney
tdelaney

Reputation: 77367

You are using shell features (the pipe) so instead of splitting the command, you should pass it as a single string (not a list) with shell=True

ip = subprocess.Popen("/sbin/ifconfig $(/sbin/route | awk '/default/ {print $8}') | grep \"inet addr\" | awk -F: '{print $2}' | awk \'{print $1}\'",
    shell=True,
    stdout=subprocess.PIPE)

Upvotes: 4

ErikR
ErikR

Reputation: 52049

Here's what I would recommend.

Create a file with this contents - call it 'route-info' and make it executable:

#!/bin/sh

/sbin/ifconfig $(/sbin/route | awk '/default/ {print $8}') |
    grep "inet addr" |
    awk -F: '{print $2}' |
    awk '{print $1}'

In your python program, use:

ip = subprocess.Popen(["/path/to/route-info"], stdout=subprocess.PIPE)

Then you don't have to worry about quoting characters and you can independently test the route-info script to make sure it is working correctly.

The script route-info doesn't take any command line arguments, but if it did this is how you would pass them:

ip = subprocess.Popen(["/path/to/route-info", arg1, arg2, ...], stdout=subprocess.PIPE)

Upvotes: 0

Related Questions