OSError: [Errno 2] 在 Django 中使用 python 子进程时没有这样的文件或目录

Posted

技术标签:

【中文标题】OSError: [Errno 2] 在 Django 中使用 python 子进程时没有这样的文件或目录【英文标题】:OSError: [Errno 2] No such file or directory while using python subprocess in Django 【发布时间】:2013-09-28 13:23:31 【问题描述】:

我正在尝试运行一个程序以使用subprocess.call() 在 Python 代码中进行一些系统调用,这会引发以下错误:

Traceback (most recent call last):
      File "<console>", line 1, in <module>
      File "/usr/lib/python2.7/subprocess.py", line 493, in call
      return Popen(*popenargs, **kwargs).wait()
      File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
      File "/usr/lib/python2.7/subprocess.py", line 1249, in _execute_child
      raise child_exception
      OSError: [Errno 2] No such file or directory

我的实际Python代码如下:

url = "/media/videos/3cf02324-43e5-4996-bbdf-6377df448ae4.mp4"
real_path = "/home/chanceapp/webapps/chanceapp/chanceapp"+url
fake_crop_path = "/home/chanceapp/webapps/chanceapp/chanceapp/fake1"+url
fake_rotate_path = "/home/chanceapp/webapps/chanceapp.chanceapp/fake2"+url
crop = "ffmpeg -i %s -vf "%(real_path)+"crop=400:400:0:0 "+ "-strict -2 %s"%(fake_crop_path)
rotate = "ffmpeg -i %s -vf "%(fake_crop_path)+"transpose=1 "+"%s"%(fake_rotate_path)
move_rotated = "mv"+" %s"%(fake_rotate_path)+" %s"%(real_path)
delete_cropped = "rm "+"%s"%(fake_crop_path)
#system calls:
subprocess.call(crop)

我可以就如何解决这个问题获得一些相关建议吗?

【问题讨论】:

The question that was duplicated to this question 有一个更好的答案。应该重新打开该问题,并将此问题复制到它。 【参考方案1】:

No such file or directory 如果您尝试使用双引号将文件参数放入Popen,也可以引发。

例如:

call_args = ['mv', '"path/to/file with spaces.txt"', 'somewhere']

在这种情况下,您需要删除双引号。

call_args = ['mv', 'path/to/file with spaces.txt', 'somewhere']

【讨论】:

【参考方案2】:

无法投票,所以我将重新发布@jfs 评论,因为我认为它应该更明显。

@AnneTheAgile:不需要 shell=True。此外,您不应该使用 除非有必要(请参阅@valid 的评论)。你应该通过 每个命令行参数作为一个单独的列表项,而不是例如,使用 ['command', 'arg 1', 'arg 2'] 而不是“command 'arg 1' 'arg 2'”。 – jfs 2015 年 3 月 3 日 10:02

【讨论】:

【参考方案3】:

如果您将字符串传递给subprocess.call,请使用shell=True

来自docs:

如果传递单个字符串,shell 必须是 True 或 否则字符串必须简单地命名要执行的程序 指定任何参数。

subprocess.call(crop, shell=True)

或:

import shlex
subprocess.call(shlex.split(crop))

【讨论】:

Python 3 提供了更好的错误消息,将有问题的“文件”命名为,但它没有提示 shell=True 是必需的。谢谢! 请注意,文档还声明“在命令字符串是从外部输入构造的情况下,强烈不鼓励使用shell=True”,请参阅答案中的链接. @AnneTheAgile: shell=True 不是必需的。此外,除非必要,否则您不应使用它(请参阅@valid 的评论)。您应该将每个命令行参数作为单独的列表项传递,例如,使用 ['command', 'arg 1', 'arg 2'] 而不是 "command 'arg 1' 'arg 2'" @user3553031 我不推荐它优于其他格式。我只是指出了这样一个事实,如果您使用的是字符串,那么您将不得不使用shell=True。安全方面超出了这个问题的范围。 @user3553031 这并不总是令人气馁,文档清楚地表明当输入来自外部输入时它是不安全的。说你永远不应该使用它是无稽之谈。而且关于子流程的问题太多了,在每个答案中都提到这一点没有任何意义。其他用户已经有关于它的 cmets,我也分享了文档链接。欢迎您编辑我的答案。

以上是关于OSError: [Errno 2] 在 Django 中使用 python 子进程时没有这样的文件或目录的主要内容,如果未能解决你的问题,请参考以下文章

easyprocess.EasyProcessCheckInstalledError: cmd=['Xvfb', '-help'] OSError=[Errno 2] 没有这样的文件或目录

用于 Traceroute 并在文件中打印输出的 Python 脚本在 Linux Mint 中显示错误(OSError: [Errno 2] No such file or directory)

OSError:[Errno 2]在Django中使用python子进程时没有这样的文件或目录

OSError:[Errno 26] 文本文件忙:'baremetrics'

OSError : [Errno 24] 打开的文件太多

OSError - Errno 13 权限被拒绝