当我在 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 调用时sh
,bash
进入 posix 模式(Bash 启动文件 - 使用名称 sh 调用)。在 5.1 之前的 bash 版本中,流程替代在 posix 模式下调用时支持被禁用,导致语法错误。
如果您直接调用该脚本应该可以工作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
选项构建的。
在这里,你不需要进程替换,你可以使用标准的外壳管道:
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")'