我对以下内容感到困惑 - 如果我通过输入名称来执行脚本或在当前 shell 中运行程序
- 它在 $PATH 变量中搜索,以查找可执行文件的位置
- 一旦找到它,它是在当前 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
分支),然后是执行*调用(用新的进程映像替换当前进程映像),其间带有可选内容(例如文件描述符重定向或信号设置)。
这执行* p
exec 系列的成员(exec 系列只是以不同的方式做同样的事情)使内核$PATH
在解析其中没有斜杠的参数时搜索环境变量。
一旦路径被解析,内核就会尝试将其作为二进制文件运行,如果前者失败并且可执行文件确实有 shebang 行,则诉诸 shebang 行。如果使用 shebang 行,则运行其中指定的解释器并传递解析的路径。
答案2
子shell和子进程之间是有区别的。你问的是关于 subshell 的。
每当父 shell 找到可执行文件时,它就会生成一个子 shell,子 shell 可以访问父 shell 的所有变量。这就是为什么 subshell 也可以访问变量 PATH 的原因。
当父 shell 生成子进程时,子进程中对变量的访问将受到限制。
您可以通过以下命令进行检查。
取消设置a; a=1
(echo "a is $a in the subshell")
sh -c 'echo "a is $a in the child shell"'
欲了解更多信息,请参阅链接子外壳信息