2012-05-18 41 views
2

我已經閱讀了SO和其他站點上的一堆不同主題,無法直接回答我的問題。目前我有這個python腳本運行完全正常,除了沒有運行fortran程序的調用正常工作。我曾嘗試使用子進程命令,os.system命令,打開通過python打開的bash腳本文件,但沒有運氣。這裏有一些例子和我得到的錯誤。似乎無法讓fortran可執行文件通過python正確運行

一個attmept:

subprocess.Popen(["sh", "{0}{1}".format(SCRIPTS,"qlmtconvertf.sh"), "qlmt"], shell=False, stdout=subprocess.PIPE) 

這使該方案有麻煩正確讀取文件錯誤。

forrtl: severe (24): end-of-file during read, unit 1, file /home/akoufos/lapw/Ar/lda/bcc55_mt1.5_lo_e8_o4/DOS/lat70/qlmt 

的另一種嘗試:

subprocess.Popen(["./{0}{1}".format(SOURCE,"qlmtconvertf"), "qlmt"], shell=False, stdout=subprocess.PIPE) 

這給沒有找到文件的錯誤。

File "/home/akoufos/lapw/Scripts_Plots/LAPWanalysis.py", line 59, in DOS 
subprocess.Popen(["./{0}{1}".format(SOURCE,"qlmtconvertf"), "qlmt"], shell=False, stdout=subprocess.PIPE) 
    File "/usr/lib64/python2.7/subprocess.py", line 672, in __init__ 
errread, errwrite) 
    File "/usr/lib64/python2.7/subprocess.py", line 1202, in _execute_child 
raise child_exception 
    OSError: [Errno 2] No such file or directory 

另一個嘗試:

os.system("{0}{1}".format(SOURCE,"qlmtconvertf qlmt")) 

這給出了一個錯誤等同於第一個例子。在所有的例子中,SOURCE =「/ home/myusername/lapw/Source /」,其中fortran源文件是SCRIPTS =「/ home/myusername/lapw/Scripts_Plots /」,其中我有其他文件和python腳本,qlmtconvertf是一個編譯好的fortran程序,而qlmt是qlmtconvertf讀取的文件。如果我在shell中調用它,就像我已經做了無數次那樣,這個源代碼工作得很好,但我試圖自動調用這些代碼。我也寫了一個bash腳本,它可以滿足我的需求,但我試圖通過python來完成所有任務。任何想法,建議或對我所做的不正確以及正在發生的事情的答案將不勝感激。謝謝大家。

編輯:我得到它的工作與弗朗西斯下面給出的建議。我必須保留完整的路徑(即/ home/username/etc)和os.path.join才能正確調用程序。

import os.path 
    LAPW = "/home/myusername/lapw/" 
    SOURCE = os.path.join(LAPW,'Source') 
    SCRIPTS = os.path.join(LAPW,'Scripts_Plots') 
    QLMTCONVERT = os.path.join(SOURCE,'qlmtconvertf') 
    qargs = [QLMTCONVERT,'qlmt'] 
    #CALLING PROGRAM 
    subprocess.Popen(qargs, stdout=subprocess.PIPE).communicate(input=None) 

爲了讓它正常工作,我還必須關閉我在python腳本中創建的'qlmt'文件。此外,我正在包含'qlmt'文件的目錄中工作。

編輯還增加.communicate(input=None)到子進程的結束,這是不必要的這個過程調用,但它對於後者我在試圖用一個文件的過程中創建腳本做是很重要的。從我的理解.communicate談話的過程中,基本上等待它完成之前執行下一個python行。類似.wait(),但更先進。如果有人明白這更多想要詳細說明,請隨時。編輯

我不完全確定爲什麼這個方法能夠工作,但是使用字符串作爲子過程的輸入卻給出錯誤。如果有任何人對此有所瞭解,我會非常感激你能否傳授你的知識。謝謝大家的幫助。

+0

您是否嘗試過'殼= TRUE'?調用外部程序時,我通常會發現這一點。 – GreenMatt

+0

這很有趣,你如何寫這些帖子,像20次看他們,並忘記提及的東西。我已經在第二個例子中嘗試了'shell = True',並且沒有'。/'。這兩個似乎都沒有工作。我也嘗試使用'〜/ lapw'作爲文件夾名稱而不是完整路徑。再一次,這兩種方式都沒有提供更多有用的錯在第一個示例中試用它會打開shell提示符,但似乎也不起作用,但不運行該程序。我會更加關注這個問題,因爲qlmtconvert似乎沒有被調用。感謝您的建議。 – falconskull

+0

試圖運行可執行文件之前,您是否嘗試將當前工作目錄更改爲可執行文件所在的目錄?我已經使用了幾個Fortran程序,希望從他們的目錄運行。 – arifwn

回答

3

我覺得你在你的文件名忘了斜線:

"{0}{1}".format(SOURCE,"qlmtconvertf qlmt") == '/home/myusername/lapw/Sourceqlmtconvertf qlmt'

我假定你的意思呢?

"{0}/{1}".format(SOURCE,"qlmtconvertf qlmt") == '/home/myusername/lapw/Source/qlmtconvertf qlmt'

我建議使用os.path.join而非直接串建設路徑創建:

import os.path 

executable = os.path.join(SOURCE, 'qlmtconvertf') 
args = ['qlmt'] 

subprocess.Popen(executable+args, stdout=subprocess.PIPE) 
+0

我實際上有'/'我忘了在我放棄頂端的變量中加入。對困惑感到抱歉。但是,我沒有意識到'os.path.join'選項。我會開始使用它,現在就會嘗試。謝謝。 – falconskull

+0

更新:此選項似乎有所幫助。但是,我不太明白爲什麼這會起作用,但將路徑作爲與'os.path.join'完全相同的輸出的字符串不起作用。你對此有何看法?十分感謝你的幫助! – falconskull

+0

仔細檢查(使用assert語句)字符串實際上是相同的。 'os.path.join'對於以依賴於操作系統的方式加入路徑段是聰明的,但它仍然返回一個字符串。 –