【发布时间】:2020-12-18 18:17:53
【问题描述】:
我正在尝试基于 bash 行为实现我自己的 shell,我注意到有些命令不适用于管道,
就像我有:export AAA=test | cat,例如这个命令不会将 AAA 添加到环境变量中,所以就像导出不起作用,
但如果我写:export | cat,它将打印环境变量,所以在这里,它就像导出工作,
与退出相同,未设置 ....
那么有人可以向我解释这种行为以及我如何实现它吗?
【问题讨论】:
我正在尝试基于 bash 行为实现我自己的 shell,我注意到有些命令不适用于管道,
就像我有:export AAA=test | cat,例如这个命令不会将 AAA 添加到环境变量中,所以就像导出不起作用,
但如果我写:export | cat,它将打印环境变量,所以在这里,它就像导出工作,
与退出相同,未设置 ....
那么有人可以向我解释这种行为以及我如何实现它吗?
【问题讨论】:
export 在这两种情况下都在 subshell 中执行,其环境是父 shell 的副本。
使用export | cat,您可以对子shell 环境的内容进行分类,这些内容并未根据从父级接收到的副本进行修改,因此您获得的输出与单独export 的输出相匹配。
使用export AAA=test | cat,您可以修改子shell 的环境,而不是调用shell。此外,在这种情况下,export 不会写入任何输出供cat 读取。管道完成后,子shell 将被销毁,控制权恢复到当前未修改环境的shell。
【讨论】:
export AAA=test | cat 确实 not 实际上修改了 subshell 的环境。 如果该子shell 生成了另一个子shell,则该子shell 的环境将在其环境中具有AAA,但运行export 命令的子shell 没有修改过的环境。
export 都不会修改 shell 的环境。它只会影响后续执行命令的环境。
export AAA=test 肯定将子shell 中名为AAA 的变量的值设置为test。从父环境初始化的变量和稍后设置的变量之间确实没有区别(AFAIK)。确实,导出名称只是意味着在构建孩子的环境时将其标记为使用,而不是将变量推入某个单独的命名空间。
bash,如果设置了lastpipe 选项)将在当前shell 中执行final 命令。我不知道任何 shell 会在当前 shell 中执行任何其他命令,尽管我不相信 POSIX 实际上禁止它。