bash - bash 变量何时导出到子 shell 和/或可由脚本访问?

标签 bash shell subprocess subshell

我对 bash 变量是否导出到子 shell 以及何时可以通过脚本访问它们感到困惑。到目前为止,我的经验让我相信 bash 变量会自动可供子 shell 使用。例如:

> FOO=bar
> echo $FOO
bar
> (echo $FOO)
bar

上面的内容似乎证明了 bash 变量可以在子 shell 中访问。

给定这个脚本:

#! /usr/bin/bash
# c.sh

func()
{
  echo before
  echo ${FOO}
  echo after
}

func

据我了解,在当前 shell 上下文中调用脚本可以使其访问当前 shell 的变量:

> . ./c.sh 
before
bar
after

如果我在没有“点空间”先例的情况下调用脚本...

> ./c.sh 
before

after

...不是说脚本是在子shell中调用的吗?如果是这样,并且当前 shell 的变量确实可用于子 shell(正如我从第一个代码块推断的那样),为什么 $FOO 不可用于 c.sh 什么时候这样运行?

同样,为什么当 c.sh 在括号内运行时 $FOO 也不可用 - 我理解这意味着在子 shell 中运行表达式:

> (./c.sh)
before

after

(如果这不会使这篇文章因太多问题而变得困惑:如果“./c.sh”和“(./c.sh)”两者在当前shell的子shell中运行脚本,两种调用方式有什么区别?)

最佳答案

(...)运行...在单独的环境中,使用子 shell 最容易实现的东西(并在 bash、dash 和大多数其他 POSIX-y shell 中实现)——也就是说,由 fork() 创建的子 shell ing 旧 shell,但不调用任何 execv -家庭功能。因此,父级的整个内存状态都会被复制,包括未导出的 shell 变量。对于子 shell,这正是您通常想要的:只是父 shell 进程镜像的副本,而不是用新的可执行镜像替换,从而保持其所有状态。

考虑(. shell-library.bash; function-from-that-library "$preexisting_non_exported_variable")举个例子:因为括号它 fork()是一个子 shell,但它随后获取 shell-library.bash 的内容直接在该 shell 内,而不替换由该 fork() 创建的 shell 解释器具有单独的可执行文件。这意味着function-from-that-library可以从父 shell 中看到非导出的函数和变量(如果是 execve() 'd,则看不到),并且启动速度更快一些(因为它不需要链接、加载等初始化一个新的 shell 解释器,就像 execve() 操作期间发生的那样);而且它对内存状态、shell 配置和进程属性(如工作目录)所做的更改不会修改调用它的父解释器(如果没有子 shell 并且它不是 fork() ,情况就会如此) 'd),因此父 shell 受到保护,不会受到库所做的配置更改的影响,这些更改可能会修改其后续操作。

<小时/>

./other-script相比之下,运行 other-script作为完全独立的可执行文件;在子 shell(不是子 shell!)被调用后,它保留非导出变量。其工作原理如下:

  • shell 调用 fork()创造一个 child 。此时,子级甚至还复制了未导出的变量状态。
  • child 打电话./other-script >>log.out指示操作系统将其替换为 open("log.out", O_APPEND) 的新实例。这次调用成功后,在子进程的PID下运行的进程是一个全新的程序,并且只有fdup() ed 变量仍然存在。

关于bash - bash 变量何时导出到子 shell 和/或可由脚本访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53312653/

相关文章:

bash - 在 awk 字符串中调用 'date' 命令,格式为 +%a

linux - 从脚本打开新的 gnome 终端并从当前脚本输入变量。

python - 如何异步获取子进程的标准输出数据?

linux - 如果之后使用管道,为什么 wait 会生成 “<pid> is not a child of this shell” 错误?

python - 如何检查子进程是否正确终止?

bash - bash 中变量不等式的正确语法是什么?

bash - Github 操作 - 错误 : Process completed with exit code 1

python - 如何从 Python 执行复杂的 shell 查找命令?

php - 查找特定日期的文件,然后搜索电话号码

linux - 在 shell 脚本中解析 ${1##*/}