意外令牌'('附近的语法错误


15

当我在CentOS的SSH终端中使用以下代码时,它可以正常工作:

paste <(printf "%s\n" "TOP")

但是,如果我将相同的行代码放置在shell脚本(test.sh)中并从终端运行shell脚本,它会引发错误

./test.sh: line 30: syntax error near unexpected token ('   
./test.sh: line 30:     paste <(printf "%s\n" "TOP")

我该如何解决这个问题?


如何准确,你运行它?什么 '#!' 行(如果有)启动您的脚本?您似乎正在调用不支持该语法的Shell解释器(例如dash而不是bash)。
steeldriver 2014年

#!/bin/sh在顶部。我执行了,bash test.sh但也没有用。
NecNecco

bash在POSIX模式下,也不支持该语法(使用--posix或调用时/bin/sh)。使用#!/bin/bash
jordanm 2014年

@NecNecco:POSIXLY_CORRECT启动时是否设置了变量bash
cuonglm 2014年

@jordanm切换到#!/bin/bash顶部可以解决此问题。
NecNecco

Answers:


23

进程替换不是由POSIX指定,所以不是所有的POSIX壳支持它,只有一些贝壳等bashzshksh88ksh93的支持。

Centos系统中,/bin/sh是的符号链接/bin/bash。当bash使用name调用时shbash进入posix模式(Bash Startup Files-用sh调用)。在posix模式下,process substitution不支持,导致语法错误。

如果bash直接调用,脚本应该可以工作bash test.sh。如果不是,则可能bash已进入posix模式。这可以,如果你开始可以发生bash--posix参数或变量POSIXLY_CORRECT被设置时bash开始:

$ bash --posix test.sh 
test.sh: line 54: syntax error near unexpected token `('
test.sh: line 54: `paste <(printf "%s\n" "TOP")'

$ POSIXLY_CORRECT=1 bash test.sh 
test.sh: line 54: syntax error near unexpected token `('
test.sh: line 54: `paste <(printf "%s\n" "TOP")

bash带有--enable-strict-posix-default选项。

在这里,您不需要进程替换,可以使用标准的shell管道:

printf "%s\n" "TOP" | paste -

-是告诉paste从stdin读取数据的标准方法。对于某些paste实现,您可以忽略它,尽管这不是标准的。

粘贴多个命令的输出时,如以下所示,将是有用的:

paste <(cmd1) <(cmd2)

在支持的系统上/dev/fd/n,可以通过以下方式完成sh

{ cmd1 4<&- | { cmd2 3<&- | paste /dev/fd/3 -; } 3<&0 <&4 4<&-; } 4<&0

(这是<(...)内部操作)。


2

这是另一个解决方法。不要运行命令,而是运行bash并使用-c将命令传递给bash:

bash -c 'paste <(printf "%s\n" "TOP")'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.