意外标记“(”附近出现语法错误

意外标记“(”附近出现语法错误

当我在 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")

我该如何解决这个问题?

答案1

工艺替代POSIX 没有指定,所以并不是所有的 POSIX shell 都支持它,只有一些 shell 像bash, zsh, ksh88, ksh93

在 CentOS 系统中,/bin/sh/bin/bash.当bash使用 name 调用时shbash进入 posix 模式(Bash 启动文件 - 使用名称 sh 调用)。在 5.1 之前的 bash 版本中,流程替代在 posix 模式下调用时支持被禁用,导致语法错误。

如果您直接调用该脚本应该可以工作bashbash test.sh。如果没有,可能bash已经进入了 posix 模式。如果您bash以参数启动或启动时设置了--posix变量,则可能会发生这种情况:POSIXLY_CORRECTbash

$ 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选项构建的。

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

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")'

相关内容