我有一个 Bash 脚本,其中有一个循环来输入特定目录,并对特定输入文件进行一定的计算。之后,它从该目录退出,并在另一个目录中使用不同的输入文件执行相同的操作。计算需要很多时间,我想并行化它。
我如何修改我的脚本?有没有一个选项可以做到这一点?
myscript.sh
cd MainDir
for dir in *
do
cd ${dir}
LD_LIBRARY_PATH="$software"/ "$software"/calc -i /home/files/"$dir.txt" -l /home/Str/Art.pdb -a 5.0 -rf /home/file/prot -cpu 1 opt -w ${dir}_res > ${dir}_WPA.log
cd ..
done
我使用命令-cpu来指示cpu的使用情况。我有很多 CPU 可供使用,那么如何并行处理更多作业呢?
例如,如果我有三个不同的输入文件,我想一起运行(在不同的目录中)以下命令:
cd 1
LD_LIBRARY_PATH="$software"/ "$software"/calc -i /home/files/1.txt -l /home/Str/Art.pdb -a 5.0 -rf /home/file/prot -cpu 1 opt -w 1_res > 1_WPA.log
-----------
cd 2
LD_LIBRARY_PATH="$software"/ "$software"/calc -i /home/files/2.txt -l /home/Str/Art.pdb -a 5.0 -rf /home/file/prot -cpu 1 opt -w 2_res > 2_WPA.log
-----------
cd 3
LD_LIBRARY_PATH="$software"/ "$software"/calc -i /home/files/3.txt -l /home/Str/Art.pdb -a 5.0 -rf /home/file/prot -cpu 1 opt -w 3_res > 3_WPA.log
有人可以帮我吗?谢谢。
答案1
您可以在命令末尾添加&
,将其发送到后台:
for i in 1 2 3 4; do
(
cd dir
command
[...]
) &
done
wait # pause until all background processes are terminated
答案2
和zsh
:
do-calc() (
cd -- $1 &&
LD_LIBRARY_PATH=$software/ $software/calc \
-i /home/files/$1.txt \
-l /home/Str/Art.pdb \
-a 5.0 \
-rf /home/file/prot -cpu 1 opt -w ${1}_res > ${1}_WPA.log
)
autoload zargs
cd MainDir && zargs -rn1 -P12 -- ./*(N-/) -- do-calc
并行运行最多 12 个这些do-calc
函数。
对于任何具有进程替换支持的类似 Korn 的 shell(例如 bash——GNU shell)和 GNU 实用程序,您可以执行类似的操作:
export software
cd MainDir &&
xargs -0rn1 -P12 -a <(
LC_ALL=C find . -maxdepth 1 ! -name '.*' -xtype d -print0 |
sort -z
) sh -c '
cd -- "$1" &&
LD_LIBRARY_PATH="$software/" "$software/calc" \
-i "/home/files/$1.txt" \
-l /home/Str/Art.pdb \
-a 5.0 \
-rf /home/file/prot -cpu 1 opt -w "${1}_res" > "${1}_WPA.log"
' sh
答案3
使用 GNU Parallel 你会做类似的事情:
doit() {
dir="$1"
cd ${dir}
LD_LIBRARY_PATH="$software"/ "$software"/calc -i /home/files/"$dir.txt" -l /home/Str/Art.pdb -a 5.0 -rf /home/file/prot -cpu 1 opt -w ${dir}_res > ${dir}_WPA.log
}
export -f doit
cd MainDir
parallel doit ::: *
这将为每个 CPU 线程运行一个作业。如果您不喜欢这样,您可以将其调整为并行运行 13 个作业:
parallel -j13 doit ::: *
如果您有类似“:::”的文件,您需要执行以下操作:
LC_ALL=C find . -maxdepth 1 ! -name '.*' -xtype d -print0 |
parallel -0 doit
或者:
parallel --argsep /// -j13 doit /// *