- shell等待用戶輸入。
- 用戶輸入一串命令,這些內(nèi)容會回顯在等待輸入處。按下回車后,回車鍵入的字符'\n'被解釋為換行,并激活阻塞shell的read系統(tǒng)調(diào)用。
- shell程序解析用戶輸入,把用戶鍵入的文本行以空格分隔,每一串字符放在一個字符數(shù)組中,并一個指向字符數(shù)組的數(shù)組,將每個字符串數(shù)組的首地址保存進來。
注:如果這些數(shù)據(jù)作為shell某個函數(shù)的局部數(shù)據(jù),那么會保存在用戶棧中。 - 通過
如果shell判斷用戶執(zhí)行一個前臺作業(yè),那么shell會調(diào)用fork函數(shù)創(chuàng)建一個子進程,并在子進程中調(diào)用execve函數(shù),加載可以執(zhí)行文件。
第一個參數(shù)就是shell解析用戶輸入時的第一個字符數(shù)組,即用戶想要運行程序名字。
execve通過第一個參數(shù)來在調(diào)用進程中加載這個程序,失敗返回-1,成功不返回。
execve第二個參數(shù)是一個存放字符指針的數(shù)組,正好對應了shell解析的結(jié)果。
當shell進程中的fork執(zhí)行后,系統(tǒng)中創(chuàng)建了一個在當前時刻和shell一模一樣的進程,當fork在這個子進程中返回后,會將從shell中解析的結(jié)果作為參數(shù)傳遞給execve(用戶棧為shell進程的副本,自然有shell中的各種變量)。
而父進程,即shell,由于是前臺作業(yè),所以會等待子進程結(jié)束。
execve陷入內(nèi)核后,內(nèi)核使用了某種方法將execve的參數(shù)暫時保存下來,然后調(diào)用加載器,根據(jù)所要運行的程序的程序頭部表映射新的用戶地址空間,此時用戶堆棧段為空,完成后跳轉(zhuǎn)到程序入口點_start。
_start調(diào)用系統(tǒng)啟動函數(shù)__libc_start_main。
此時用戶棧中有了數(shù)據(jù):
然后調(diào)用main函數(shù)。