Python中的子处理库

Python中的子处理库,python,subprocess,Python,Subprocess,我有一个脚本,它分析.ply文件的3d文件格式,并提供有关该文件的数据。我试图在我的目录中找出哪些文件已损坏,哪些未损坏。因此,我尝试使用子流程库运行脚本来查找.ply文件的任意功能。在本例中,是最小边长度。如果err中有任何内容,则表示它无法检索任意功能,并且文件已损坏。在这里,我只在一个文件上运行它。然而,我不断地得到一个错误 import subprocess sample_file_directory = "..." # directory where file is SCRIPT_D

我有一个脚本,它分析.ply文件的3d文件格式,并提供有关该文件的数据。我试图在我的目录中找出哪些文件已损坏,哪些未损坏。因此,我尝试使用子流程库运行脚本来查找.ply文件的任意功能。在本例中,是最小边长度。如果err中有任何内容,则表示它无法检索任意功能,并且文件已损坏。在这里,我只在一个文件上运行它。然而,我不断地得到一个错误

import subprocess

sample_file_directory = "..." # directory where file is
SCRIPT_DIR = "..." # directory where script is

p = subprocess.Popen([SCRIPT_DIR,sample_file_directory,'min','edgelen'],stdout=subprocess.PIPE,stderr=subprocess.PIPE) 
min_side_len, err = p.communicate()
print len(err)

有人能帮我找出为什么我会犯这个错误吗?我的数据目录和脚本目录都有效。还有,如果我遗漏了重要的东西,我也很抱歉。第一次发布。

subprocess.Popen不会为您合并路径组件。据我所知,您只提供了一个目录。您需要将目标可执行文件的名称添加到指定给Popen的路径中。请尝试以下操作:

p = subprocess.Popen([SCRIPT_DIR,sample_file_directory,'min','edgelen'],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1249, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory

脚本_DIR变量是绝对路径还是相对路径在运行脚本的位置有效?如果是后者,则可能无法工作,因为子流程可能在具有不同工作目录的不同环境中启动。

问题在于:

p = subprocess.Popen([os.path.join(SCRIPT_DIR,SCRIPT_NAME),sample_file_directory,'min','edgelen'],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
请注意这一部分:

p = subprocess.Popen([SCRIPT_DIR,sample_file_directory,'min','edgelen'],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
现在,请看,您已经知道子流程需要一个列表。但问题是,您正在将目录作为列表的一部分传递。列表的格式如下所示:

[命令,arg1,arg2…]

现在,当您运行该命令时,您正在执行以下操作:

[脚本\u目录->命令 示例文件目录->arg1 'min'->arg2 “edgelen”->arg3]

看到问题了吗?您正在将脚本的目录作为要运行的命令传递,并将脚本的名称作为参数传递。导入操作系统模块并执行以下操作:

Popen([SCRIPT_DIR,sample_file_directory,'min','edgelen']
这就是:

[脚本目录和示例文件目录连接在一起->命令 'min'->arg1 “edgelen”->arg2]


os.path.join自动添加路径分隔符。

另一个可能的情况是,您试图在未安装32位库的64位系统上运行32位二进制文件。事实上,我今天早些时候遇到了这个问题。这里记录了一个修复程序。我对你们的系统一无所知,所以这可能是完全不相关的建议,但我想提一下也没什么坏处。丹·阿尔伯特。他想出了解决办法的答案!非常感谢,丹

实际的脚本名称是什么,您是否将其提供给Popen调用?该脚本称为mesh_info,可以在名为trimesh2的包中找到。是的,我用SCRIPT_DIR在Popen中调用它,因为我在目录中包含了脚本名。当在Popen中调用的脚本是一个文本文件,其中包含子进程找不到的shebang时,您可能会遇到此错误。例如,如果你的脚本开始了!而不是python/usr/local/env-python,您将得到此错误。subprocess.Popen无法访问$PATHOne。另一个可能的问题是,您正在尝试在未安装32位库的64位系统上运行32位二进制文件。事实上,我今天早些时候遇到了这个问题。一个修复是有文档记录的。我对你们的系统一无所知,所以这可能是完全不相关的建议,但我想提一下也没什么坏处。啊,是的!这就是问题所在!非常感谢!应该是os.path.joinSCRIPT\u DIR,SCRIPT\u NAME。i、 例如,这两个应该直接传递,而不是列表的一部分。我应该指定抱歉,目录中已经包含了脚本名。感谢您的更正,JJC。我不记得是哪一个了。OP:我不得不同意其他人的意见,说你的程序可能就是找不到你要运行的脚本。使用绝对路径不应该有这个问题,所以我会在调用Popen之前尝试打印出路径。可以尝试复制正在打印的完整路径并将其转储到shell中,以确保它可以运行。其他需要注意的事情是跨文件系统和遵循符号链接。理论上,所有这些都应该为您处理,但奇怪的事情发生了:不,不幸的是,我使用的是绝对路径hmmm。您是否尝试过将SCRIPT\u DIR、sample\u file\u目录等作为组合字符串而不是列表传递,并使用shell=True选项?如果您的命令依赖于shell扩展,例如~或其他通配符或shell功能,则除非您使用后一种方法,否则这些功能将不起作用。除此之外,您是否尝试过运行其他命令,如/bin/date或您知道其位置的简单命令?shell=True可能有助于测试,但对于最终的程序,我会确保将其删除。正如现在的程序一样,您不会遇到安全问题,但是如果您稍后返回并允许用户指定任何参数,则很容易忘记该细节。请参阅下面的警告,以了解为什么您应该谨慎使用shell=True。我完全赞同DanAlbert关于shell=True选项的警告。我
只有在shell扩展是找不到该命令的原因的情况下才建议使用它,但我应该包括关于在生产中不使用它的建议:-为什么要将脚本目录和文件目录连接在一起?我应该声明脚本目录包含脚本名,脚本将文件作为参数。哦…好吧…那么它就是找不到脚本。我以为SCRIPT_DIR就是文件夹,sample_file_directory就是脚本名。很抱歉Popen找不到你的剧本真是太严重了。尝试在打印脚本\u DIR的Popen调用之前添加一个print语句,以确保它是您想要的。
p = subprocess.Popen([os.path.join(SCRIPT_DIR,sample_file_directory),'min','edgelen'],stdout=subprocess.PIPE,stderr=subprocess.PIPE)