导出的BASH函数中的进程替换在OS X中不起作用?

时间:2015-11-20 04:54:01

标签: macos bash gnu-parallel

考虑以下(不可否认的荒谬)最小的非工作示例:

#!/usr/bin/env bash

test_func() {
  echo "$1" \
    | tee >(cat - > test) \
    | cat }

export -f test_func

parallel test_func :::: <(seq 1 4)

在BASH版本3.2.57(1)下 - 在OS X版本10.11.1上发布,这会产生以下错误:

sh: test_func: line 0: syntax error near unexpected token `('
sh: test_func: line 0: `test_func () {  echo "$1" | tee >(cat - > test) | cat -'
sh: error importing function definition for `test_func'

在OS X中导出的BASH函数中没有进程替换?

2 个答案:

答案 0 :(得分:1)

我的想法太长了,无法发表评论,所以我在回答中写下来。

首先,Bash的Bourne shell仿真似乎存在缺陷(请注意,OS X上的/bin/sh实际上是Bash):它尝试导入以bash导出的函数,这显然是错误的来源。为了测试这个:

> func () { echo 'Exported function leaked into sh.'; } && export -f func && /bin/sh -c func
Exported function leaked into sh.

例如,一个简单的进程替换(在Bourne shell中不存在)会将其吹走:

> func () { cat <(echo yay); } && export -f func && /bin/sh -c :
/bin/sh: func: line 0: syntax error near unexpected token `('
/bin/sh: func: line 0: `func () {  cat <(echo yay)'
/bin/sh: error importing function definition for `func'

注意我在/bin/sh子shell中没有做任何事情(我只运行:)。

至于为何在运行parallel时看到这些错误消息,我认为这是shparallel部分,链中某处不必要的调用问题。请注意,即使您使用硬编码SHELL甚至PARALLEL_SHELL,问题也不会消失(请参阅此页面了解此环境变量的文档),即运行SHELL=/bin/bash parallel ...或{{1没有帮助,所以这显然是一个问题。但是,PARALLEL_SHELL=/bin/bash parallel ...(或sh仿真模式中的Bash)在非交互式调用时不会尝试读取任何启动文件,因此很难收集调用sh的确切证据(甚至简短地说)链中。

我没时间查看sh的10k行源代码以确认我的猜测(奇怪的是,就此而言;我不明白为什么parallel应该是已调用),因此您应该发送电子邮件至bug-parallel@gnu.org或parallel@gnu.org以获得一些专家意见。并行的maintainer也潜伏在这里。

答案 1 :(得分:1)

在大多数系统的git版本[dd793ce]中修复。

对于dragonfly,freebsd,netbsd,qnx和unixware,您需要设置PARALLEL_SHELL:

PARALLEL_SHELL=/bin/bash parallel --onall -S bsdserver 'func() { cat <(echo bash only construct); };export -f func; parallel func ::: ' ::: 1