Python 用于生成/使用输出文件的subprocess.call()或subprocess.Popen
我正试图编写一个Python代码来与另一个使用命令行提示的软件交互。执行命令行提示符后,目录中会生成多个输出文件,软件会使用这些输出文件进行一些计算。另外,我程序的其余部分使用这些输出文件。目前,我运行python代码,然后在命令行提示符下手动输入,然后调用其余代码,这一切正常,但是当我尝试放置:Python 用于生成/使用输出文件的subprocess.call()或subprocess.Popen,python,subprocess,Python,Subprocess,我正试图编写一个Python代码来与另一个使用命令行提示的软件交互。执行命令行提示符后,目录中会生成多个输出文件,软件会使用这些输出文件进行一些计算。另外,我程序的其余部分使用这些输出文件。目前,我运行python代码,然后在命令行提示符下手动输入,然后调用其余代码,这一切正常,但是当我尝试放置: subprocess.call(['sfit4Layer0.py', '-bv5', '-fs'], shell=False) 在我的文件中,它没有正确执行(没有生成输出文件) 当我编写上述代码时,
subprocess.call(['sfit4Layer0.py', '-bv5', '-fs'], shell=False)
在我的文件中,它没有正确执行(没有生成输出文件)
当我编写上述代码时,它是自己的单独python代码,并在代码的第一部分之后立即调用它——它也起作用了
根据我的输出,我确信问题在于:调用生成了多个文件,然后使用这些文件进行计算,但是,它没有生成正确的文件,因此我的输出中会出现错误。因此,在某种程度上,它似乎超越了自身:在进行计算之前不等待输出文件的生成,但同样,当我在程序之外单独运行此命令时,它会工作。你知道为什么会这样吗
我做错了什么?我是否需要指定目录(输出文件是否可以放在我计算机的其他地方)?我需要使用subprocess.Popen吗?我已经在互联网上搜索过了,但我对Python还是新手,完全被难住了
欢迎任何建议。谢谢
编辑:对于询问的人,以下是sfit4Layer0.py代码:
#! /usr/bin/python
##! /usr/local/python-2.7/bin/python
##! /usr/bin/python
##! /usr/bin/python
# Change the above line to point to the location of your python executable
#----------------------------------------------------------------------------------------
# Name:
# sfit4Layer0.py
#
# Purpose:
# This file is the zeroth order running of sfit4. It accomplishes the following:
# 1) Calls pspec to convert binary spectra file (bnr) to ascii (t15asc)
# 2) Calls hbin to gather line parameters from hitran
# 3) Calls sfit4
# 4) Calls error analysis from Layer1mods.py
# 5) Clean outputs from sfit4 call
#
#
# External Subprocess Calls:
# 1) pspec executable file from pspec.f90
# 2) hbin executable file from hbin.f90
# 3) sfit4 executable file from sfit4.f90
# 4) errAnalysis from Layer1mods.py
#
#
#
# Notes:
# 1) Options include:
# -i <dir> : Optional. Data directory. Default is current working directory
# -b <dir/str> : Optional. Binary directory. Default is hard-code.
# -f <str> : Run flags, h = hbin, p = pspec, s = sfit4, e = error analysis, c = clean
#
#
# Usage:
# ./sfit4Layer0.py [options]
#
#
# Examples:
# 1) This example runs hbin, pspec, sfit4, error analys, and cleans working directory prior to execution
# ./sfit4Layer0.py -f hpsec
#
# 2) This example just runs sfit4
# ./sfit4Layer0.py -f s
#
# 3) This example cleans the output file created by sfit4 in directory (/User/home/datafiles/) which is not the current directory
# ./sfit4Layer0.py -i /User/home/datafiles/ -f c
#
# Version History:
# Created, May, 2013 Eric Nussbaumer (ebaumer@ucar.edu)
#
#
# License:
# Copyright (c) 2013-2014 NDACC/IRWG
# This file is part of sfit4.
#
# sfit4 is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# sfit4 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with sfit4. If not, see <http://www.gnu.org/licenses/>
#
#----------------------------------------------------------------------------------------
#---------------
# Import modules
#---------------
import sys
import os
import getopt
import sfitClasses as sc
from Layer1Mods import errAnalysis
from Tkinter import Tk
from tkFileDialog import askopenfilename
#------------------------
# Define helper functions
#------------------------
def usage(binDirVer):
print 'sfit4Layer0.py -f <str> [-i <dir> [-b <dir/str> ] \n'
print '-i <dir> Data directory. Optional: default is current working directory'
print '-f <str> Run Flags: Necessary: h = hbin, p = pspec, s = sfit4, e = error analysis, c = clean'
print '-b <dir/str> Binary sfit directory. Optional: default is hard-coded in main(). Also accepts v1, v2, etc.'
for ver in binDirVer:
print ' {}: {}'.format(ver,binDirVer[ver])
sys.exit()
def main(argv):
#----------------
# Initializations
#----------------
#------------
# Directories
#------------
wrkDir = os.getcwd() # Set current directory as the data directory
binDir = '/data/bin' # Default binary directory. Used of nothing is specified on command line
binDirVer = {
'v1': '/data/ebaumer/Code/sfit-core-code/src/', # Version 1 for binary directory (Eric)
'v2': '/data/tools/400/sfit-core/src/', # Version 2 for binary directory (Jim)
'v3': '/Users/jamesw/FDP/sfit/400/sfit-core/src/', # Version 2 for binary directory (Jim)
'v4': '/home/ebaumer/Code/sfit4/src/',
'v5': '/Users/allisondavis/Documents/Summer2016/sfit4_0.9.4.3/src'
}
#----------
# Run flags
#----------
hbinFlg = False # Flag to run hbin
pspecFlg = False # Flag to run pspec
sfitFlg = False # Flag to run sfit4
errFlg = False # Flag to run error analysis
clnFlg = False # Flag to clean directory of output files listed in ctl file
#--------------------------------
# Retrieve command line arguments
#--------------------------------
try:
opts, args = getopt.getopt(sys.argv[1:], 'i:b:f:?')
except getopt.GetoptError as err:
print str(err)
usage(binDirVer)
sys.exit()
#-----------------------------
# Parse command line arguments
#-----------------------------
for opt, arg in opts:
# Data directory
if opt == '-i':
wrkDir = arg
sc.ckDir(wrkDir,exitFlg=True)
# Binary directory
elif opt == '-b':
if not sc.ckDir(arg,exitFlg=False,quietFlg=True):
try: binDir = binDirVer[arg.lower()]
except KeyError: print '{} not a recognized version for -b option'.format(arg); sys.exit()
else: binDir = arg
if not(binDir.endswith('/')): binDir = binDir + '/'
# Run flags
elif opt == '-f':
flgs = list(arg)
for f in flgs:
if f.lower() == 'h': hbinFlg = True
elif f.lower() == 'p': pspecFlg = True
elif f.lower() == 's': sfitFlg = True
elif f.lower() == 'e': errFlg = True
elif f.lower() == 'c': clnFile = True
else: print '{} not an option for -f ... ignored'.format(f)
elif opt == '-?':
usage(binDirVer)
sys.exit()
else:
print 'Unhandled option: {}'.format(opt)
sys.exit()
#--------------------------------------
# If necessary change working directory
# to directory with input data.
#--------------------------------------
if os.path.abspath(wrkDir) != os.getcwd(): os.chdir(wrkDir)
if not(wrkDir.endswith('/')): wrkDir = wrkDir + '/'
#--------------------------
# Initialize sfit ctl class
#--------------------------
ctlFileName = wrkDir + 'sfit4.ctl'
if sc.ckFile(wrkDir+'sfit4.ctl'): ctlFileName = wrkDir + 'sfit4.ctl'
else:
Tk().withdraw()
ctlFileName = askopenfilename(initialdir=wrkDir,message='Please select sfit ctl file')
ctlFile = sc.CtlInputFile(ctlFileName)
ctlFile.getInputs()
#------------------------
# Initialize sb ctl class
#------------------------
if errFlg:
if sc.ckFile(wrkDir+'sb.ctl'): sbCtlFileName = wrkDir + 'sb.ctl'
else:
TK().withdraw()
sbCtlFileName = askopenfilename(initialdir=wrkDir,message='Please select sb ctl file')
sbCtlFile = sc.CtlInputFile(sbCtlFileName)
sbCtlFile.getInputs()
#---------------------------
# Clean up output from sfit4
#---------------------------
if clnFlg:
for k in ctlFile.inputs['file.out']:
if 'file.out' in k:
try: os.remove(wrkDir + ctlFile.inputs[k])
except OSError: pass
#----------
# Run pspec
#----------
if pspecFlg:
print '*************'
print 'Running pspec'
print '*************'
rtn = sc.subProcRun( [binDir + 'pspec'] )
#----------
# Run hbin
#----------
if hbinFlg:
print '************'
print 'Running hbin'
print '************'
rtn = sc.subProcRun( [binDir + 'hbin'] )
#----------
# Run sfit4
#----------
if sfitFlg:
print '************'
print 'Running sfit'
print '************'
rtn = sc.subProcRun( [binDir + 'sfit4'] )
#-------------------
# Run error analysis
#-------------------
if errFlg:
print '**********************'
print 'Running error analysis'
print '**********************'
rtn = errAnalysis(ctlFile,sbCtlFile,wrkDir)
if __name__ == "__main__":
main(sys.argv[1:])
#/usr/bin/python
##! /usr/local/python-2.7/bin/python
##! /usr/bin/python
##! /usr/bin/python
#将上面的行更改为指向python可执行文件的位置
#----------------------------------------------------------------------------------------
#姓名:
#sfit4Layer0.py
#
#目的:
#此文件是sfit4运行的第0个顺序。它实现了以下功能:
#1)调用pspec将二进制光谱文件(bnr)转换为ascii(t15asc)
#2)调用hbin从hitran收集线路参数
#3)呼叫sfit4
#4)从LayerMods.py调用错误分析
#5)sfit4呼叫的清洁输出
#
#
#外部子进程调用:
#1)pspec.f90中的pspec可执行文件
#2)hbin.f90中的hbin可执行文件
#3)来自sfit4.f90的sfit4可执行文件
#4)Layer1mods.py的错误分析
#
#
#
#注:
#1)选项包括:
#-i:可选。数据目录。默认为当前工作目录
#-b:可选。二进制目录。默认值是硬代码。
#-f:运行标志,h=hbin,p=pspec,s=sfit4,e=error analysis,c=clean
#
#
#用法:
#./sfit4Layer0.py[选项]
#
#
#示例:
#1)此示例在执行之前运行hbin、pspec、sfit4、错误分析并清理工作目录
#./sfit4Layer0.py-f hpsec
#
#2)此示例仅运行sfit4
#./SFIT4层0.py-f s
#
#3)此示例清除sfit4在目录(/User/home/datafiles/)中创建的输出文件,该目录不是当前目录
#./sfit4Layer0.py-i/User/home/datafiles/-f c
#
#版本历史记录:
#创建于2013年5月Eric Nussbaumer(ebaumer@ucar.edu)
#
#
#许可证:
#版权所有(c)2013-2014 NDACC/IRWG
#此文件是sfit4的一部分。
#
#sfit4是自由软件:您可以重新发布和/或修改它
#它是根据GNU通用公共许可证的条款发布的
自由软件基金会,或者许可证的第3版,或者
#任何更高版本。
#
#分发sfit4是希望它会有用,
#但无任何保证;甚至没有任何关于
#适销性或适合某一特定目的。见
#有关更多详细信息,请参阅GNU通用公共许可证。
#
#您应该已经收到GNU通用公共许可证的副本
#以及sfit4。如果没有,请参阅
#
#----------------------------------------------------------------------------------------
#---------------
#导入模块
#---------------
导入系统
导入操作系统
导入getopt
将SFITClass作为sc导入
从Layer1Mods导入错误分析
从Tkinter导入Tk
从tkFileDialog导入askopenfilename
#------------------------
#定义辅助函数
#------------------------
def使用(binDirVer):
打印'sfit4Layer0.py-f[-i[-b]\n'
打印'-i数据目录。可选:默认为当前工作目录'
打印'-f运行标志:必要:h=hbin,p=pspec,s=sfit4,e=error analysis,c=clean'
打印'-b二进制sfit目录。可选:默认值在main()中硬编码。也接受v1、v2等
对于binDirVer中的版本:
打印“{}:{}”。格式(ver,binDirVer[ver])
sys.exit()
def总管(argv):
#----------------
#初始化
#----------------
#------------
#目录
#------------
wrkDir=os.getcwd()#将当前目录设置为数据目录
binDir='/data/bin'#默认的二进制目录。在命令行中未指定任何用法
binDirVer={
“v1”:“/data/ebaumer/Code/sfit-core-Code/src/”,#二进制目录(Eric)的第1版
“v2”:“/data/tools/400/sfit-core/src/”,#二进制目录(Jim)的第2版
“v3”:“/Users/jamesw/FDP/sfit/400/sfit-core/src/”,#二进制目录(Jim)的第2版
“v4”:“/home/ebaumer/Code/sfit4/src/”,
“v5”:“/Users/allisondavis/Documents/Summer2016/sfit4_0.9.4.3/src”
}
#----------
#跑旗
#----------
hbinFlg=False#运行h的标志
subprocess.call(['sfit4Layer0.py', '-bv5', '-fs'], shell=True)
subprocess.call(['sfit4Layer0.py', '-bv5', '-fs'], shell=False)
subprocess.call(['python','/path/to/script/sfit4Layer0.py','-bv5','-fs'], shell=False)
subprocess.call(['/path/to/script/sfit4Layer0.py -bv5 -fs'], shell=True)