subprocess.Popen() error (No such file or directory) when calling command with arguments as a string
You should pass the arguments as a list (recommended):
subprocess.Popen(["wc", "-l", "sorted_list.dat"], stdout=subprocess.PIPE)
Otherwise, you need to pass shell=True
if you want to use the whole "wc -l sorted_list.dat"
string as a command (not recommended, can be a security hazard).
subprocess.Popen("wc -l sorted_list.dat", shell=True, stdout=subprocess.PIPE)
Read more about shell=True
security issues here.
OSError: [Errno 2] No such file or directory while using python subprocess with command and arguments
Use shell=True
if you're passing a string to subprocess.call
.
From docs:
If passing a single string, either
shell
must beTrue
or
else the string must simply name the program to be executed without
specifying any arguments.
subprocess.call(crop, shell=True)
or:
import shlex
subprocess.call(shlex.split(crop))
subprocess.Popen - No such file or directory
rewrite the code as follows
import subprocess
process = subprocess.Popen(['echo', '5'])
command should be a list
OSError: no such file or directory on using subprocess.Popen
You can't run subprocess.Popen as a string like that without add shell=True.
result = subprocess.Popen('ffprobe -i input_video -show_entries format=duration -v quiet -of csv="p=0"', stdout=subprocess.PIPE,stderr=subprocess.STDOUT, shell=True)
If you split the command into a list of args, then you can use the method you used without shell=True. The non-shell method is generally recommended: When to use Shell=True for Python subprocess module
result = subprocess.Popen(['ffprobe', '-i', 'input_video', '-show_entries', 'format=duration', '-v', 'quiet', '-of', 'csv="p=0"'], stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
Python Subprocess Error No Such File or Directory
The command arguments for Popen
should be a sequence of strings.
Try this:
import subprocess
subprocess.Popen(["ffmpeg", "-f", "x11grab",
"-framerate", "60", "-video_size",
"1366x768", "-i", ":0.0", "out.mpg"])
Note that the first string that contains the name of the command should not contain any spaces! If you would use "ffmpeg " (note the space at the end) instead of "ffmpeg" it would fail again with a "no such file or directory" error because there is no command with the name "ffmpeg "!
You could also use shlex
:
import subprocess
import shlex
cmd = "ffmpeg -f x11grab -framerate 60 -video_size 1366x768 -i :0.0 out.mpg"
subprocess.Popen(shlex.split(cmd))
Subprocess command shows FileNotFoundError: [Errno 2] No such file or directory
Your commands are still wrong. If you just want to run these commands like the shell does, the absolutely easiest way to do that is to ... use the shell.
result = subprocess.run('''
# useless cat, but bear with
cat output3.txt |
sed 's/"/ /g' |
grep "shipOption" |
grep -v "getShipMethod" |
cut -d ',' -f2 |
sed 's/"//g' |
sort |
uniq -c |
sort -nr |
head -10
''',
# Probably add these too
check=True,
capture_output=True,
# We are using the shell for piping etc
shell=True)
If you want to remove the shell=True
and manually run all these processes, you have to understand how the shell works. In particular, you need to fix the quoting so that the commands you run have the quotes which remain after the shell has processed the syntactic quotes.
p1 = subprocess.Popen(['cat', 'output3.txt'], stdout=subprocess.PIPE) # still useless
p2 = subprocess.Popen(['sed','s/"/ /g'], stdin=p1.stdout, stdout=subprocess.PIPE)
p3 = subprocess.Popen(['grep', "shipOption"], stdin=p2.stdout,stdout=subprocess.PIPE)
p4 = subprocess.Popen(['grep', '-v', "getShipMethod"], stdin=p3.stdout, stdout=subprocess.PIPE)
p5 = subprocess.Popen(['cut', '-d', ',', '-f2'], stdin=p4.stdout, stdout=subprocess.PIPE)
p6 = subprocess.Popen(['sed', 's/"//g'],stdin=p5.stdout, stdout=subprocess.PIPE)
p7 = subprocess.Popen(['sort'], stdin=p6.stdout, stdout=subprocess.PIPE)
p8 = subprocess.Popen(['uniq', '-c'], stdin=p7.stdout, stdout=subprocess.PIPE)
p9 = subprocess.Popen(['sort', '-nr'], stdin=p8.stdout, stdout=subprocess.PIPE)
p0 = subprocess.Popen(['head', '-10'], stdin=p9.stdout, stdout=subprocess.PIPE)
Notice in particular how the arguments to sed
and grep
have their outer quotes removed, and how we removed shell=True
everywhere. As a rule of thumb, if the first argument to Popen
(or other subprocess
methods) is a list, you should not use shell=True
, and vice versa. (There are situations where you can pass a list to shell=True
but ... let's not even begin to go there.)
All of this seems rather moot, though, since Python can eminently well do all of these things.
from collections import Counter
counts = Counter()
with open('output3.txt', 'r', encoding='utf-8') as lines:
for line in lines:
line = line.rstrip('\n').replace('"', ' ')
if "shipOption" in line and "getShipMethod" not in line:
field = line.split(',')[1].replace('"', '')
counts[field] += 1
print(counts.most_common(10))
Probably you would want to put the rstrip
and replace
inside the if
to avoid unnecessary work. The same refactoring could be done to the shell pipeline, of course.
Related Topics
How to Create a Datetime in Python from Milliseconds
Add Column to Dataframe with Constant Value
Python - Rolling Functions for Groupby Object
Pandas: Looking Up the List of Sheets in an Excel File
Django Submit Two Different Forms with One Submit Button
Add Sum of Values of Two Lists into New List
Python Ctypes Issue on Different Oses
Iterate a List with Indexes in Python
Use .Corr to Get the Correlation Between Two Columns
Differences Between Numpy.Random and Random.Random in Python
Why Isn't Python Very Good for Functional Programming
How to Apply Gradient Clipping in Tensorflow
Differencebetween Pylab and Pyplot
What Is the Recommended Way of Allocating Memory for a Typed Memory View
Python Read JSON File and Modify
Python Numpy/Scipy Curve Fitting
Cannot Return Results from Stored Procedure Using Python Cursor