【问题标题】:why some bash commands with pipe doesn't work为什么一些带有管道的 bash 命令不起作用
【发布时间】:2020-12-18 18:17:53
【问题描述】:

我正在尝试基于 bash 行为实现我自己的 shell,我注意到有些命令不适用于管道, 就像我有:export AAA=test | cat,例如这个命令不会将 AAA 添加到环境变量中,所以就像导出不起作用,

但如果我写:export | cat,它将打印环境变量,所以在这里,它就像导出工作, 与退出相同,未设置 .... 那么有人可以向我解释这种行为以及我如何实现它吗?

【问题讨论】:

    标签: c linux bash process pipe


    【解决方案1】:

    export 在这两种情况下都在 subshel​​l 中执行,其环境是父 shell 的副本。

    使用export | cat,您可以对子shell 环境的内容进行分类,这些内容并未根据从父级接收到的副本进行修改,因此您获得的输出与单独export 的输出相匹配。

    使用export AAA=test | cat,您可以修改子shell 的环境,而不是调用shell。此外,在这种情况下,export 不会写入任何输出供cat 读取。管道完成后,子shell 将被销毁,控制权恢复到当前未修改环境的shell。

    【讨论】:

    • Minor nit: export AAA=test | cat 确实 not 实际上修改了 subshel​​l 的环境。 如果该子shell 生成了另一个子shell,则该子shell 的环境将在其环境中具有AAA,但运行export 命令的子shell 没有修改过的环境。
    • 我想你没有理解我的问题,这里的问题是在管道的情况下,导出不会向我的 shell 的环境变量添加任何东西,但如果没有管道,它会继续按预期工作,和exit一样,如果有带有管道的exit,shell不会退出。
    • @REVERSI 无论是否在管道中,export 都不会修改 shell 的环境。它只会影响后续执行命令的环境。
    • @WilliamPursell 我认为这取决于您所说的“环境”。 export AAA=test 肯定将子shell 中名为AAA 的变量的值设置为test。从父环境初始化的变量和稍后设置的变量之间确实没有区别(AFAIK)。确实,导出名称只是意味着在构建孩子的环境时将其标记为使用,而不是将变量推入某个单独的命名空间。
    • @REVERSI 大多数 shell 通过为每个命令派生一个新进程来实现管道。一些shell(包括bash,如果设置了lastpipe 选项)将在当前shell 中执行final 命令。我不知道任何 shell 会在当前 shell 中执行任何其他命令,尽管我不相信 POSIX 实际上禁止它。
    猜你喜欢
    • 2019-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-27
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    相关资源
    最近更新 更多