为什么不使用 <<EOF 而不是 cat <<EOF ?

Dan*_*ndo 5 zsh cat io-redirection

我想知道何时使用cat <<比简单地使用更可取<<。我正在 ZSH shell 中进行测试,并且

cat <<EOF
Hello world!
EOF
Run Code Online (Sandbox Code Playgroud)

输出相同的

<<EOF
Hello world!
EOF
Run Code Online (Sandbox Code Playgroud)

.

var=$(cat <<EOF
Hello world!
EOF
)
Run Code Online (Sandbox Code Playgroud)

具有相同的变量值

var=$(<<EOF
Hello world!
EOF
)
Run Code Online (Sandbox Code Playgroud)

两种形式的 here-doc 之间的实际区别是什么?

hch*_*baw 5

只要 zsh 默认行为(例如调用zsh -f),两个示例之间就没有区别。我们可以检查跟踪输出与调用两个例子zsh -x -fcat将即使在后一种情况下,居然要求。

尽管这些差异在没有命令的重定向中zshmisc(1)进行了描述,但. zsh 将在没有命令的情况下以多种方式进行重定向,因此我们可以对其进行处理以免破坏任何内容:

  • cat显式使用。
  • 设置本地选项/参数。

没有命令的重定向

当一个简单的命令包含一个或多个重定向运算符和零个或多个参数赋值,但没有命令名称时,zsh 可以以多种方式运行。

如果未设置参数NULLCMD或设置了选项CSH_NULLCMD,则会导致错误。这是 csh 行为,在模拟 csh 时默认设置CSH_NULLCMD

如果设置了选项SH_NULLCMD,内置的 ':' 将作为具有给定重定向的命令插入。这是模拟 sh 或 ksh 时的默认设置。

否则,如果设置了参数NULLCMD,其值将用作具有给定重定向的命令。如果同时设置了NULLCMDREADNULLCMD,那么当重定向是输入时,将使用后者的值而不是前者的值。NULLCMD的默认值是“cat”,READNULLCMD的默认值是“ more ”。因此

< 文件

在标准输出上显示文件的内容,如果是终端则使用分页。NULLCMDREADNULLCMD可能指的是 shell 函数。

--没有命令的重定向,zshmisc(1)

因此,在后一种情况下,$var如果设置了 zsh shell 选项SH_NULLCMD等,则不会设置。

# I've tested with running `zsh -f` to check the various behaviors.
test-nullcmd () {
  local var=$(<<EOF
Hello world!
EOF
)
  echo "$var"
}

test-nullcmd
#> Hello world!

() {
  setopt localoptions shnullcmd
  test-nullcmd
}
# nothing will be printed

() {
  setopt localoptions cshnullcmd
  test-nullcmd
}
# test-nullcmd:1: redirection with no command (error)

() {
  local NULLCMD=
  test-nullcmd
}
# test-nullcmd:1: redirection with no command (error)
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我们可以使用command catcat不仅仅是为了防止别名扩展。