在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Linux/ exec 跟 source 差在哪?
別人echo、你也echo,是問echo知多少?
何為 shell?
你要 if 還是 case 呢?
""(雙引號(hào)) 與''(單引號(hào)) 差在哪?
exec 跟 source 差在哪?
$(())與$()還有${}差在哪?
() 與 {} 差在哪?
shell and Carriage 關(guān)系
for what? while 與 until 差在哪?
大于小于號(hào)差別?
[^ ] 跟[! ]差在哪? (RE: Regular Expression)
[^ ] 跟[! ]差在哪? (wildcard)
特殊符號(hào)差異
&& 與 || 差在哪?
var=value 在 export 前后的差在哪?

exec 跟 source 差在哪?

這次讓我們從 CU shell 版的一個(gè)實(shí)例帖子來談起吧: (論壇改版后,原鏈接已經(jīng)失效)

例中的提問原文如下:

帖子提問:

cd /etc/aa/bb/cc 可以執(zhí)行 但是把這條命令放入 shell 腳本后,shell 腳本不執(zhí)行! 這是什么原因?

意思是:運(yùn)行 shell 腳本,并沒有移動(dòng)到 / etc/aa/bb/cc 目錄。

我當(dāng)時(shí)如何回答暫時(shí)別去深究,先讓我們了解一下進(jìn)程 (process) 的概念好了。

首先,我們所執(zhí)行的任何程序,都是父進(jìn)程 (parent process) 產(chǎn)生的一個(gè) 子進(jìn)程 (child process), 子進(jìn)程在結(jié)束后,將返回到父進(jìn)程去。 此現(xiàn)象在 Linux 中被稱為fork

(為何要稱為 fork 呢? 嗯,畫一下圖或許比較好理解...^_^)

當(dāng)子進(jìn)程被產(chǎn)生的時(shí)候,將會(huì)從父進(jìn)程那里獲得一定的資源分配、及 (更重要的是) 繼承父進(jìn)程的環(huán)境。

讓我們回到上一章所談到的 "環(huán)境變量" 吧: 所謂環(huán)境變量其實(shí)就是那些會(huì)傳給子進(jìn)程的變量。 簡單而言, "遺傳性" 就是區(qū)分本地變量與環(huán)境變量的決定性指標(biāo)。 然而,從遺傳的角度來看,我們不難發(fā)現(xiàn)環(huán)境變量的另一個(gè)重要特征: 環(huán)境變量只能從父進(jìn)程到子進(jìn)程單向傳遞。 換句話說:在子進(jìn)程中環(huán)境如何變更,均不會(huì)影響父進(jìn)程的環(huán)境。

接下來,在讓我們了解一下 shell 腳本 (shell script) 的概念. 所謂 shell script 講起來很簡單,就是將你平時(shí)在 shell prompt 輸入的多行 command line, 依序輸入到一個(gè)文件文件而已。

再結(jié)合以上兩個(gè)概念 (process + script),那應(yīng)該不難理解如下的這句話的意思了: 正常來說,當(dāng)我們執(zhí)行一個(gè) shell script 時(shí),其實(shí)是先產(chǎn)生一個(gè) sub-shell 的子進(jìn)程, 然后 sub-shell 再去產(chǎn)生命令行的子進(jìn)程。 然則,那讓我們回到本章開始時(shí),所提到的例子在重新思考:

帖子提問:

cd/etc/aa/bb/cc 可以執(zhí)行 但是把這條命令放入 shell 腳本后,shell 腳本不執(zhí)行! 這是什么原因?

意思是:運(yùn)行 shell 腳本,并沒有移動(dòng)到 /etc/aa/bb/cc 目錄。

我當(dāng)時(shí)的答案是這樣的:

因?yàn)椋覀円话闩艿?shell script 是用 sub-shell 去執(zhí)行的。 從 process 的概念來看,是 parent process 產(chǎn)生一個(gè) child process 去執(zhí)行, 當(dāng) child 結(jié)束后,返回 parent, 但 parent 的環(huán)境是不會(huì)因 child 的改變而改變的。 所謂的環(huán)境變量元數(shù)很多,如 effective id(euid),variable, working dir 等等... 其中的 working dir($PWD) 正是樓主的疑問所在: 當(dāng)用 sub-shell 來跑 script 的話,sub-shell 的 $pwd 會(huì)因?yàn)?cd 而變更, 但返回 primary shell 時(shí),$PWD 是不會(huì)變更的。

能夠了解問題的原因及其原理是很好的,但是? 如何解決問題,恐怕是我們更應(yīng)該感興趣的是吧?

那好,接下來,再讓我們了解一下source命令好了。 當(dāng)你有了fork的概念之后,要理解soruce就不難:

所謂source,就是讓 script 在當(dāng)前 shell 內(nèi)執(zhí)行、 而不是產(chǎn)生一個(gè) sub-shell 來執(zhí)行。 由于所有執(zhí)行結(jié)果均在當(dāng)前 shell 內(nèi)執(zhí)行、而不是產(chǎn)生一個(gè) sub-shell 來執(zhí)行。

因此, 只要我們?cè)締为?dú)輸入的 script 命令行,變成source命令的參數(shù), 就可輕而易舉地解決前面提到的問題了。

比方說,原本我們是如此執(zhí)行 script 的:

$ ./my_script.sh

現(xiàn)在改成這樣既可:

$ source ./my_script.sh

或者:

$ . ./my_script.sh

說到這里,我想,各位有興趣看看/etc底下的眾多設(shè)定的文件, 應(yīng)該不難理解它們被定義后,如何讓其他 script 讀取并繼承了吧?

若然,日后,你有機(jī)會(huì)寫自己的 script, 應(yīng)也不難專門指定一個(gè)設(shè)定的文件以供不同的 script 一起 "共用" 了... ^_^

okay, 到這里,若你搞懂forksource的不同, 那接下來再接受一個(gè)挑戰(zhàn):

exec又與source/fork有何不同呢?

哦... 要了解exec或許較為復(fù)雜,尤其是扯上File Decscriptor的話... 不過,簡單來說:

exec 也是讓 script 在同一個(gè)進(jìn)程上執(zhí)行,但是原有進(jìn)程則被結(jié)束了。 簡言之,原有進(jìn)程能否終止,就是execsource/fork的最大差異了。

嗯,光是從理論去理解,或許沒那么好消化, 不如動(dòng)手 "實(shí)踐 + 思考" 來得印象深刻哦。

下面讓我們?yōu)閮蓚€(gè)簡單的 script,分別命名為 1.sh 以及 2.sh

1.sh

#!/bin/bash

A=B 
echo "PID for 1.sh before exec/source/fork:$$"
export A
echo "1.sh: \$A is $A"
case $1 in
        exec)
                echo "using exec..."
                exec ./2.sh ;;
        source)
                echo "using source..."
                . ./2.sh ;;
        *)
                echo "using fork by default..."
                ./2.sh ;;
esac
echo "PID for 1.sh after exec/source/fork:$$"
echo "1.sh: \$A is $A"

2.sh

#!/bin/bash

echo "PID for 2.sh: $$"
echo "2.sh get \$A=$A from 1.sh"
A=C
export A
echo "2.sh: \$A is $A"

然后分別跑如下參數(shù)來觀察結(jié)果:

$ ./1.sh fork
$ ./1.sh source
$ ./1.sh exec

好了,別忘了仔細(xì)比較輸出結(jié)果的不同及背后的原因哦... 若有疑問,歡迎提出來一起討論討論~~~~

happy scripting! ^_^