使用subprocess.Popen时出现“没有此文件或目录”,不是由于字符串命令导致的

0 投票
3 回答
13016 浏览
提问于 2025-04-17 15:29

我正在运行一个处理wav文件的网络服务,但我不想让任何人随便上传文件,所以我先用下面的代码检查上传文件的时长:

os.chdir("/home/me/bin")
proc = subprocess.Popen(['duration',wav],stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=False)
out, errors = proc.communicate()
time = int(float(out.strip()))
if time > MAX_TIME:
    sys.exit(1)

这个方法已经正常工作了几个月,但最近(我应该提一下是在迁移之后)我遇到了以下错误:

Traceback (most recent call last):
  File "/home/me/webservice.py", line 100, in <module>
    proc = subprocess.Popen(['duration',wav],stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=False)
  File "/usr/lib64/python2.6/subprocess.py", line 639, in __init__
    errread, errwrite)
  File "/usr/lib64/python2.6/subprocess.py", line 1228, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

这个错误似乎主要是因为使用了字符串作为命令,而不是列表,但在这里并不是这个问题。当我尝试在一个单独的脚本中重现这个错误时,我却做不到。

有没有人知道这可能是什么原因呢?

3 个回答

-2

可以考虑在文件的开头做一些类似下面的事情,这样就不需要使用chdir,除非你有其他原因必须这么做。

import os
cmd = os.path.expanduser('~/bin/duration')
if not os.path.isfile(cmd):
    raise IOError("command '%s' not found" % cmd)


proc = subprocess.Popen([cmd,wav ...
0

这个错误可能不是因为你给 Popen 的可执行文件出问题了,而是因为它后面调用了另一个可执行文件,但在新环境的路径里找不到这个文件。

我也遇到过这种情况,问题是我没有安装我所调用的脚本所需的解释器。调试起来很让人沮丧,因为错误信息并没有告诉你到底缺少哪个文件。

3

没有路径的命令总是只在 PATH 中查找。你不能仅仅通过进入一个目录来让 subprocess(或者你的命令行)找到那个目录里的命令,除非你至少指定一个相对路径。这是标准的命令查找行为。

如果你想在当前工作目录中运行一个命令,你必须指定路径 ./,这样才能明确表示不使用 PATH 的查找规则。

PATH 环境变量中使用相对路径并不是在所有地方都支持的;把 . 加入 PATH 被认为是安全风险,有些系统会明确过滤掉 .。你必须从一个允许这样做的系统迁移到一个不允许 .PATH 中的系统。

撰写回答