我有一个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