为什么`avar = 7; exec $avar< <(ls)` 让我的 shell 崩溃
Why does `avar=7; exec $avar< <(ls)` make my shell crash
所以我想看看我是否可以有可变编号的输出位置(7)。我想知道这里发生了什么,以至于导致整个 shell 崩溃?
命令:avar=7; exec $avar< <(ls)
按要求回答问题
exec 7
尝试用名为 7
的程序 替换 shell,就像 exec ls
替换 shell 和一个名为 ls
的程序。无论哪种方式,shell 退出。
因为在 变量扩展发生之前 解析了重定向语法(根据 bash 较新版本中添加的特定豁免,而不是 Apple 发布的版本),这不任何事件的行为类似于 exec 7< <(ls)
.
新 Shell 版本中的参数化重定向
但是如果您 有新版本的 bash 怎么办?如果不使用 eval
,您仍然无法将变量放在重定向的左侧,但是您 do 可以自动分配以前未使用的文件描述符(并且您可以在右侧使用变量)。
# in bash 4.3+ only, allocate a new file descriptor for the process substitution
exec {ls_fd}< <(ls)
# copy that FD to number 7, then close the automatically-assigned one
exec 7<&"$ls_fd" {ls_fd}>&-
要完全执行您要求的操作,您最终会使用 eval
:
avar=7
# again, this requires a newer bash than the stock MacOS one
exec {ls_fd}< <(ls)
printf -v cmd 'exec %d<&"$ls_fd"' "$avar" && eval "$cmd"
exec {ls_fd}>&-
所以我想看看我是否可以有可变编号的输出位置(7)。我想知道这里发生了什么,以至于导致整个 shell 崩溃?
命令:avar=7; exec $avar< <(ls)
按要求回答问题
exec 7
尝试用名为 7
的程序 替换 shell,就像 exec ls
替换 shell 和一个名为 ls
的程序。无论哪种方式,shell 退出。
因为在 变量扩展发生之前 解析了重定向语法(根据 bash 较新版本中添加的特定豁免,而不是 Apple 发布的版本),这不任何事件的行为类似于 exec 7< <(ls)
.
新 Shell 版本中的参数化重定向
但是如果您 有新版本的 bash 怎么办?如果不使用 eval
,您仍然无法将变量放在重定向的左侧,但是您 do 可以自动分配以前未使用的文件描述符(并且您可以在右侧使用变量)。
# in bash 4.3+ only, allocate a new file descriptor for the process substitution
exec {ls_fd}< <(ls)
# copy that FD to number 7, then close the automatically-assigned one
exec 7<&"$ls_fd" {ls_fd}>&-
要完全执行您要求的操作,您最终会使用 eval
:
avar=7
# again, this requires a newer bash than the stock MacOS one
exec {ls_fd}< <(ls)
printf -v cmd 'exec %d<&"$ls_fd"' "$avar" && eval "$cmd"
exec {ls_fd}>&-