脚本是在当前 shell 还是子 shell 下运行的程序?

脚本是在当前 shell 还是子 shell 下运行的程序?

我对以下内容感到困惑 - 如果我通过输入名称来执行脚本或在当前 shell 中运行程序

  1. 它在 $PATH 变量中搜索,以查找可执行文件的位置
  2. 一旦找到它,它是在当前 shell 中运行可执行文件还是会生成一个子 shell/进程来运行可执行文件?

我相信将生成一个新的子进程来运行可执行文件,但话虽如此,子进程如何知道(可执行文件的路径)来运行可执行文件? — 如果我修改了父 shell 中的 PATH,以便它可以找到可执行文件(仅使用 PATH=$PATH:/newpath/to/executable)但不执行导出

e.g., — I did not do an export here
$ PATH=$PATH:/path/to/executable
$ executable 

当父 shell 找到可执行文件时,它接下来会做什么(生成子进程?运行可执行文件?)。但同样,当编辑的 PATH 环境没有导出到子进程时,子进程如何找到可执行文件

答案1

通常不是家长来寻找$PATH。通常是内核。

在内部,生成一个新进程是fork (创建一个新进程但继续运行当前代码;父进程和子进程通常各自进入自己的进程)if分支),然后是执行*调用(用新的进程映像替换当前进程映像),其间带有可选内容(例如文件描述符重定向或信号设置)。

执行* pexec 系列的成员(exec 系列只是以不同的方式做同样的事情)使内核$PATH在解析其中没有斜杠的参数时搜索环境变量。

一旦路径被解析,内核就会尝试将其作为二进制文件运行,如果前者失败并且可执行文件确实有 shebang 行,则诉诸 shebang 行。如果使用 shebang 行,则运行其中指定的解释器并传递解析的路径。

答案2

子shell和子进程之间是有区别的。你问的是关于 subshel​​l 的。

每当父 shell 找到可执行文件时,它就会生成一个子 shell,子 shell 可以访问父 shell 的所有变量。这就是为什么 subshel​​l 也可以访问变量 PATH 的原因。

当父 shell 生成子进程时,子进程中对变量的访问将受到限制。

您可以通过以下命令进行检查。

取消设置a; a=1
(echo "a is $a in the subshel​​l")
sh -c 'echo "a is $a in the child shell"'

欲了解更多信息,请参阅链接子外壳信息

相关内容