微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Linux Pipes中的子shell,子过程和变量与常规的分叉命令

如何解决Linux Pipes中的子shell,子过程和变量与常规的分叉命令

我试图更多地了解linux中的进程如何在其执行环境中工作。 我严格遵守Bash shell及其解释方式。

所以,看看我是否理解正确:

  1. 在不是内置命令的bash shell中运行的任何命令中,bash首先应在子shell中进行分叉,以复制大多数父执行环境,包括别名+未导出的shell变量以及其他内容,然后执行exec(execv() )的程序实例。在短时间内,子进程仍在运行bash(因此,仅出于这个原因,我们可以将其命名为“ subshel​​l”),然后调用execv()并执行程序实例。
  2. 如果您运行的命令是内置命令,则在运行时,该命令将直接执行而不会分叉,因为它内置在bash shell中,因为它将例如在cd_builtin函数的“ cd”中调用
  3. 对于管道,在bash中,所有命令都在它们自己的子shell /子进程中启动,就像在“ 1”点解释的那样。 (不分叉另一个bash实例(如bash脚本的情况)),包括内置实例(例如在“ cd / etc | echo will”中),bash会首先分叉并在子级中调用cd_builtin,就像命令不是内置的,它也可以“回显”管道的一部分)
  4. 我在多篇文章中看到人们在谈论Shell变量(未导出)与导出环境变量时,也倾向于在子进程/子进程中使用术语“ Sub-shell”(就像我所说的那样)对我来说,看到从bash(在execv()之前短暂有一个bash子shell)的分叉进程中,exec可以访问别名和shell未导出变量的命令会产生一些混乱,而读取子进程不会我知道,如果我运行bash脚本,bash将派生bash的另一个实例并在那里运行脚本,而无权访问我未导出的变量或别名(因为别名不导出)

我理解正确吗?我知道我错过了一些事情。 谢谢!

解决方法

在bash的分叉过程中(在execv()之前有一个bash子shell),我仍然可以访问别名和shell未导出的变量

不,(写脚本的bash 用户)不能。这个短命的代码完成了exec程序所需的操作,仅此而已。它是bash可执行文件中的固定机器代码,而不是您可以控制的脚本。您不能使其访问别名和未导出的变量。只是不这样做。

如果您修改bash的源代码并在forkexec之间插入可访问这些内容的C代码,那么可以, you (bash author 从现在开始)可以访问它们。但是你为什么呢?

一旦调用execbash的内存就消失了,别名和shell未导出的变量也随之消失了。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。