source命令與“.”點命令

轉載自:http://wenku.baidu.com/view/345d194d2e3f5727a5e96269.html


source 命令是 bash shell 的內置命令,從 C Shell 而來。

source 命令的另一種寫法是點符號,用法和 source 相同,從Bourne Shell而來。

source 命令可以強行讓一個腳本去立即影響當前的環境。

source 命令會強制執行腳本中的全部命令,而忽略文件的權限。

source 命令通常用於重新執行剛修改的初始化文件,如.bash_profile .profile 等等。

source 命令可以影響執行腳本的shell的環境, export 則只能影響其shell的環境。


使用方法舉例:

$source ~/.bashrc

或者:

$. ~/.bashrc

執行後 ~/.bashrc 中的內容立即生效。

一個典型的用處是,在使用 Android mm 等相關命令時,需要先執行以下命令:

$cd <android source path>

$source./build/envsetup.sh 或者$. ./build/envsetup.sh


source命令( C Shell 而來)bash shell的內置命令。點命令,就是個點符號,(Bourne Shell而來)source的另一名稱。同樣的,當前腳本中設置的變量也將作爲腳本的環境,source(或點)命令通常用於重新執行剛修改的初始化文件,如 .bash_profile .profile 等等。例如,如果在登錄後對.bash_profile 中的 EDITER TERM 變量做了修改,則能用source命令重新執行 .bash_profile 中的命令而不用註銷並重新登錄

source命令的作用就是用來執行一個腳本,那麼:

source a.sh 同直接執行 ./a.sh 有什麼不同呢,比如你在一個腳本里export $KKK=111 ,如果你用./a.sh執行該腳本,執行完畢後,你運行 echo $KKK ,發現沒有值,如果你用source來執行,然後再echo ,就會發現KKK=111因爲調用./a.sh來執行shell是在一個子shell裏運行的,所以執行後,結果並沒有反應到父shell不過source不同,他就是在本shell中執行的,所以能看到結果。

.”點命令是shell的一個內部命令,它從指定的shell文件中讀入所有命令語句並在當前進程中執行。因此當多個shell進程(父子進程或無關進程均可)共享一組變量值時,就可以將這些變量賦值語句定義到一個shell文件裏,並在需要這些變量值的程序中使用點語句來引用這個shell文件,從而實現變量值共享(對這些變量值的修改僅涉及到這個shell文件)。但要注意的是,這個shell文件不能包括含有位置參數的語句,即不能接受$1、$2等命令行參數。

從上面可以看出,其實點命令相當於c語言裏面的#include。點命令還有另一個寫法:source。下面我們將舉例來說明。

我們先寫一個簡單的shell腳本文件,暫且命名爲file1吧:

#! /bin/bash

a="hi"

echo $a

我們先來執行一下這個shell腳本,打開終端,敲入:./file1

結果是什麼,你應該也看到了吧:

bash: ./file1: Permission denied

爲什麼呢。我們先不管這個吧,先看一下,另一個結果:

. ./file1(注意啊,兩個點之間有個空格的哦,要不就成了上一級目錄了,如果你不嫌麻煩的話,也可以寫source./file1)這個的結果呢,跟前面就不一樣了,正如我們所願的,輸出了hi


./file1,直接執行,需要另起shell進程,而你似乎還沒有這個權限(這個改一下就OK了,後面再說),而用點命令就不一樣了(注意啊,./file這裏的點可不是點命令裏的點啊,我就被這個問題困擾了很久,汗死,竟然忘了點還有當前目錄的意思,大家b4我吧),點命令會在當前的shell下執行。補充說一下怎麼改一下file1的權限,讓我們可以在按shell腳本來執行:chmod +x file1

再執行一下./file1,是不是OK了?再來看另一個例子吧。首先腳本文件file1

#! /bin/bash

a="hi"

腳本文件file2(與file1在同一個目錄下)

#! /bin/bash

./file1

echo $a

記得改一下file1的權限啊,要不./file1就沒法執行了。執行一下看看結果。什麼都沒有,是吧。我們再改一下file2,這回用一下咱們的點命令

#! /bin/bash

. ./file1

echo $a

怎麼樣結果不一樣了吧。(原諒我實在太懶了,只能舉這麼簡短的例子了,呵呵)。這個例子應該還是能說明點問題的吧。如果不用點命令的話,會另起shell進程,而啓動這個進行的時候,它會建立自己的進程環境(暫且這麼叫它吧),然後在這個進行結束的時候,它所建立的環境也隨之被銷燬。而且點命令就不一樣了,它會把點命令所帶的shell腳本里的所以內容帶到當前的shell進程裏,在本程序裏,就是變量a了。

廢話了這麼多,其實好像把點命令想像成C裏的#includeOK了,呵呵。不過經過這麼折騰,還是學到了一點東西的,至少知道了.不僅有點命令的作用,更有當前目錄的意思(冷啊,該補一下linux基礎了)。


爲什麼在shell腳本里面export的環境變量,在set裏面竟然看不到。

爲什麼在shell腳本里面用export設置環境變量之後,當shell執行完了,用set命令看不到呢?但是你如果直接在終端裏export 環境變量用set是看到的。


一個shell腳本test.sh的內容爲:

#!/bin/bash

export AA=123

當我們執行test.sh的時候,是當前終端所在的shell fork一個子shell然後執行test.sh的,執行完了再返回終端所在的shell。明白這點,就容易理解了,我們在test.sh設置了AA環境變量,它只在fork出來的這個子shell中生效,shell只能繼承父shell的環境變量,而不能修改父shell的環境變量,所以test.sh結束後,父進程的環境就覆蓋回去。所以在test.sh之後完之後,我們用set命令是看不了AA這個環境變量的值的。

那有什麼辦法可以讓腳本的環境變量在腳本執行之後仍然對當前終端存在呢?用sorcue 或者.(dot) 。明確告訴shell不要fork執行腳本,而是在當前的shell執行,這樣環境變量就可以保存下來了

source命令用法:

source Filename (通常用“.”來代替)

source test.sh .test.sh是等效的。

【補充】

source命令與shell scripts的區別是,

source在當前bash環境下執行命令,而scripts是啓動一個子shell來執行命令。這樣如果把設置環境變量(或alias等等)的命令寫進scripts中,就只會影響子shell,無法改變當前的BASH,所以通過文件(命令列)設置環境變量時,要用source 命令。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章