Linux shell執行source和 . 的區別
一般Linux上執行一個shell指令碼,有如下幾種方法:
bash test.sh
source test.sh
. test.sh
./test.sh
source 和 .
source和 . 這兩個都是shell自帶的內建命令,這兩個命令是等價的關係。也就是說
source test.sh
. test.sh
這兩條命令的執行是完全一樣的。
使用type來看下命令型別:
[email protected]:~/work/test/linuxshell$ type source
source 是 shell 內建
[email protected] :~/work/test/linuxshell$ type .
. 是 shell 內建
使用help來檢視命令介紹:
[email protected]:~/work/test/linuxshell$ help . .: . 檔名 [引數] 在當前 shell 中執行一個檔案中的命令。 在當前 shell 中讀取並執行 FILENAME 檔案中的命令。$PATH 變數中的 條目被用於尋找包含 FILENAME 檔案的目錄。如果提供了任何的 ARGUMENTS 引數,則它們將成為 FILENAME 檔案執行時的位置引數。 退出狀態: 返回 FILENAME 檔案中最後一個命令的狀態;如果 FILENAME 檔案不可讀則失敗。
這兩個命令是會由父shell建立子程序去執行shell指令碼,並且特別關鍵的一點,它會繼承所有父shell的環境變數。
使用如下命令進行測試:
#!/bin/bash
echo "Print Bash Path:$SHELL"
echo $EXPORT_VAR
echo $LOCAL_VAR
執行如下:
[email protected]cheng:~/work/test/linuxshell$ LOCAL_VAR=local
[email protected]:~/work/test/linuxshell$ export EXPORT_VAR=export
[email protected] :~/work/test/linuxshell$ source test.sh
Print Bash Path:/bin/bash
export
local
[email protected]:~/work/test/linuxshell$ . test.sh
Print Bash Path:/bin/bash
export
local
bash + shell script
使用這種型別的命令,是會顯式的呼叫bash shell作為我們的指令碼直譯器進行執行,bash需要存在於我們PATH環境變數裡。
[email protected]:~/work/test/linuxshell$ bash test.sh
Print Bash Path:/bin/bash
export
[email protected]:~/work/test/linuxshell$ which bash
/bin/bash
當然除了bash,加入我們用於其他型別的shell直譯器,也可以使用同樣的方法執行指令碼。從上面的測試來看,bash + shell script的方式,並不會整合所有的父shell環境變數,但是會繼承父shell export出來的環境變數。
./ + shell script
./這個方法在linux世界是用來執行一切可執行檔案的方法,不僅僅可以用來執行shell指令碼。需要特別注意的是 ./ 並不等於 . 符號,兩者是具有本質區別的。
./ 這個符號後面需要跟一個可執行檔案的路徑,用於定位執行檔案的位置,這個路徑可以是相對路徑。那麼如何區分不同的可執行檔案呢?對於shell指令碼來說,我們會在開頭加上:
#! /bin/bash
這個就代表著這是一個需要使用bash shell來進行解釋的指令碼,當然同樣的方式也適用於其他語言,比如python:
#!/bin/python
這裡的#!是具有異常魔力的標誌,我們叫他magic number。它是用來區分不同型別可執行檔案的一種方式。注意#!後面必須要加上對應的直譯器路徑,並且必須是正確的路徑。否則可能會執行失敗。
擴充套件
當然還有一種情況,假如我的系統安裝了不同型別shell,那麼要如何執行我的指令碼使用不同shell來執行呢?實際上指令碼中的magic number後指定的只是該指令碼預設的執行shell,當我們使用 ./ 來執行時,就會使用預設的shell。如果此時使用顯式的方式,那麼是會覆蓋預設直譯器的。
比如我們在指令碼中第一行使用mksh作為直譯器:
#! /bin/mksh
但是在執行是使用如下命令:
bash test.sh
那麼該指令碼使用bash shell來執行。
比如我的例子:
[email protected]:~/work/test/linuxshell$ ./test.sh
bash: ./test.sh: /bin/mksh: 直譯器錯誤: 沒有那個檔案或目錄
[email protected]:~/work/test/linuxshell$ bash test.sh
Print Bash Path:/bin/bash
export
由於我的機器沒有按照mksh,所以預設查詢mksh會失敗報錯。但是顯式告訴系統使用bash來執行,就可以執行成功。