Запустите сценарий оболочки 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)

...

В этом случае входное имя файла не нужно заключать в кавычки, поскольку оно не интерпретируется оболочкой.

Другие вопросы по тегам