我正在尝试学习GNU Parallel,因为我有一个案例,我认为我可以轻松地并行化bash函数。所以在尝试学习时,我去了GNU Parallel manual那里有an example ...但我甚至无法让它工作!即:
(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.
正如您所看到的,我甚至无法获得运行的简单示例。因此,我可能做了一些非常愚蠢和基本的事情......但我不知所措。
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.
ETA2:请注意,我可以在脚本中调用&#39; doit 1&#39 ;,比如说,它会这样做。所以这个功能是有效的,它不是......导出的吗?
答案 0 :(得分:26)
您无法从定义它的shell外部调用shell函数。 shell函数是shell中的一个概念。 parallel
命令本身无法访问它。
在bash中调用export -f doit
通过环境导出该函数,以便子进程选择它。但只有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
如果您只想为执行SHELL
命令设置parallel
而不是为脚本的其余部分设置:
doit () { … }
export -f doit
SHELL=$(type -p bash) parallel doit ::: 1 2 3
我不确定如何处理远程作业,除了--env=doit
之外,您可能需要传递--env=SHELL
(请注意,这假设bash
的路径相同到处)。
是的,这个奇怪之处应该在手册中更加突出。在command
argument的描述中有一个简短的注释,但它不是非常明确(它应该解释为command
个单词与空格连接作为分隔符然后传递给{{1} }),$SHELL -c
部分甚至没有列出SHELL
。 (我鼓励你把这个报告为一个bug;我不是这样做的,因为我几乎没有使用过这个程序。)
¹这是一个糟糕的设计,因为SHELL
应该表示交互式命令行shell的用户界面首选项,而不是更改程序的行为。
答案 1 :(得分:3)
从版本20160722开始,您可以使用env_parallel
:
doit() { echo "$@"; }
echo world | env_parallel doit Hello
您只需将env_parallel
添加到.bashrc
env_parallel --install
{{1}}