- shell等待用户输入。
- 用户输入一串命令,这些内容会回显在等待输入处。按下回车后,回车键入的字符'\n'被解释为换行,并激活阻塞shell的read系统调用。
- shell程序解析用户输入,把用户键入的文本行以空格分隔,每一串字符放在一个字符数组中,并一个指向字符数组的数组,将每个字符串数组的首地址保存进来。
注:如果这些数据作为shell某个函数的局部数据,那么会保存在用户栈中。 - 通过
如果shell判断用户执行一个前台作业,那么shell会调用fork函数创建一个子进程,并在子进程中调用execve函数,加载可以执行文件。
第一个参数就是shell解析用户输入时的第一个字符数组,即用户想要运行程序名字。
execve通过第一个参数来在调用进程中加载这个程序,失败返回-1,成功不返回。
execve第二个参数是一个存放字符指针的数组,正好对应了shell解析的结果。
当shell进程中的fork执行后,系统中创建了一个在当前时刻和shell一模一样的进程,当fork在这个子进程中返回后,会将从shell中解析的结果作为参数传递给execve(用户栈为shell进程的副本,自然有shell中的各种变量)。
而父进程,即shell,由于是前台作业,所以会等待子进程结束。
execve陷入内核后,内核使用了某种方法将execve的参数暂时保存下来,然后调用加载器,根据所要运行的程序的程序头部表映射新的用户地址空间,此时用户堆栈段为空,完成后跳转到程序入口点_start。
_start调用系统启动函数__libc_start_main。
此时用户栈中有了数据:
然后调用main函数。