为什么不使用 <<EOF 而不是 cat <<EOF?
Why not using <<EOF instead of cat <<EOF?
我想知道什么时候使用 cat <<
比仅使用 <<
更可取。我正在 ZSH shell 和
中进行测试
cat <<EOF
Hello world!
EOF
输出相同的
<<EOF
Hello world!
EOF
.
var=$(cat <<EOF
Hello world!
EOF
)
具有与
相同的变量值
var=$(<<EOF
Hello world!
EOF
)
两种形式的 here-doc 之间的实际区别是什么?
所描述的行为仅限于 zsh。在 zsh 上,与不必要地调用外部二进制文件 (/bin/cat
) 相比,这是一个显着的性能增强。
如果您想将 heredoc 的内容发送到标准输出,而无需在 POSIX shell(例如 bash)上启动外部工具(例如 cat
)的开销,您而是需要如下内容:
# read heredoc into $var, terminated by first NUL, w/ truthy exit status
IFS= read -r -d '' var <<'EOF' ||:
content goes here
EOF
# emit $var to stdout
printf '%s' "$var"
zsh 语法虽然不受 POSIX 的保证,但比 read; printf
方法简洁得多,同时比 cat
.
快得多
只要 zsh 默认行为(例如调用 zsh -f
),两个示例之间就没有差异。我们可以通过调用带有 zsh -x -f
的两个示例来检查跟踪输出,即使在后一种情况下,cat
也会被实际调用。
尽管 Redirections with no command, zshmisc(1)
中描述了这些差异。 zsh 将以多种方式在没有命令的情况下进行重定向,因此我们可以做到不破坏任何东西:
- 明确使用
cat
。
- 设置localoptions/parameters.
Redirections with no command
When a simple command consists of one or more redirection operators and zero or more parameter assignments, but no command name, zsh can behave in several ways.
If the parameter NULLCMD is not set or the option CSH_NULLCMD is set, an error is caused. This is the csh behavior and CSH_NULLCMD is set by default when emulating csh.
If the option SH_NULLCMD is set, the builtin ‘:’ is inserted as a command with the given redirections. This is the default when emulating sh or ksh.
Otherwise, if the parameter NULLCMD is set, its value will be used as a command with the given redirections. If both NULLCMD and READNULLCMD are set, then the value of the latter will be used instead of that of the former when the redirection is an input. The default for NULLCMD is ‘cat’ and for READNULLCMD is ‘more’.Thus
< file
shows the contents of file on standard output, with paging if that is a terminal. NULLCMD and READNULLCMD may refer to shell functions.
因此,在后一种情况下,如果设置了 zsh shell 选项 SH_NULLCMD
,则不会设置 $var
,等等
# 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)
顺便说一句,我们可以使用 command cat
而不是 cat
来防止别名扩展。
我想知道什么时候使用 cat <<
比仅使用 <<
更可取。我正在 ZSH shell 和
cat <<EOF
Hello world!
EOF
输出相同的
<<EOF
Hello world!
EOF
.
var=$(cat <<EOF
Hello world!
EOF
)
具有与
相同的变量值var=$(<<EOF
Hello world!
EOF
)
两种形式的 here-doc 之间的实际区别是什么?
所描述的行为仅限于 zsh。在 zsh 上,与不必要地调用外部二进制文件 (/bin/cat
) 相比,这是一个显着的性能增强。
如果您想将 heredoc 的内容发送到标准输出,而无需在 POSIX shell(例如 bash)上启动外部工具(例如 cat
)的开销,您而是需要如下内容:
# read heredoc into $var, terminated by first NUL, w/ truthy exit status
IFS= read -r -d '' var <<'EOF' ||:
content goes here
EOF
# emit $var to stdout
printf '%s' "$var"
zsh 语法虽然不受 POSIX 的保证,但比 read; printf
方法简洁得多,同时比 cat
.
只要 zsh 默认行为(例如调用 zsh -f
),两个示例之间就没有差异。我们可以通过调用带有 zsh -x -f
的两个示例来检查跟踪输出,即使在后一种情况下,cat
也会被实际调用。
尽管 Redirections with no command, zshmisc(1)
中描述了这些差异。 zsh 将以多种方式在没有命令的情况下进行重定向,因此我们可以做到不破坏任何东西:
- 明确使用
cat
。 - 设置localoptions/parameters.
Redirections with no command
When a simple command consists of one or more redirection operators and zero or more parameter assignments, but no command name, zsh can behave in several ways.
If the parameter NULLCMD is not set or the option CSH_NULLCMD is set, an error is caused. This is the csh behavior and CSH_NULLCMD is set by default when emulating csh.
If the option SH_NULLCMD is set, the builtin ‘:’ is inserted as a command with the given redirections. This is the default when emulating sh or ksh.
Otherwise, if the parameter NULLCMD is set, its value will be used as a command with the given redirections. If both NULLCMD and READNULLCMD are set, then the value of the latter will be used instead of that of the former when the redirection is an input. The default for NULLCMD is ‘cat’ and for READNULLCMD is ‘more’.Thus
< file
shows the contents of file on standard output, with paging if that is a terminal. NULLCMD and READNULLCMD may refer to shell functions.
因此,在后一种情况下,如果设置了 zsh shell 选项 SH_NULLCMD
,则不会设置 $var
,等等
# 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)
顺便说一句,我们可以使用 command cat
而不是 cat
来防止别名扩展。