GNU Parallel 和 Bash 函数:如何运行手册中的简单示例
Posted
技术标签:
【中文标题】GNU Parallel 和 Bash 函数:如何运行手册中的简单示例【英文标题】:GNU Parallel and Bash functions: How to run the simple example from the manual 【发布时间】:2014-07-11 22:27:24 【问题描述】:我正在尝试学习 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:请注意,我可以在脚本中调用“doit 1”,例如,它会执行此操作。所以这个函数是有效的,只是没有......导出?
【问题讨论】:
你确定你有 GNU 并行,而不是 Tollef Fog Heen 的版本吗? @larsmans,它是 GNU 并行:(247) $ parallel --version GNU parallel 20140522 @shellter,我试过了。同样的答案。 它在我的 OSX 下的 Mac 上运行良好。您是否使用chmod +x tpar.bash
使tpar.bash
可执行
在doit()
前面加function
有帮助吗
【参考方案1】:
您不能从定义它的 shell 外部调用 shell 函数。 shell函数是shell内部的一个概念。 parallel
命令本身无法访问它。
在 bash 中调用 export -f doit
通过环境导出函数,以便它被子进程拾取。但只有 bash 理解 bash 函数。 (grand)*child 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
的路径在任何地方都是相同的)。
是的,这个奇怪的地方应该在手册中更突出地提到。在<em>command</em>
argument的描述中有一个简短的注释,但不是很明确(它应该解释<em>command</em>
单词以空格作为分隔符然后传递给$SHELL -c
)和@987654339 @ 甚至没有在 environment variables 部分中列出。 (我鼓励您将此报告为错误;我不这样做是因为我几乎不使用此程序。)
¹ 这是一个糟糕的设计,因为 SHELL
应该指示交互式命令行 shell 的用户界面偏好,而不是改变程序的行为。
【讨论】:
@larsmansexport
在脚本顶部更简单,但确实为parallel
命令(及其子进程)设置SHELL
也是一种选择。【参考方案2】:
从 20160722 版本开始,您可以改用 env_parallel
:
doit() echo "$@";
echo world | env_parallel doit Hello
您只需将env_parallel
添加到.bashrc
即可激活它。您可以通过运行一次将其添加到.bashrc
:
env_parallel --install
【讨论】:
注意env_parallel --install
会将运行which env_parallel.bash
的行附加到.bashrc
,因此只需要运行一次。以上是关于GNU Parallel 和 Bash 函数:如何运行手册中的简单示例的主要内容,如果未能解决你的问题,请参考以下文章
GNU Parallel:如何从gnu并行管道接收stdin,就像它来自文件一样?
sh 使用cytominer_scripts和GNU parallel并行处理平板