linux - bash 4.4 不将变量传递给子 shell

标签 linux bash shell

Bash 4.4 和 4.3 在将变量传递到子 shell 或 heredocs 方面似乎表现不同。

来自@CharlesDuffy 的简单复制:

export var=0; var=1 cat <<<"$(env | grep '^var')"

Bash 4.4 输出 var=0,bash 4.3 输出 var=1

我用于重现问题的原始脚本:

TZ=Europe/London
timezone=Asia/Tokyo
echo TZ=$TZ
echo timezone=$timezone

date +%H:%M
TZ=$timezone date +%H:%M

IFS=':' TZ=$timezone read hour minute <<EOF
        $(date +%H:%M)
EOF
echo TZOUTER $hour-$minute

IFS=':' read hour minute <<EOF
        $(TZ=$timezone date +%H:%M)
EOF
echo TZINNER $hour-$minute

Bash 4.3 (Ubuntu 16.04) 提供:

TZ=Europe/London
timezone=Asia/Tokyo
14:52
22:52
TZOUTER 22-52
TZINNER 22-52

Bash 4.4(Ubuntu 17.04)提供:

TZ=Europe/London
timezone=Asia/Tokyo
13:53
22:53
TZOUTER 13-53
TZINNER 22-53

(在 bash 4.3 上,内部和外部方法都给出相同的时间,在 bash 4.4 上,TZOUTER 给出原始 TZ 值)。

有谁知道为什么会这样?我看过https://lists.gnu.org/archive/html/info-gnu/2016-09/msg00008.html但我不知道是哪个变化导致了行为的改变。

最佳答案

来自 2014-12-3 的详细变更日志条目:

subst.c

  • command_substitute: if running command substitution as part of expanding a redirection (expanding_redir == 1), flush any temporary environment we've inherited as part of this command, since we are not supposed to have access to the temporary environment. Since expanding_redir only controls access to the temporary environment for variable lookup and binding, we can turn it off in the subshell

具体来说,新增了如下代码:

  if (expanding_redir)
    {
      flush_temporary_env ();
      expanding_redir = 0;
    }

...这只是删除了 temporary_env 哈希表的所有内容,防止在 execute_simple_command 中调用 merge_temporary_env() 时临时环境变量被不适本地扩展() 在与重定向相关的扩展期间。

关于linux - bash 4.4 不将变量传递给子 shell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44049768/

相关文章:

ruby - 在 Ruby shell 脚本中运行 OS X `say` 命令而不退出

shell - 在 Linux shell 脚本中测试颜色支持

linux - 找不到 Linux 内核 v3.5 中的 trace_console 定义

linux - 如何在文件中每一行的开头均匀地添加一组值?

linux - 合并 log4j 日志行

macos - 使用 pkgbuild 打包不同的文件类型

linux - lmctfy 和 lxc 有什么区别

java - "ASCII"上下左右箭头代码

linux - 我的模式匹配出了什么问题?

linux - 如何使用linux shell命令将整个目录上传到ftp服务器?