一、在 Shell 腳本中調(diào)用另一個 Shell 腳本的三種方式
先來說一下主要以下有幾種方式:
- 1 fork: 如果腳本有執(zhí)行權(quán)限的話舟误,path/to/foo.sh颠毙。如果沒有,sh path/to/foo.sh肌索。
- 2 exec: exec path/to/foo.sh
- 3 source: source path/to/foo.sh
1.1 fork
fork 是最普通的, 就是直接在腳本里面用 path/to/foo.sh 來調(diào)用foo.sh 這個腳本蕉拢,比如如果是 foo.sh 在當(dāng)前目錄下,就是 ./foo.sh诚亚。運(yùn)行的時候 terminal 會新開一個子 Shell 執(zhí)行腳本 foo.sh晕换,子 Shell 執(zhí)行的時候, 父 Shell 還在。子 Shell 執(zhí)行完畢后返回父 Shell站宗。子 Shell 從父 Shell 繼承環(huán)境變量闸准,但是子 Shell 中的環(huán)境變量不會帶回父 Shell。
1.2 exec
exec 與 fork 不同梢灭,不需要新開一個子 Shell 來執(zhí)行被調(diào)用的腳本. 被調(diào)用的腳本與父腳本在同一個 Shell 內(nèi)執(zhí)行夷家。但是使用 exec 調(diào)用一個新腳本以后, 父腳本中 exec 行之后的內(nèi)容就不會再執(zhí)行了。這是 exec 和 source 的區(qū)別.
1.3 source
與 fork 的區(qū)別是不新開一個子 Shell 來執(zhí)行被調(diào)用的腳本敏释,而是在同一個 Shell 中執(zhí)行. 所以被調(diào)用的腳本中聲明的變量和環(huán)境變量, 都可以在主腳本中進(jìn)行獲取和使用库快。
其實從命名上可以感知到其中的細(xì)微區(qū)別,下面通過兩個腳本來體會三種調(diào)用方式的不同:
第一個腳本颂暇,命名為script1.sh:
#!/usr/bin/env bash
A=1
echo "before exec/source/fork: PID for 1.sh = $$"
export A
echo "In 1.sh: variable A=$A"
case $1 in
--exec)
echo -e "==> using exec…\n"
exec ./2.sh ;;
--source)
echo -e "==> using source…\n"
. ./2.sh ;;
*)
echo -e "==> using fork by default…\n"
./2.sh ;;
esac
echo "after exec/source/fork: PID for 1.sh = $$"
echo -e "In 1.sh: variable A=$A\n"
第二個腳本缺谴,我們命名為 2.sh:
#!/usr/bin/env bash
echo "PID for 2.sh = $$"
echo "In 2.sh get variable A=$A from 1.sh"
A=2
export A
echo -e "In 2.sh: variable A=$A\n"
注:這兩個腳本中的參數(shù) 用于返回腳本的 PID , 也就是進(jìn)程 ID。這個例子是想通過顯示 PID 判斷兩個腳本是分開執(zhí)行還是同一進(jìn)程里執(zhí)行,也就是是否有新開子 Shell湿蛔。當(dāng)執(zhí)行完腳本 2.sh 后膀曾,腳本 1.sh 后面的內(nèi)容是否還執(zhí)行。
$ ./1.sh
PID for 1.sh before exec/source/fork:5845
1.sh: $A is B
using fork by default…
PID for 2.sh: 5242
2.sh get $A=B from 1.sh
2.sh: $A is C
PID for 1.sh after exec/source/fork:5845
1.sh: $A is B
fork方式可以看出阳啥,兩個腳本都執(zhí)行了添谊,運(yùn)行順序為1-2-1,從兩者的PID值察迟,可以看出斩狱,兩個腳本是分成兩個進(jìn)程運(yùn)行的。
$ ./1.sh – exec
PID for 1.sh before exec/source/fork:5562
1.sh: $A is B
using exec…
PID for 2.sh: 5562
2.sh get $A=B from 1.sh
2.sh: $A is C
exec方式運(yùn)行的結(jié)果是扎瓶,2執(zhí)行完成后所踊,不再回到1。運(yùn)行順序為1-2概荷。從pid值看秕岛,兩者是在同一進(jìn)程中運(yùn)行的。
$ ./1.sh source
PID for 1.sh before exec/source/fork:5156
1.sh: $A is B
using source…
PID for 2.sh: 5156
2.sh get $A=B from 1.sh
2.sh: $A is C
PID for 1.sh after exec/source/fork:5156
1.sh: $A is C
source方式的結(jié)果是兩者在同一進(jìn)程里運(yùn)行误证。該方式相當(dāng)于把兩個腳本先合并再運(yùn)行继薛。
二. 等待.sh腳本僅在另一個腳本完成后才能運(yùn)行?
2.1 &&連接器
只需使用&&連接器(即復(fù)合命令):
./script1.sh && ./script2.sh
但是請注意愈捅,只有script1.sh 即第一個腳本退出代碼為0(即沒有錯誤)時遏考,才會執(zhí)行第二個腳本。
2.2 蓝谨;連接器
如果要執(zhí)行序列灌具,無論第一個腳本的結(jié)果如何,只需執(zhí)行以下操作
./script1.sh ; ./script2.sh
您可以測試兩個連接器的行為:
$ true && echo aa
aa
$ false && echo aa
$ false ; echo aa
aa
總結(jié)
除了exec 之外像棘,其他都可以順序執(zhí)行稽亏,只是如果對環(huán)境變量有要求的話,就要分辨使用fork還是source了
作者:大城市的小蝸牛
源鏈接:https://blog.csdn.net/m0_46535940/article/details/124959568