For*_*ran 17 bash gnu-parallel
我正在尝试学习GNU Parallel,因为我有一个案例,我认为我可以轻松地并行化bash函数.所以在尝试学习的时候,我去了GNU Parallel手册,里面有一个例子 ......但我甚至无法让它工作!以机智:
(232) $ bash --version
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
(233) $ cat tpar.bash
#!/bin/bash
echo `which parallel`
doit() {
echo Doing it for $1
sleep 2
echo Done with $1
}
export -f doit
parallel doit ::: 1 2 3
doubleit() {
echo Doing it for $1 $2
sleep 2
echo Done with $1 $2
}
export -f doubleit
parallel doubleit ::: 1 2 3 ::: a b
(234) $ bash tpar.bash
/home/mathomp4/bin/parallel
doit: Command not found.
doit: Command not found.
doit: Command not found.
doubleit: Command not found.
doubleit: Command not found.
doubleit: Command not found.
doubleit: Command not found.
doubleit: Command not found.
doubleit: Command not found.
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我甚至无法获得运行的简单示例.因此,我可能正在做一些非常愚蠢和基本的事情......但我不知所措.
ETA:根据评论者的建议(chmod + x,set -vx):
(27) $ ./tpar.bash
echo `which parallel`
which parallel
++ which parallel
+ echo /home/mathomp4/bin/parallel
/home/mathomp4/bin/parallel
doit() {
echo Doing it for $1
sleep 2
echo Done with $1
}
export -f doit
+ export -f doit
parallel doit ::: 1 2 3
+ parallel doit ::: 1 2 3
doit: Command not found.
doit: Command not found.
doit: Command not found.
doubleit() {
echo Doing it for $1 $2
sleep 2
echo Done with $1 $2
}
export -f doubleit
+ export -f doubleit
parallel doubleit ::: 1 2 3 ::: a b
+ parallel doubleit ::: 1 2 3 ::: a b
doubleit: Command not found.
doubleit: Command not found.
doubleit: Command not found.
doubleit: Command not found.
doubleit: Command not found.
doubleit: Command not found.
Run Code Online (Sandbox Code Playgroud)
ETA2:注意,我可以在脚本中调用'doit 1',比如说,它会做到这一点.所以功能是有效的,它不是......导出的?
Gil*_*il' 28
您无法从定义它的shell外部调用shell函数.shell函数是shell中的一个概念.该parallel命令本身有没有办法来访问它.
调用export -f doitbash通过环境导出函数,以便子进程获取它.但只有bash才能理解bash函数.(宏)*子bash进程可以调用它,但不能调用其他程序,例如其他shell.
通过消息"未找到命令",您的首选shell似乎是(t)csh.你需要告诉parallel调用bash.parallel调用SHELL环境变量¹指示的shell ,因此将其设置为指向bash.
export SHELL=$(type -p bash)
doit () { … }
export -f doit
parallel doit ::: 1 2 3
Run Code Online (Sandbox Code Playgroud)
如果您只想设置SHELL执行parallel命令而不是脚本的其余部分:
doit () { … }
export -f doit
SHELL=$(type -p bash) parallel doit ::: 1 2 3
Run Code Online (Sandbox Code Playgroud)
我不知道该如何处理远程作业,您可能需要通过--env=SHELL除--env=doit(注意,这个假设的路径bash是一样的无处不在).
是的,这个奇怪之处应该在手册中更加突出.在command参数的描述中有一个简短的注释,但它不是非常明确(它应该解释这些command单词与空格连接作为分隔符然后传递给$SHELL -c),SHELL甚至没有列在环境变量部分中.(我鼓励你把这个报告为一个bug;我不是这样做的,因为我几乎没有使用过这个程序.)
¹ 这是一个糟糕的设计,因为SHELL它应该表示交互式命令行shell的用户界面首选项,而不是改变程序的行为.
从版本20160722开始,您可以改为使用env_parallel:
doit() { echo "$@"; }
echo world | env_parallel doit Hello
Run Code Online (Sandbox Code Playgroud)
您只需env_parallel将其添加到中即可激活.bashrc。您可以.bashrc通过运行一次将其添加到:
env_parallel --install
Run Code Online (Sandbox Code Playgroud)