GNU Parallel和Bash函数:如何运行手册中的简单示例

时间:2014-05-22 18:15:01

标签: bash gnu-parallel

我正在尝试学习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 ;,比如说,它会这样做。所以这个功能是有效的,它不是......导出的吗?

2 个答案:

答案 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}}