在linux里,source、sh、bash、./都可以執行shell script文件,那它們有什么不同嗎?
-----------
1、source
source a.sh
在當前shell內去讀取、執行a.sh,而a.sh不需要有"執行權限"
source命令可以簡寫為"."
. a.sh
注意:中間是有空格的。
2、sh/bash
sh a.sh bash a.sh
都是打開一個subshell去讀取、執行a.sh,而a.sh不需要有"執行權限"
通常在subshell里運行的腳本里設置變量,不會影響到父shell的。
3、./
./a.sh #bash: ./a.sh: 權限不夠 chmod +x a.sh ./a.sh
打開一個subshell去讀取、執行a.sh,但a.sh需要有"執行權限"
可以用chmod +x添加執行權限
另外,使用./來執行的文件里有alias語句的話,shell並不會把alias別名擴展成對應的命令,要解決的話,得使用shopt命令來開啟alias擴展選項
shopt -s expand_aliases
4、fork、source、exec
- 使用fork方式運行script時, 就是讓shell(parent process)產生一個child process去執行該script,當child process結束后,會返回parent process,但parent process的環境是不會因child process的改變而改變的。
- 使用source方式運行script時, 就是讓script在當前process內執行, 而不是產生一個child process來執行。由於所有執行結果均於當前process內完成,若script的環境有所改變, 當然也會改變當前process環境了。
- 使用exec方式運行script時, 它和source一樣,也是讓script在當前process內執行,但是process內的原代碼剩下部分將被終止。同樣,process內的環境隨script改變而改變。
通常如果我們執行時,都是默認為fork的。
為了實踐下,我們可以先建立2個sh文件,以下代碼來自ChinaUnix的網中人:
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"
自己運行下,觀看結果吧 :)
chmod +x 1.sh chmod +x 2.sh ./1.sh fork ./1.sh source ./1.sh exec