当您调用 source 或 .(其中一个是另一个的别名。source cmd not POSIX - kind of bashism)时,您将 bash 脚本 加载到 当前 bash 进程中并执行。所以你可以
- 读取源脚本中设置的变量,
- 使用其中定义的函数。
- 如果脚本执行此操作,甚至执行分叉和/或子进程。
当您调用sh 时,您启动了一个运行/bin/sh 的新会话的fork(子进程或子),这通常是一个符号链接到bash。在这种情况下,子脚本设置的环境变量将在子脚本完成时被删除。
警告:sh 可能是指向另一个 shell 的符号链接。
实用样例
例如,如果你想通过特定的方式改变当前工作目录,你不能这样做
$ cat <<eof >myCd2Doc.sh
#!/bin/sh
cd /usr/share/doc
eof
$ chmod +x myCd2Doc.sh
这不会如你所愿:
$ cd /tmp
$ pwd
/tmp
$ ~/myCd2Doc.sh
$ pwd
/tmp
因为 当前工作目录 是环境的一部分,myCd2Doc.sh 将在 subshell 中运行。
但是:
$ cat >myCd2Doc.source <<eof
# Shell source file
myCd2Doc() {
cd /usr/share/doc
}
eof
$ . myCd2Doc.source
$ cd /tmp
$ pwd
/tmp
$ myCd2Doc
$ pwd
/usr/share/doc
看看mycd function!! (使用基于关联数组的bash完成)。
执行级别$SHLVL
$ cd /tmp
printf %b '\43\41/bin/bash\necho This is level \44SHLVL.\n' >qlvl.sh
$ bash qlvl.sh
This is level 2.
$ source qlvl.sh
This is level 1.
$ cat <<eoqlvl2 >qlvl2.sh
#!/bin/bash
export startLevel recursionLimit=5
echo This is level $SHLVL started:${startLevel:=$SHLVL}.
(( SHLVL < recursionLimit )) && ./qlvl2.sh
eoqlvl2
$ chmod +x qlvl2.sh
$ ./qlvl2.sh
This is level 2 started:2.
This is level 3 started:2.
This is level 4 started:2.
This is level 5 started:2.
$ source qlv2.sh
This is level 1 started:1.
This is level 2 started:1.
This is level 3 started:1.
This is level 4 started:1.
This is level 5 started:1.
有点远
$ sed '$a ps --sid $SID fw' qlvl.sh >qlvl3.sh
$ chmod +x qlvl3.sh
$ export SID
$ read SID < <(ps ho sid $$)
$ echo $SID $$
8983 8983
( 当前 PID ($$ == 进程 ID) 与 SID (会话 ID 是相同的标识符>)。这并不总是正确的。)
$ ./qlvl3.sh
This is level 2.
PID TTY STAT TIME COMMAND
8983 pts/10 Ss 0:00 /bin/bash
10266 pts/10 S+ 0:00 \_ /bin/bash ./qlvl3.sh
10267 pts/10 R+ 0:00 \_ ps --sid 8983 fw
$ . qlvl3.sh
This is level 1.
PID TTY STAT TIME COMMAND
8983 pts/10 Ss 0:00 /bin/bash
10428 pts/10 R+ 0:00 \_ ps --sid 8983 fw
点. 是source 的别名。因此,两个命令之间的唯一区别是 slash 替换为 space。
还有一个最终测试:
$ printf %b '\43\41/bin/bash\necho Ending this.\nsleep 1;exit 0\n' >finalTest.sh
$ bash finalTest.sh
Ending this.
$ source finalTest.sh
Ending this.
... 您可能会注意到两种语法之间的不同 行为。 ;-)