我正在尝试学习 GNU Parallel,因为我有一个案例,我认为我可以轻松地并行化 bash 函数。因此,在尝试学习的过程中,我查阅了GNU并行手册,其中有一个示例...但我什至无法让它工作!也就是说:
(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.
如您所见,我什至无法运行这个简单的示例。因此,我可能正在做一些非常愚蠢和基本的事情......但我不知所措。
预计到达时间:根据评论者的建议(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:注意,我可以在脚本中调用“doit 1”,它就会这样做。所以这个函数是有效的,只是没有...导出?
您无法从定义 shell 的外部调用 shell 函数。 shell函数是shell内部的一个概念。
parallel
命令本身无法访问它。
在 bash 中调用
export -f doit
会通过环境导出该函数,以便子进程拾取该函数。但只有 bash 理解 bash 函数。一个(大)*子 bash 进程可以调用它,但不能调用其他程序,例如不能调用其他 shell。
根据消息“未找到命令”,您的首选 shell 似乎是 (t)csh。您需要告诉
parallel
来调用 bash。 parallel
调用由 SHELL
环境变量 1 指示的 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=SHELL
之外,您可能还需要传递
--env=doit
(请注意,这假设到 bash
的路径在任何地方都是相同的)。
command
参数的描述中有一个简短的注释,但它不是很明确(它应该解释 command
单词以空格作为分隔符连接起来,然后传递给 $SHELL -c
),并且 SHELL
甚至没有列在 环境变量 部分中。 (我鼓励您将此报告为错误;我不会这样做,因为我几乎从不使用这个程序。)
1 这是糟糕的设计,因为
SHELL
应该指示交互式命令行 shell 的用户界面首选项,而不是更改程序的行为。
自版本 20160722 起,您可以改为使用
env_parallel
:
doit() { echo "$@"; }
echo world | env_parallel doit Hello
您只需将其添加到
env_parallel
即可激活.bashrc
。您可以通过运行一次将其添加到.bashrc
:
env_parallel --install
在
zsh
中,这有效:
/usr/bin/parallel "$(where doit);doit" ::: 1 2 3