Linux:source 命令的一点小细节

转载请注明来源:http://blog.csdn.net/imred/article/details/50381931
前几天听到同学提起了Linux中的source命令,能用来执行一个shell脚本文件,即使这个脚本文件没有设置可执行权限位(x)。当时我就想,这样应该会方便不少,不用再输入一个chmod语句来给shell脚本加上可执行权限了。
今天我测试了一下source这个命令,功能正如前面同学所述的那样。到最后,我随手敲了一个“source /bin/yum”命令(Fedora23用dnf代替了yum,此时yum是一个shell脚本文件,用来执行dnf程序),闪出了几行文字,然后terminal就自动关闭了。当时我怀疑是什么原因导致bash崩溃了,我就又打开了一个terminal,然后键入“bash”,打开了一个作为原terminal的bash进程的子进程的bash。然后再次执行“source /bin/yum”,这次terminal没有自动关闭,但也没有输出什么错误信息。然后我键入“exit”,terminal就关闭了,这说明这个exit关闭的是作为父进程的bash程序,作为子进程的bash程序在之前就关闭了。
作为对比,我把另一个经常用来执行shell脚本的命令:sh,也测试了一下,并没有出现刚才的状况。这让我感到很奇怪。
这时候我又检查了一下sh命令“ls - /bin/sh“,发现这个sh文件只是一个符号链接而已,指向同目录下的bash程序。联想到之前学到一点关于shell程序工作原理的知识,我弄明白了到底是怎么一回事。
shell程序的工作原理大概是这样的,首先接受输入,然后判断输入是否是shell内置的命令。如果是的话,直接执行相关功能,执行完毕后,继续接受下一个输入;如果不是的话,将其视为一个可执行程序,然后在PATH中查找这个程序,如果存在的话,shell会调用fork,创造一个子进程,然后子进程再调用exec执行这个可执行程序,执行完毕后,继续接受下一个输入。
所以,使用sh执行yum脚本时,由于它并不是内置命令,所以实际上是先创建了一个作为原bash进程子进程的bash进程,然后由子bash进程执行这个脚本(此时并不需要调用exec,请读者自己思考)。执行的时候,父bash进程被挂起,当子bash进程执行到最后的exit时(实际上yum这个shell脚本文件中最后一条语句是一个exec调用,并没有exit语句,因为dnf是一个python脚本。但是这并不影响结果),子bash进程就结束了,然后父bash进程继续工作。所以它并不会导致父bash进程被结束。
而使用source命令呢?它会直接在父bash环境下一条条执行shell脚本中的命令,而没有fork出子进程。这就导致执行到最后父bash进程被结束,terminal被关闭。
所以这种方便是有一定副作用的,如果你在文本环境下,这样的副作用有可能是关掉你的bash进程,然后让你重新登录。
转载请注明来源:http://blog.csdn.net/imred/article/details/50381931

你可能感兴趣的:(linux,shell,脚本,fedora)