Python Subprocess Grep
I think you're running up against two problems:
This call:
p = subprocess.Popen(['grep', "%s *.log"%userid]...
will not work as expected without
shell=True
because the list of arguments are being passed directly toos.execvp
, which requires each item to be a single string representing an argument. You've squished two separate arguments together into a single string (in other words, grep is interpreting "foo12 *.log
" as the pattern to search, and not pattern+file list).You can fix this by saying:
p = subprocess.Popen(['grep', userid, '*.log']...)
The second issue is that, again without
shell=True
,execvp
doesn't know what you mean by*.log
and passes it directly along to grep, without going through the shell's wildcard expansion mechanism. If you don't want to useshell=True
, you can instead do something like:import glob
args = ['grep', userid]
args.extend(glob.glob('*.log')
p = subprocess.Popen(args, ...)
run linux grep command from python subprocess
This has been gone over many, many times before; but here is a simple pure Python replacement for the inefficient postprocessing.
from subprocess import Popen, PIPE
eth1 = subprocess.Popen(['/sbin/ifconfig', 'eth1'], stdout=PIPE)
out, err = eth1.communicate()
for line in out.split('\n'):
line = line.lstrip()
if line.startswith('inet addr:'):
ip = line.split()[1][5:]
Cant use grep in subprocess command
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)
Using the subprocess module to grep with the | character
The result of command.split()
contains quotes which should no longer be there. That's why Python provides shlex.split
, but it's also not hard to understand how to split the command manually, though obviously you need to understand the role of the quotes in the shell, and how basically you need to remove them when there is no shell.
command = 'grep "one\|three" ./file.txt'
results1 = subprocess.check_output(['grep', r'one\|three', './file.txt'])
results2 = subprocess.check_output(shlex.split(command))
results3 = subprocess.check_output(command, shell=True) # better avoid
Quotes tell the shell to not perform whitespace tokenization and/or wildcard expansion on a value, but when there is no shell, you should simply provide a string instead where the shell allowed or even required you to use a quoted string.
Python subprocess library: Running grep command from Python
On UNIX, specifying shell=True
will cause the first argument to be treated as the command to execute, with all subsequent arguments treated as arguments to the shell itself. Thus, the >
won't have any effect (since with /bin/sh -c
, all arguments after the command are ignored).
Therefore, you should actually use
catdoc_cmd = ['catdoc -w "%s" > testing.txt' % name]
A better solution, though, would probably be to just read the text out of the subprocess' stdout
, and process it using re
or Python string operations:
catdoc_cmd = ['catdoc', '-w' , name]
catdoc_process = subprocess.Popen(catdoc_cmd, stdout=subprocess.PIPE,stderr=subprocess.PIPE)
for line in catdoc_process.stdout:
if keyword in line:
print line.strip()
python shell command pipes grep no results
Your script fails because of the quotes around DNS=
.
You can use shell=True
to make the script work:
dnslineprocess = subprocess.Popen(getdnsline, stdin=userdataprocess.stdout, stdout=subprocess.PIPE, shell=True)
Source: Passing double quote shell commands in python to subprocess.Popen()?
Using subprocess to get output of grep piped through head -1
The docs show you how to replace shell piping using Popen:
from subprocess import PIPE, Popen
p1 = Popen(['grep', '-n', 'some phrase', '{some file path}'],stdout=PIPE)
p2 = Popen(['head', '-1'], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
out,err = output = p2.communicate()
How to run ps cax | grep something in Python?
See Replacing shell pipeline:
import subprocess
proc1 = subprocess.Popen(['ps', 'cax'], stdout=subprocess.PIPE)
proc2 = subprocess.Popen(['grep', 'python'], stdin=proc1.stdout,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
proc1.stdout.close() # Allow proc1 to receive a SIGPIPE if proc2 exits.
out, err = proc2.communicate()
print('out: {0}'.format(out))
print('err: {0}'.format(err))
PS. Using shell=True
can be dangerous. See for example the warning in the docs.
There is also the sh module which can make subprocess scripting in Python a lot more pleasant:
import sh
print(sh.grep(sh.ps("cax"), 'something'))
Related Topics
How to Embed Matplotlib in Pyqt - for Dummies
Multiprocessing: How to Share a Dict Among Multiple Processes
Drf: Simple Foreign Key Assignment with Nested Serializers
Downloading a Picture via Urllib and Python
What Is the Id( ) Function Used For
Django Multivaluedictkeyerror Error, How to Deal with It
Accessing Elements of Python Dictionary by Index
Add a Prefix to All Flask Routes
How to Enable Cors on Django Rest Framework
Output to the Same Line Overwriting Previous Output
Order' of Unordered Python Sets
Import CSV File as a Pandas Dataframe
Can't Set Attributes on Instance of "Object" Class
Slice 2D Array into Smaller 2D Arrays