溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

shell中exec解析

發(fā)布時(shí)間:2020-06-17 06:12:36 來(lái)源:網(wǎng)絡(luò) 閱讀:475 作者:Abigale2018 欄目:開(kāi)發(fā)技術(shù)

參考:《linux命令、編輯器與shell編程》 《unix環(huán)境高級(jí)編程》

  exec和source都屬于bash內(nèi)部命令(builtins commands),在bash下輸入man exec或man source可以查看所有的內(nèi)部命令信息。

bash shell的命令分為兩類(lèi):外部命令和內(nèi)部命令。外部命令是通過(guò)系統(tǒng)調(diào)用或獨(dú)立的程序?qū)崿F(xiàn)的,如sed、awk等等。內(nèi)部命令是由特殊的文件格式(.def)所實(shí)現(xiàn),如cd、history、exec等等。

  在說(shuō)明exe和source的區(qū)別之前,先說(shuō)明一下fork的概念。

  fork是linux的系統(tǒng)調(diào)用,用來(lái)創(chuàng)建子進(jìn)程(child process)。子進(jìn)程是父進(jìn)程(parent process)的一個(gè)副本,從父進(jìn)程那里獲得一定的資源分配以及繼承父進(jìn)程的環(huán)境。子進(jìn)程與父進(jìn)程唯一不同的地方在于pid(process id)。

環(huán)境變量(傳給子進(jìn)程的變量,遺傳性是本地變量和環(huán)境變量的根本區(qū)別)只能單向從父進(jìn)程傳給子進(jìn)程。不管子進(jìn)程的環(huán)境變量如何變化,都不會(huì)影響父進(jìn)程的環(huán)境變量。 

shell script:

有兩種方法執(zhí)行shell scripts,一種是新產(chǎn)生一個(gè)shell,然后執(zhí)行相應(yīng)的shell scripts;一種是在當(dāng)前shell下執(zhí)行,不再啟用其他shell。

新產(chǎn)生一個(gè)shell然后再執(zhí)行scripts的方法是在scripts文件開(kāi)頭加入以下語(yǔ)句

#!/bin/sh

一般的script文件(.sh)即是這種用法。這種方法先啟用新的sub-shell(新的子進(jìn)程),然后在其下執(zhí)行命令。

另外一種方法就是上面說(shuō)過(guò)的source命令,不再產(chǎn)生新的shell,而在當(dāng)前shell下執(zhí)行一切命令。

source:

source命令即點(diǎn)(.)命令。

在bash下輸入man source,找到source命令解釋處,可以看到解釋”Read and execute commands from filename in the current shell environment and …”。從中可以知道,source命令是在當(dāng)前進(jìn)程中執(zhí)行參數(shù)文件中的各個(gè)命令,而不是另起子進(jìn)程(或sub-shell)。

exec:

在bash下輸入man exec,找到exec命令解釋處,可以看到有”No new process is created.”這樣的解釋?zhuān)@就是說(shuō)exec命令不產(chǎn)生新的子進(jìn)程。那么exec與source的區(qū)別是什么呢?

exec命令在執(zhí)行時(shí)會(huì)把當(dāng)前的shell process關(guān)閉,然后換到后面的命令繼續(xù)執(zhí)行。

  1. 系統(tǒng)調(diào)用exec是以新的進(jìn)程去代替原來(lái)的進(jìn)程,但進(jìn)程的PID保持不變。因此,可以這樣認(rèn)為,exec系統(tǒng)調(diào)用并沒(méi)有創(chuàng)建新的進(jìn)程,只是替換了原來(lái)進(jìn)程上下文的內(nèi)容。原進(jìn)程的代碼段,數(shù)據(jù)段,堆棧段被新的進(jìn)程所代替。

一個(gè)進(jìn)程主要包括以下幾個(gè)方面的內(nèi)容:

(1)一個(gè)可以執(zhí)行的程序

(2) 與進(jìn)程相關(guān)聯(lián)的全部數(shù)據(jù)(包括變量,內(nèi)存,緩沖區(qū))

(3)程序上下文(程序計(jì)數(shù)器PC,保存程序執(zhí)行的位置)

  1. exec是一個(gè)函數(shù)簇,由6個(gè)函數(shù)組成,分別是以excl和execv打頭的。

執(zhí)行exec系統(tǒng)調(diào)用,一般都是這樣,用fork()函數(shù)新建立一個(gè)進(jìn)程,然后讓進(jìn)程去執(zhí)行exec調(diào)用。我們知道,在fork()建立新進(jìn)程之后,父進(jìn)各與子進(jìn)程共享代碼段,但數(shù)據(jù)空間是分開(kāi)的,但父進(jìn)程會(huì)把自己數(shù)據(jù)空間的內(nèi)容copy到子進(jìn)程中去,還有上下文也會(huì)copy到子進(jìn)程中去。而為了提高效率,采用一種寫(xiě)時(shí)copy的策略,即創(chuàng)建子進(jìn)程的時(shí)候,并不copy父進(jìn)程的地址空間,父子進(jìn)程擁有共同的地址空間,只有當(dāng)子進(jìn)程需要寫(xiě)入數(shù)據(jù)時(shí)(如向緩沖區(qū)寫(xiě)入數(shù)據(jù)),這時(shí)候會(huì)復(fù)制地址空間,復(fù)制緩沖區(qū)到子進(jìn)程中去。從而父子進(jìn)程擁有獨(dú)立的地址空間。而對(duì)于fork()之后執(zhí)行exec后,這種策略能夠很好的提高效率,如果一開(kāi)始就copy,那么exec之后,子進(jìn)程的數(shù)據(jù)會(huì)被放棄,被新的進(jìn)程所代替。

  1. exec與system的區(qū)別

(1) exec是直接用新的進(jìn)程去代替原來(lái)的程序運(yùn)行,運(yùn)行完畢之后不回到原先的程序中去。

(2) system是調(diào)用shell執(zhí)行你的命令,system=fork+exec+waitpid,執(zhí)行完畢之后,回到原先的程序中去。繼續(xù)執(zhí)行下面的部分。

總之,如果你用exec調(diào)用,首先應(yīng)該fork一個(gè)新的進(jìn)程,然后exec. 而system不需要你fork新進(jìn)程,已經(jīng)封裝好了。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI