2013-01-22 97 views
0

我試圖使用subprocess.Popen(['cp'等..])在while循環中傳輸和重命名一些文件。並等待()。不幸的是,wait()命令似乎不能正常工作,即不等待文件完全複製到新目錄。大多數情況下,文件複製都很好,但是,隨機文件的一小部分不會(每次運行腳本都不是相同的文件),因此是零字節文件或不完整的文件。我也試過使用subprocess.check_call(),但這也不起作用。當我打印poll()值時,它始終爲零,這意味着該過程已完成。注意我正在處理的所有文件都在150KB範圍內。由於我使用的是iraf例程,我的python腳本正在使用python 2.7,python版本的iraf(圖像縮減和分析工具)運行在pyraf中。有沒有辦法強制Popen()或check_call()等待文件傳輸完成?如何強制wait()完全等待subprocess.Popen()完成

while count <= ncross_correlate and skip_flag != 's': 
    ...more stuff 
    try: 
     iraf.rv.fxcor (object_fits, template_fits, apertures="*", cursor="", 
     continuum="both", filter="both", rebin="smallest", pixcorr="no", 
     osample=osample_reg, rsample=osample_reg, apodize=0.1, function="gaussian", 
     width="INDEF", height=0., peak="no", minwidth=3., maxwidth=21., weights=1., 
     background=0., window=300., wincenter="INDEF", output=output_name, verbose="long", 
     imupdate="no", graphics="stdgraph", interactive="no", autowrite="yes", 
     autodraw="yes", ccftype="image", observatory="aao", continpars="", filtpars="", 
     keywpars="") 

     # Create a eps file of the cross_correlation file. 
     gki_output_name = output_name + '.gki' 
     iraf.plot.sgikern (gki_output_name, device='eps', generic='no', debug='no', 
     verbose='no', gkiunit='no') 

不幸的是在fxcor創建.gki文件轉換爲一些可讀 格式伊拉克空軍以外的唯一方法是調用伊拉克空軍任務sgikern的轉儲一個.EPS文件在我 伊拉克空軍/伊拉克空軍/目錄,而不提供更改文件名或目錄放置的選項。事實上,文件名是隨機生成的。非常沮喪!另外請注意,使用iraf.plot.sgikern創建的任何eps文件都沒有問題(即,沒有開頭的0 KB文件)。複製和重命名是我遇到問題的地方。

 # Find the eps file in /iraf/iraf/, rename it, and move to proper output location. 
     iraf_dir = '/iraf/iraf/' 
     eps_file_list = glob.glob(iraf_dir + 'sgi' + '*.eps') 

     ...more code 

在這一點上我一直在使用check_call()或POPEN()嘗試:

 subprocess.check_call(['cp', eps_file_list[0], ccf_output_dir + object_name_sub + 
          '.eps'], stdout=subprocess.PIPE) 
     subprocess.check_call(['rm', eps_file_list[0]], stdout=subprocess.PIPE) 

 process1 = subprocess.Popen(['cp', eps_file_list[0], ccf_output_dir + 
            object_name_sub + '.eps'], stdout=subprocess.PIPE) 
     process1.wait() 
     process2 = subprocess.Popen(['rm', eps_file_list[0]], stdout=subprocess.PIPE) 
     process2.wait() 

     ...more stuff 

    # end of try statement 
#end of while statement 

我想,如果我能以某種方式在合併的兩條POPEN聲明一個單獨的Popen語句,並且還包括一個可能爲0.01s的shell睡眠時間,以強制其他兩個進程在返回完成的進程之前完成,這可能會修復它。也許這樣的事情,雖然我不知道確切的sentax的:

process1 = subprocess.Popen(['cp', eps_file_list[0], ccf_output_dir + 
      object_name_sub + '.eps']; ['rm', eps_file_list[0]]; ['sleep', 0.01], 
      stdout=subprocess.PIPE) 
process1.wait()  

但願這給你什麼,我試圖做一個想法。我一直在嘗試很多不同的事情,並且全力尋找解決這個問題的辦法,而且我真的被困住了。

乾杯, 佈雷特

+0

有函數叫''communic',會幫你 –

+0

不相關,但'fxcor'函數簽名是荒謬的。 – Anorov

+0

我看不出溝通會如何幫助我。你能舉個例子格里傑什嗎? Fxcor確實有很多輸入,因此調用序列很長。基本上fxcor代表傅里葉互相關。 –

回答

0

或許下面就足夠了:

subprocess.check_call(['mv', eps_file_list[0], ccf_output_dir + object_name_sub + 
         '.eps'], stdout=subprocess.PIPE) 

process1 = subprocess.Popen(['mv', eps_file_list[0], ccf_output_dir + 
           object_name_sub + '.eps'], stdout=subprocess.PIPE) 
process1.wait() 
+0

我不認爲有兩個移動過程會起作用。如果在調用第二個命令之前文件已被第一個命令部分移動,而第二個命令很可能不會找到要移動的文件(因爲它已被第一個命令移動)。我對嗎? –

+0

我並不是建議將兩者結合使用,而是建議使用一種或另一種,正如您的示例所示。 – user1999418

+0

本質上,爲什麼不使用'mv'而不是'cp'然後'rm'。 – user1999418

0

你有沒有使用shutil.copyfile的副本,併爲os.remove刪除考慮?

如果你真的想用子進程,我相信語法是這樣的:

process1 = subprocess.Popen('cp ' + eps_file_list[0] + ' ' + ccf_output_dir + 
     object_name_sub + '.eps; rm ' + eps_file_list[0] ' + '; sleep 0.01', 
     stdout=subprocess.PIPE) 

這樣,你調用命令都在一個字符串:'cp whatever foo/bar.eps; rm whatever; sleep 0.01'

你可以也格式化三重引號括起來的,並有命令在單獨的行:

''' 
cp %s %s%s 
rm %s 
sleep %s 
''' % (eps_file_list[0], ccf_output_dir, object_name_sub, eps_file_list[0], 0.01) 
+0

嗨,亞倫,是的,我已經考慮過shutil.copyfile和os.remove,但是,我遇到了同樣的問題。我弄清楚瞭如何通過這樣做來組合多個Popen命令:cmd1 ='cp {0} {1}'.format(iraf_dir + eps_file,ccf_output_dir + object_name_sub +'.eps') cmd2 ='rm {0}' .format(iraf_dir + eps_file) cmd3 ='sleep 0.05' process1 = subprocess.Popen(「{}; {}; {}」.format(cmd1,cmd2,cmd3),shell = True,stdout = subprocess.PIPE ) process1.wait() –

0

這不是一個完整的解決方案,也沒有一個令人滿意的一個,但我t是我所想到的最好的作品,99.9%的時間(我創建的4000多個eps中有5個文件是我的0字節或不完整的)。這比原來的方式有所改善,大約95%的時間都是成功的。我已經粘貼下面的代碼:

 try: 
     iraf.rv.fxcor (object_fits, template_fits, apertures="*", cursor="", 
     continuum="both", filter="both", rebin="smallest", pixcorr="no", osample=osample_reg, 
     rsample=osample_reg, apodize=0.1, function="gaussian", width="INDEF", height=0., peak="no", 
     minwidth=3., maxwidth=21., weights=1., background=0., window=300., 
     wincenter="INDEF", output=output_name, verbose="long", imupdate="no", 
     graphics="stdgraph", interactive="no", autowrite="yes", autodraw="yes", 
     ccftype="image", observatory="aao", continpars="", filtpars="", keywpars="") 

     # Create a eps file of the cross_correlation file. 
     gki_output_name = output_name + '.gki' 
     iraf.plot.sgikern (gki_output_name, device='eps', generic='no', debug='no', 
     verbose='no', gkiunit='no') 
     time.sleep(0.25) 

我把時間臥鋪這裏我發現了一些PS文件在我的伊拉克空軍目錄中創建並沒有被我的代碼試圖移動時完全寫入文件到另一個目錄。

 # Find the eps file in /iraf/iraf/, rename it, move to proper output location, and delete the old eps file. 
     iraf_dir = '/iraf/iraf/' 
     eps_file_list = glob.glob(iraf_dir + 'sgi' + '*.eps') 

     ...continuation of code 

     if len(eps_file_list) == 1: 
      eps_file_sub = os.path.basename(eps_file_list[0]) 

      cmd1 = 'cp {0} {1}'.format(eps_file_list[0], ccf_output_dir + object_name_sub + '.eps') 
      cmd2 = 'rm {0}'.format(eps_file_list[0]) 
      cmd3 = 'sleep 0.05' 
      process1 = subprocess.Popen("{}; {}; {}".format(cmd1, cmd2, cmd3), shell=True, stdout=subprocess.PIPE) 
      process1.wait() 

With process1我發送了三個子進程shell命令。首先是將eps文件從my/iraf目錄複製到另一個目錄(首先創建它們的iraf函數不允許我給這些文件指定一個合適的名稱,也不允許輸出位置)。第二個是從我的/ iraf目錄中刪除eps文件。第三個命令強迫內核睡覺。通過這樣做,Python在達到睡眠命令之前不會收到完成的信號。這部分我相信完美。唯一的問題是,當我達到這個命令時,用於創建eps文件的iraf例程很少創建它們的速度不夠快。

 #endif 

     num_cross = num_cross + 1 
    #Endtry 
    ...more code 

這是一個非常笨重的解決方案,不能滿足要求,但99.9%的時間工作。如果有人有更好的解決方案,請讓我知道。這是一個非常令人沮喪的問題,我問過的每個人都無法提出更好的方案(包括那些經常在我的天文部門進行python編程的人)。