据我所知,Linux 中有两个执行阶段,处理我们运行的每个命令。我会按照我的理解来命名,因为我不知道原来的措辞:
Shell 处理 --- shell 编辑命令(将其分割到不同的行等),所有这些都是在与当前 shell 不同的 shell 中完成的。
shell 处理后执行结果(在我们使用的原始 shell 中)。
有人可以回答这些操作的名称并参考他认为最适合新学习者的一些阅读材料吗?
答案1
- Shell 处理 --- shell 编辑命令(将其分割到不同的行等)
是的,有点像。 shell 将命令作为单个字符串(通常是一行输入)获取,并将其转换为一组字符串,这些字符串实际上转到它最终运行的可执行文件。 shell 将空格分隔的单词从单个字符串拆分为多个字符串,还处理引号、扩展变量等。
所以,像
ls "$options" "/filename with spaces"
可能会产生三个字符串ls
、-l
(来自 的值$options
)和/filename with spaces
(删除引号)。这些被传递给exec()
运行程序的系统调用。
所有这些都是在与当前 shell 不同的 shell 中完成的。
不,不是真的。一些 shell 扩展(例如$( ... )
)会生成子 shell 来完成艰苦的工作,但对于常规的“简单”命令行来说,这种情况不会发生。
- shell 处理后执行结果(在我们使用的原始 shell 中)。
在解析命令行之后实际执行程序在逻辑上是一个独立的步骤。但从技术上讲,这发生在另一个进程中,因为在 Unix 上运行另一个程序的方式涉及首先调用fork()
,它创建一个新进程作为第一个进程的副本,然后调用exec()
用实际程序替换这个(shell 的)副本运行(ls
在示例中说)。
如果命令以exec
(开头exec ls
,则跳过分叉,并且 shell 将其自身替换为它正在启动的命令。
就像评论中提到的那样,shell 内置命令(就像echo
在许多 shell 中一样)也经常在同一进程中运行,而无需分叉。
(以上所有内容都有些简化。真实的 shell 可能具有此处未描述的其他功能。)