使用GNU Parallel在Wine下运行Windows程序

3

我有一个非常基础的脚本,用于在Wine下运行多个Windows种群遗传学程序(msvar.exe)。它使用“find”命令查找多个文件夹中的初始化文件(INTFILE),然后使用该初始化文件在每个目录中启动一个msvar.exe实例。不同的文件夹将在初始化文件中具有不同的参数,因此我可以通过添加“&”参数来运行一系列模拟。这是脚本内容:

for i in $(find /home/msvartest -name INTFILE -type f)
do (
cd $(dirname $(realpath $i));
#   wine explorer /desktop=name msvar.exe;
wineconsole --backend=user msvar.exe;
) &
done

目前我在我的双六核机器上,每次同时运行多达20个msvar.exe副本,每个副本都在自己的wineconsole(或wine浏览器窗口)下运行。每个运行实例可能需要3到4天,但程序只能在单个核心上运行,因此我需要并行运行模拟。看起来Gnu parallel是运行msvar.exe的更好方法,并且可以让我在远程计算机上运行更多模拟。我尝试了在Run wine in parallel with gnu-parallel - needs {%} slot substitution to work中建议的使用wineconsole运行Gnu parallel,但没有成功。是否有人能够帮助,或者最好能提供一个脚本供我使用。感谢您的帮助。

很荣幸您接受了我的答案,但实际上,来自@OleTange(他是杰出的GNU Parallel的作者)的答案更正确-请查看他在我的答案下面的评论。 - Mark Setchell
很不幸我没能聪明到让Ole的脚本正常工作 - 多么尴尬啊!! - dberryman
2个回答

2

我认为,如果您不使用像这样的导出函数,那么您的命令将变得异常冗长和难以操作:

#!/bin/bash

doit() {
   ...
   ...
}

export -f doit
parallel -j 10 doit ::: {0..99}

因此,对于您的示例,代码可能如下(未经测试):

#!/bin/bash

doit() {
   echo Processing $1
   cd $(dirname $(realpath "$1"));
   WINEPREFIX=$HOME/slot{%} wineconsole --backend=user msvar.exe
}
export -f doit

find /home/msvartest -name INTFILE -type f | parallel --dry-run doit

很遗憾,我没有设置您的环境来测试它,但如果有小错误,它应该会很接近并且易于纠正。尝试并查看它的效果,然后删除--dry-run以让其实际执行。

如果您的文件名中有空格,则应在find命令中使用-print0,并在parallel之后添加-0,但这只是暂时使事情变得更复杂。


在函数中,{%} 不会被替换 - 只有在命令行中才会被替换。 - Ole Tange
太棒了,这让我朝着正确的方向前进了,我甚至大致明白它们是如何工作的(我是一名生物学家,只知道足以危及编程!)。现在是关于如何使用并行在远程服务器上运行msvar.exe的问题。如果我只是在“parallel”和“doit”之间添加远程服务器详细信息(按照帮助文件),远程服务器会说“doit”不是一个命令,即使对我来说也是显而易见的原因。如何修改此内容以复制数据文件夹并允许在安装有msvar.exe的远程服务器上运行? - dberryman
1
哎呀!你的要求已经超出了我的能力范围!也许先把它全部运行在一台服务器上,然后再提出一个新问题,询问如何将数据和工作并行地分布在其他远程服务器上,并希望 Ole 能像他一直以来那样关注。 - Mark Setchell
好的。先发布在单台机器上运行的脚本,我们会从那里开始处理。 - Ole Tange
抱歉,Fantastic 的意思是它起作用了!我所要做的就是修改目录到正在使用的目录,删除 --dry-run,然后它立即起作用了。这个函数可以工作:doit() { echo 正在处理 $1

cd $(dirname $(realpath "$1"));

cd $(dirname $(readlink -f "$1")); WINEPREFIX=$HOME/slot{%} wine /home/DaveB/msvar/msvar0.4.1b/msvar.exe } export -f doitfind /home/DaveB/msvar/MSVAR_ORC_NEWUPLOAD -name INTFILE -type f | parallel doit
- dberryman
请忽略上面的脚本,那是不小心插入的。Mark建议的脚本是正确的,只需将目录调整为find命令即可。当我运行它时,有20个线程运行20个msvar.exe实例-太棒了。再过4天我就会得到结果。我没能让Ole的脚本起作用,但也没有试太多次。这将对我们中的许多人有所帮助,并节省数周或数月的分析时间。非常感谢您的努力。我会在另一个问题中询问远程执行的问题。 - dberryman

1
#!/bin/bash

doit() {
   echo Processing $1
   cd $(dirname $(realpath "$1"));
   WINEPREFIX=$HOME/slot$2 wineconsole --backend=user msvar.exe
}
export -f doit

find /home/msvartest -name INTFILE -type f | parallel doit {} {%}

是的,你说得对 - 像往常一样。看起来更好了;-) - Mark Setchell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接