|
首先,我們從一個十分簡單的例子test.sh開始吧: #!/bin/sh #this is a test. cd /tmp echo 'hello,this is a test' 這是一個十分簡單的程序,但是運行結(jié)果可能會讓你吃驚哦! 這個時候,我們發(fā)現(xiàn)程序運行之后,并沒有改變當(dāng)前目錄。(黑人問號???) 別著急,我們先了解一下linux程序如何運行。 linux程序三種執(zhí)行方法 運行l(wèi)inux程序有三種方法,分別是: 1、使文件具有可執(zhí)行權(quán)限,直接運行文件。 chmod 命令用來修改文件的權(quán)限。+x是使文件擁有可執(zhí)行的權(quán)限。就如上面我們運行程序一樣。但是我們看到的結(jié)果與我們想象當(dāng)中有一定的出入。 2、直接調(diào)用命令解釋器執(zhí)行程序。 如下圖所示: 由于我們的解釋器是/bin/sh,所以,用sh命令解釋器來執(zhí)行程序。 我們也看到當(dāng)前的工作路徑?jīng)]有發(fā)生變化。(黑人問號???) 3、使用source執(zhí)行文件。 沒錯,這里我們發(fā)現(xiàn)當(dāng)前的工作路徑發(fā)生了變化,(黑人問號???)但是究竟為什么呢?讓我們帶著三個黑人問號詳細(xì)了解一下linux程序究竟怎么執(zhí)行。 linux程序執(zhí)行的過程 當(dāng)命令行shell執(zhí)行程序時,首先判斷是否該程序具有可執(zhí)行權(quán)限。如果沒有可執(zhí)行權(quán)限,就會提示:Permission denied(權(quán)限不夠),如下圖所示: 在第一種方法中,我們直接執(zhí)行文件,就先加上了可執(zhí)行權(quán)限。 當(dāng)命令行接收到我們的執(zhí)行命令,并且判斷具有可執(zhí)行權(quán)限后,則調(diào)用Linux內(nèi)核命令新建一個進(jìn)程,在新建的進(jìn)程中調(diào)用指定的命令。但是我們的test.sh不是編譯型的文件,所以linux內(nèi)核不知道如何執(zhí)行,然后交給shell,shell就知道這是一個腳本,那么就啟動一個新的shell進(jìn)程來進(jìn)行執(zhí)行。但是linux系統(tǒng)有很多shell,如圖: 我們程序第一行看到是#!/bin/sh,這時,命令行就啟用一個新的bash進(jìn)程來執(zhí)行程序。 程序執(zhí)行差異 在我們運行shell程序的三種方法中,前兩種方法的執(zhí)行過程如下: (1)父進(jìn)程接收到命令,然后發(fā)現(xiàn)不是內(nèi)建命令,于是創(chuàng)建了一個和自己一樣的s h e l l進(jìn)程,來執(zhí)行這個外部命令 (2)這個s h e l l子進(jìn)程用/bin/sh取代自己,sh進(jìn)程設(shè)置自己的運行環(huán)境變量,其中包括了$PWD變量。 (3)sh進(jìn)程依次執(zhí)行內(nèi)建命令cd和echo。在此過程中,sh進(jìn)程(子進(jìn)程)的環(huán)境變量被cd命令改變。 (4)子進(jìn)程執(zhí)行完畢,就消亡了,一直在等待的父進(jìn)程醒來,繼續(xù)接受命令。 所以我們明白了前兩種方法執(zhí)行結(jié)果跟我們預(yù)期不一樣的原因,父進(jìn)程的當(dāng)前目錄(環(huán)境變量)無法被子進(jìn)程改變。 但是,使用source執(zhí)行是shell腳本時不會創(chuàng)建子進(jìn)程,而是在父進(jìn)程中直接執(zhí)行。至此黑人問號消失,繼續(xù)加油寫代碼吧。
|
|
|