點號和source命令
點符號(從Bourne Shell而來)是source的另一名稱,sh 只支持點號,不支持source命令,所以建議使用點號。
source script.sh == . script.sh
陷阱
. script.sh != ./script.sh
or
source script.sh != ./script.sh
./script.sh來執行shell是在一個子shell裡運行的,所以執行後,export變數並沒有反應到父shell裡,而sourc就是在當前shell中執行的,所以export變數能夠反應到當前shell。
paremeter
cat <<EOF > test.sh
echo '$0'=$0 '$1'=$1
EOF
----------------------
ironman@inbu-ironman:/tmp$ ./test.sh a b
$0=./test.sh $1=a
ironman@inbu-ironman:/tmp$ . ./test.sh a b
$0=/bin/bash $1=a
例子
#!/bin/sh
echo "export monitor=1" >> /etc/profile
source /etc/profile
執行 ./test.sh 再 執行echo $monitor,沒有輸出任何值。因為./test.sh執行後產生子shell,之後source /etc/profile是在子shell環境執行,因此./test.sh結束後,子shell環境也就刪除不留下痕跡。
export
讓module.sh 可以讀取 main.sh的變數
main.sh
export number=123
. module.sh
module.sh
echo $number
模組化路徑問題
├── modules
│ ├── log.sh
│ ├── svn_core.sh
│ └── utils.sh
└── svncobranches.sh
當svncobranches.sh在source svn_core.sh時,如果svn_core.sh的相對路徑不是在modules目錄。這樣svn_core.sh導入utils.sh和log.sh就會出錯
使用$PATH
由client shell將整個modules目錄放入到PATH環境變量中,那麼在該shell進程中所有的導入都不需要指定相對或者絕對路徑。好像它們都在同一個目錄下一樣。
realpath=$(readlink -f "$0")
basedir=$(dirname "$realpath")
export PATH=$PATH:$basedir/modules
避免重複引入
example: utils.sh include log.sh
#in utils.sh
if [ "$log" ]; then
return
fi
export log="log.sh"