Запустите сценарий оболочки Linux, используя файл, вставленный пользователем в Python
Я пытаюсь запустить команду ffprobe, используя предварительно определенный пользователем входной файл в Python. И затем я буду использовать сгенерированный файл этой командой, чтобы сообщить о некоторых параметрах в более организованном виде. Мой код:
import subprocess
import json
cmd = "ffprobe -v quiet -print_format -show_format -show_streams /path/to/input/file.mp4 > output.json"
subprocess.call(cmd.split())
with open('output.json') as json_data:
data = json.load(json_data)
json_data.close()
d = float((data["streams"][0]["duration"]))
t = (data["streams"][0]["time_base"])
fps = [float(x) for x in t.split('/')]
print "==========================General=========================="
print "Name of the File: %s" %(data["format"]["filename"])
print "Duration: %.2f minutes" %(d/60)
print "Frame Rate: %d fps" %fps[1]
print "Bitrate: %.2f Mbps" %(float(data["format"]["bit_rate"])/1000000)
Я думал использовать: input_file = ("Please enter the path to your input file: ")
и затем используйте input_file в команде ffprobe во второй строке моего кода. Но я не уверен, как я могу сделать это в кавычках. Также обратите внимание, что имя файла должно также включать расширение, например input.mp4.
2 ответа
Это должно работать:
#!/usr/bin/env python
import subprocess
import json
input_file = raw_input("Please enter the input file path: ")
returned_data = subprocess.check_output(['ffprobe', '-v', 'quiet', '-print_format', 'json', '-show_format', '-show_streams', input_file])
data = json.loads(returned_data.decode('utf-8'))
Перенаправление оболочки (>
) будет работать только когда shell=True
передается subprocess.call()
, Как правило, вам следует избегать этого, особенно если вы принимаете пользовательский ввод как часть выполняемой команды, и в этом случае вам необходимо убедиться, что пользовательский ввод правильно экранирован, например, с помощью shlex.qutoe()
,
Вместо использования перенаправления в оболочке вы можете открыть файл для записи в python и передать его как stdout
или если вам не нужен файл, который вы можете использовать subprocess.check_output()
вместо subprocess.call()
:
input_filename = raw_input("Please enter the path to your input file: ")
cmd = ['ffprobe', '-v', 'quiet', '-print_format', 'json', '-show_format', '-show_streams',
input_filename]
returned_data = subprocess.check_output(cmd)
data = json.loads(returned_data.decode('utf-8')) # assuming the returned data is utf-8 encoded
...
Или то же самое с использованием файла для записи в:
input_filename = raw_input("Please enter the path to your input file: ")
cmd = ['ffprobe', '-v', 'quiet', '-print_format', 'json', '-show_format', '-show_streams',
input_filename]
with open('output.json', 'wb') as outfile:
subprocess.call(cmd, stdout=outfile)
with open('output.json', 'r') as infile:
data = json.load(infile)
...
В этом случае входное имя файла не нужно заключать в кавычки, поскольку оно не интерпретируется оболочкой.