如果通过外壳脚本,exec()是否为每个命令调用fork?

对于传递给exec()的shell脚本中的每个命令,它是否分支并在子进程中运行? 假设我有一个名为test.sh的shell脚本,其中包含以下内容;

#!/bin/bash

echo Hello
echo There

我想知道的是,如果我要在C程序中的test.sh上调用execvp(),那么如何处理一系列命令。

对于脚本中的每个命令,在返回父级并对下一个命令重复之前,是否有一个派生后跟该命令的另一个exec调用?

到目前为止,我已经在这个确切的示例上使用了strace。我的发现是,如果我在脚本中添加了两个回显,则不会调用clone()(我相信这相当于分叉?),但是如果我将两只单独的猫这样:

#!/bin/bash

cat file1
cat file2

然后,我在strace中找到两个要克隆的调用。同时,单独跟踪单个cat调用,而不从shell脚本上的execvp调用运行它,不会在strace中产生任何克隆。

我非常希望澄清exec调用处理shell脚本的方式。

iCMS 回答:如果通过外壳脚本,exec()是否为每个命令调用fork?

bash shell具有许多内置命令,它们在与shell相同的过程中执行。 +---+--------+-----+-----+ |ID |Name |Marks|Grade| +---+--------+-----+-----+ |1 |Julia |88 |9 | |2 |Samantha|68 |7 | |3 |Maria |99 |10 | |4 |Scarlet |78 |8 | |5 |Ashley |63 |7 | |6 |Jane |81 |9 | +---+--------+-----+-----+ 命令是内置命令之一。

echo在外部程序中,因此外壳程序必须catfork才能创建进程并运行程序。

,

一些命令内置在外壳中,因此它们不需要派生。必须内置实现控制流的所有命令(例如ifwhilecase)。更改外壳程序状态的命令也必须内置,例如{{1} }和cd

此外,许多简单的命令作为Shell内置实现。其中包括ulimitecho。因此,使用两个printf命令在第一个脚本中看不到任何派生。

echo命令(本身是内置命令)可用于显示哪些命令是内置命令。例如,type报告type echo,但echo is a shell builtin报告type cat

最后,脚本的退出状态与最后一个命令的退出状态相同。因此,作为优化,它不会派生上一个命令,而只是执行它。这就是为什么当脚本有两个cat is /bin/cat命令而不是只有一个命令时看到叉子的原因。

本文链接:https://www.f2er.com/2225723.html

大家都在问