我有一個python腳本,它使用subprocess.check_call
來啓動Wine(Linux上的Windows模擬器),然後葡萄酒啓動Z:\\Program Files (x86)\\PeaZip\\peazip.exe
。Python subprocess.check_call([「wine」] ..)有一個同步問題
首先,當我在調試模式python3 -u -m ipdb unpack_archive.py
中測試了這個python腳本,並且一步步設置了wine啓動和運行語句的斷點時,Wine成功運行peazip.exe
。也就是說,peazip在Linux上成功提取PEA檔案。
但是,當我測試此python腳本不在調試模式python3 unpack_archive.py
,然後我發現peazip.exe不會成功提取PEA存檔。所以我懷疑葡萄酒或python subprocess.check_call()中存在同步問題。現在
我的解決方法是,將time.sleep(1.0)
推出酒後:
elif 'PEA archive' in ftype:
if splitext(arcname)[1] != '.pea':
tmpfile = os.path.join(tmpdir, basename(arcname))+'.pea'
else:
tmpfile = os.path.join(tmpdir, basename(arcname))
shutil.copy(arcname, tmpfile)
subprocess.check_call(["wine", "/home/acteam/.wine/drive_c/Program Files (x86)/PeaZip/peazip.exe",
"-ext2here", to_wine_path(tmpfile)])
import time
time.sleep(1.0) # if we don't sleep, then peazip.exe won't extract file successfully
os.remove(tmpfile)
copy_without_symlink(tmpdir, outdir)
我檢查了wine manual,它沒有提及任何同步。我也檢查了subprocess.check_call()。該文件明確指出check_call()將等待命令完成。
我不想要這個解決方法,因爲如果PEA存檔文件非常大,那麼sleep()的超時值必須更大,並且我們無法在運行之前預測足夠的超時值。
我參考了@jasonharper的建議。使用subprocess.check_output()而不是check_call()
elif 'PEA archive' in ftype:
if splitext(arcname)[1] != '.pea':
tmpfile = os.path.join(tmpdir, basename(arcname))+'.pea'
else:
tmpfile = os.path.join(tmpdir, basename(arcname))
shutil.copy(arcname, tmpfile)
subprocess.check_output(["wine", "/home/acteam/.wine/drive_c/Program Files (x86)/PeaZip/peazip.exe",
"-ext2here", to_wine_path(tmpfile)])
os.remove(tmpfile)
copy_without_symlink(splitext(tmpfile)[0], outdir)
我python3 unpack_archive.py Kevin.pea
測試它,這是一個2.0GB的PEA存檔。提取過程花費4分16秒。三個子文件已成功解壓。
好。我試圖使用'wineserver --foreground'。我發現'peazip.exe'完成提取後'wineserver'也會終止。 我在啓動'wine'之前啓動'wineserver --foreground',並等待'wineserver'子進程終止。 – MikimotoH