shell如何执行程序?

shell如何执行程序?

如果我使用 gcc 编译一个程序,并尝试从 bash shell 执行它,那么 bash 执行它的确切步骤顺序是什么?

我知道涉及到fork(),,,,(和其他事情),但是有人可以给出准确的步骤顺序和一些合适的阅读参考吗execve()loaderdynamic linker

编辑:

从答案来看,这个问题似乎蕴含着多种可能性。我想缩小范围到一个简单的情况:

(test.c 只是打印 hello world)

$ gcc test.c -o test
$ ./test

上述情况( )中的步骤是什么./test,特别是在某些子进程中启动 bash 程序,进行加载、链接等?

答案1

嗯,确切的顺序可能会有所不同,因为可能有一个 shell 别名或函数在执行实际程序之前首先被扩展/解释,然后限定文件名 ( /usr/libexec/foo) 与将在所有目录中查找的文件名之间存在差异环境PATH变量(只是foo)。此外,执行的细节可能会使事情变得复杂,因为foo | bar | zot需要 shell 进行更多工作(一些fork(2)dup(2)、当然还有 ,pipe(2)以及其他系统调用),而类似的exec foo工作则要少得多,因为 shell 只是将其自身替换为新程序(即,它没有fork)。同样重要的是进程组(尤其是前台进程组,SIGINT当有人开始混搭Ctrl+时,其所有 PID 都会被占用) C、会话以及作业是否将在后台运行、受监视 ( foo &) 或后台被忽略 ( foo & disown)。 /O 重定向细节也会改变一些事情,例如,标准输入是否被 shell ( foo <&-) 关闭,或者文件是否作为 stdin ( foo < blah) 打开。

strace或类似的信息将提供有关此过程中进行的特定系统调用的信息,并且每个调用都应该有手册页。合适的系统级阅读可以是 Stevens 的“UNIX 环境中的高级编程”中的任意章节,而 shell 书籍(例如“从 Bash 到 Z Shell”)将更详细地介绍 shell 方面的内容。

答案2

假设教科书示例 shell(为了代码清晰)已经运行(因此动态链接器已完成),您提到的命令将要求 shell 进行以下系统调用:

  • 读取:在本例中获取下一个命令 gcc
  • fork:需要两个进程,我们假设父进程的 pid 为 500,子进程用于说明。
  • 父进程将调用 wait(501),同时子进程将调用 exec。此时,shell 不再在 pid 501 上运行。gcc 进行大量系统调用,至少包括 open、close、read、write、chmod、fork、exec、wait 和 exit。
  • 当gcc调用exit时,wait会返回,调用write来显示提示符,然后重复该过程。

当然,更复杂的命令会增加这个基本序列的复杂性。基本复杂性的两个简单示例是基本 io 重定向,其中在 fork 与 exec 和后台进程之间插入打开、关闭、dup 序列,其中跳过等待(并将另一个等待添加到 sigchld 处理程序)。

答案3

我建议阅读部分8.4.6 使用fork和execve运行程序

http://www.groupes.polymtl.ca/inf2610/documentation/ComputerSystemBook.pdf

相关内容