Python中subprocess.check_output与os.system调用Fortran程序异常问题
问题分析与解决办法
你的问题核心在于subprocess模块的参数传递逻辑和os.system的差异,导致Fortran程序无法正确解析命令行参数。
为什么最初的subprocess写法会报错?
os.system会把整个命令字符串直接交给shell处理,shell会自动将-inp ./output_00076拆分成-inp(选项)和./output_00076(选项值)两个独立参数。但当你使用subprocess.check_output且不设置shell=True时,列表中的每个元素都会被当作一个完整的命令行参数传递给程序——你的代码把'-inp ./output_00076'作为单个参数传给了get_cpus,而非拆分后的两个参数。
Fortran程序解析参数时,无法识别这种合并后的奇怪选项,自然无法正确读取后续数值,因此抛出了列表导向I/O语法错误。
为什么加了shell=True还是不对?
当设置shell=True时,如果传入参数列表,subprocess会把列表第一个元素作为要执行的命令,后面的元素会被当作shell的位置参数(比如$1、$2),而非传递给get_cpus的参数。这就导致get_cpus根本没收到你指定的-inp、-xc等选项,所以返回了参数缺失的提示。
正确的写法
方法1:推荐(不用shell=True,正确拆分参数)
把每个选项和对应的参数拆分成列表中的独立元素,这是subprocess官方推荐的安全写法:
result = subprocess.check_output([ './get_cpus', '-inp', './output_00076', '-xc', '{:.4e}'.format(loc[0]), '-yc', '{:.4e}'.format(loc[1]), '-zc', '{:.4e}'.format(loc[2]), '-rad', '{:.4e}'.format(rad) ])
方法2:用shell=True(需拼成完整命令字符串)
如果一定要依赖shell解析命令,需要把整个命令拼成单一字符串(和os.system的写法一致):
cmd_str = './get_cpus -inp ./output_00076 -xc {:.4e} -yc {:.4e} -zc {:.4e} -rad {:.4e}'.format( loc[0], loc[1], loc[2], rad ) result = subprocess.check_output(cmd_str, shell=True)
注意:这种方式存在命令注入风险,除非必要不推荐使用。
内容的提问来源于stack exchange,提问作者earnric
相关产品推荐
相关产品推荐

