Subprocess.Popen() Error (No Such File or Directory) When Calling Command with Arguments as a String

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 be True 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



Leave a reply



Submit