Cant use grep in subprocess command

2020-04-16 03:47发布

I'm having a problem with my subprocess command, I like to grep out the lines that match with "Online" line.

def run_command(command):
    p = subprocess.Popen(command,shell=False,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT)
    return iter(p.stdout.readline, b'')

command = 'mosquitto_sub -u example -P example -t ITT/# -v | grep "Online" '.split()
for line in run_command(command):
    print(line)

But I will get an error

Error: Unknown option '|'.



Use 'mosquitto_sub --help' to see usage.

But when running with linux shell

user@server64:~/Pythoniscriptid$ mosquitto_sub -u example -P example  -t ITT/# -v | grep "Online"
ITT/C5/link Online
ITT/IoT/tester55/link Online
ITT/ESP32/TEST/link Online

I also tried shell = True, but with no success, because I will get another error, that dosen't recognize the topic ITT/#

Error: You must specify a topic to subscribe to.



Use 'mosquitto_sub --help' to see usage.

The "possible dublicate" didn't help me at all, So I think I'm having a different problem. I tried to change code to this, put in not getting any return

def run_command(command,command2):
    p1 = subprocess.Popen(command,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
    p2 = subprocess.Popen(command2,stdin=p1.stdout,stdout=subprocess.PIPE)
    return iter(p2.stdout.readline,'')



command = 'mosquitto_sub -u example -P example -t ITT/# -v'.split()
command2 = 'grep Online'.split()

#subprocess.getoutput(command)

for line in run_command(command,command2):
    print(line)

1条回答
唯我独甜
2楼-- · 2020-04-16 03:53

When you split the text, the list will look like

['mosquitto_sub', ..., 'ITT/#', '-v', '|', 'grep', '"Online"']

When you pass this list to subprocess.Popen, a literal '|' will be one of the arguments to mosquitto_sub.

If you use shell=True, you must escape any special characters like # in the command, for instance with double quotes:

import subprocess
command = 'echo -e "ITT/#\\ni am Online\\nbar Online\\nbaz" | grep "Online" '
p = subprocess.Popen(
    command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in iter(p.stdout.readline, b''):
    print(line)

Alternatively, connect the pipes as you wrote, but make sure to iterate until b'', not u'':

import subprocess

def run_command(command, command2):
    p1 = subprocess.Popen(command,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
    p2 = subprocess.Popen(command2,stdin=p1.stdout,stdout=subprocess.PIPE)
    return iter(p2.stdout.readline, b'')

command = ['echo', '-e', 'ITT/#\\ni am Online\\nbar Online\\nbaz']
command2 = 'grep Online'.split()

for line in run_command(command,command2):
    print(line)
查看更多
登录 后发表回答