当我在 CentOS 的 SSH 终端中使用以下代码时,它工作正常:
paste <(printf "%s\n" "TOP")
Run Code Online (Sandbox Code Playgroud)
但是,如果我将相同的行代码放在 shell 脚本(test.sh)中并从终端运行 shell 脚本,它会抛出错误,如下所示
./test.sh: line 30: syntax error near unexpected token ('
./test.sh: line 30: paste <(printf "%s\n" "TOP")
Run Code Online (Sandbox Code Playgroud)
我该如何解决这个问题?
cuo*_*glm 28
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")
Run Code Online (Sandbox Code Playgroud)
或者bash
是用--enable-strict-posix-default
选项构建的。
在这里,您不需要进程替换,您可以使用标准的 shell 管道:
printf "%s\n" "TOP" | paste -
Run Code Online (Sandbox Code Playgroud)
-
是告诉paste
从 stdin 读取数据的标准方法。对于某些paste
实现,您可以省略它,尽管这不是标准的。
在粘贴多个命令的输出时会有用,例如:
paste <(cmd1) <(cmd2)
Run Code Online (Sandbox Code Playgroud)
在支持 的系统上/dev/fd/n
,可以通过以下方式完成sh
:
{ cmd1 4<&- | { cmd2 3<&- | paste /dev/fd/3 -; } 3<&0 <&4 4<&-; } 4<&0
Run Code Online (Sandbox Code Playgroud)
(这是<(...)
内部所做的)。