Вызов подпроцесса Python () не выполняет команду оболочки - PullRequest
1 голос
/ 04 июля 2019

Я пытаюсь создать программу на python (python 3.6), которая записывает команды на терминал для загрузки определенного видео на YouTube (используя youtube-dl).

Если я захожу на терминал и выполняю следующую команду:

cd; cd Desktop; youtube-dl "https://www.youtube.com/watch?v=b91ovTKCZGU"

Будет загружено видео на мой рабочий стол. Однако, если я выполню приведенный ниже код, который должен выполнять ту же команду на терминале, он не выдаст ошибку, но и не загрузит это видео.

import subprocess                
cmd = ["cd;", "cd", "Desktop;", "youtube-dl", "\"https://www.youtube.com/watch?v=b91ovTKCZGU\""]
print(subprocess.call(cmd, stderr=subprocess.STDOUT,shell=True))

Кажется, что это просто выводит 0. Я не думаю, что существует какая-либо ошибка 0, которая существует (есть ошибки 126 и 127). Так что, если он не выдает ошибку, почему он также не загружает видео?

Обновление: Я исправил приведенный выше код, передав строку, и проверил, что youtube-dl установлен в моем python по умолчанию, а также находится в папке, куда я хочу скачать видео, но все равно выдает ошибку 127, что означает команду «youtube». -dl "не найден.

Ответы [ 2 ]

0 голосов
/ 05 июля 2019

Я отвечу на этом примере:

>>> subprocess.call(["echo $0 $2", "foo", "skipped", "bar"], shell=True)
foo bar
0

Первый элемент списка - это команда оболочки (echo $0 $2), а остальные элементы - это позиционные параметры, которые команда может использовать ($0, $1, ...).

В вашем примере вы создаете подоболочку, которая запускает только команду cd;. Позиционные параметры игнорируются. Подробности см. В документах Popen и bash .

Как отмечено в комментариях, вы должны сделать команду строкой (а не списком).

0 голосов
/ 04 июля 2019

cd; cd Desktop; youtube-dl "https://www.youtube.com/watch?v=b91ovTKCZGU" - не единственная команда; это список (ограниченный ;) из трех отдельных команд.

subprocess.call(cmd, ..., shell=True) фактически совпадает с

subprocess.call(['sh', '-c'] + cmd)

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

subprocess.call('cd; cd Desktop; youtube-dl "https://www.youtube.com/watch?v=b91ovTKCZGU"', shell=True)

Если вы действительно хотите использовать форму списка (что всегда хорошо), используйте параметр cwd вместо запуска cd.

subprocess.call(['youtube-dl', 'https://www.youtube.com/watch?v=b91ovTKCZGU'],
                cwd=os.path.expanduser("~/Desktop"))
...