调用
source(或其别名
.)时,您将bash脚本加载并执行 到 当前 bash进程中。所以你可以
- 读取在源脚本中设置的变量,
- 使用其中定义的功能。
- 甚至在脚本执行的情况下执行fork和/或子进程。
调用时
sh,您将启动一个 fork (子进程或 子 进程),该 fork
运行新的会话
/bin/sh,通常是的符号链接
bash。在这种情况下,子脚本完成时将删除由子脚本设置的环境变量。
注意 :
sh可能是到 另一个 外壳的符号链接。
一个小样本
例如,如果要通过特定方式更改 当前工作目录 ,则无法执行
$ cat <<eof >myCd2Doc.sh#!/bin/shcd /usr/share/doceof$ chmod +x myCd2Doc.sh
这不会达到您的期望:
$ cd /tmp$ pwd/tmp$ ~/myCd2Doc.sh$ pwd/tmp
因为 当前的工作目录 是环境的一部分,并且
myCd2Doc.sh将在一个 subshell中 运行。
但:
$ cat >myCd2Doc.source <<eof# Shell source filemyCd2Doc() { cd /usr/share/doc}eof$ . myCd2Doc.source$ cd /tmp$ pwd/tmp$ myCd2Doc$ pwd/usr/share/doc我写了一些 mycd
函数示例(基于 bash
Associative Array的 bash完成)。 __
执行水平 $SHLVL
$ cd /tmpprintf %b '4341/bin/bashnecho 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/bashexport startLevelecho This is level $SHLVL started:${startLevel:=$SHLVL}.((SHLVL<5)) && ./qlvl2.sheoqlvl2$ 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/bash10266 pts/10 S+ 0:00 _ /bin/bash ./qlvl3.sh10267 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/bash10428 pts/10 R+ 0:00 _ ps --sid 8983 fw
点
.是的别名
source。因此,两个命令之间的唯一区别被
slash替换为
space。
并进行 最终 测试:
$ printf %b '4341/bin/bashnecho Ending this.nsleep 1;exit 0n' >finalTest.sh$ bash finalTest.sh Ending this.$ source finalTest.shEnding this.
…您可能会注意到两种语法之间的行为 有所不同 。;-)



