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

Question:

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?

Asked By: user2921139

||

Answers:

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)
Answered By: ErikR

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)
Answered By: tdelaney

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)
Answered By: xscorp7
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.