Python子进程call()不执行shell命令

时间:2019-07-04 19:44:22

标签: python subprocess youtube-dl

我正在尝试制作一个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 :(得分:0)

cd; cd Desktop; youtube-dl "https://www.youtube.com/watch?v=b91ovTKCZGU"不是单个命令;这是三个单独命令的列表(由;分隔)。

subprocess.call(cmd, ..., shell=True)实际上与

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

这几乎不是您想要的。相反,只需传递一个字符串,然后让Shell解析它即可。

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"))

答案 1 :(得分:0)

我将用一个例子来回答这个问题:

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

该列表的第一个元素是shell命令(echo $0 $2),其余元素是该命令可以选择使用的位置参数($0$1,.. )。

在您的示例中,您正在创建一个仅运行cd;命令的子外壳。位置参数将被忽略。有关详细信息,请参见Popenbash文档。

如注释中所述,您应该使命令成为字符串(而不是列表)。