shell 的命令可分为内建命令与非内建(外部)命令。二者操作方式,大不相同。
外部命令
也被称为文件系统命令,是存在于bash shell 之外的程序。它们并非shell 程序的一部分。外部命令程序通常位于/bin
, /usr/bin
, /sbin
或/usr/sbin
中。一般可以通过which
, type
找到它们。比如ps
就是一个外部命令。
因为实用程序的功能通常都比较强大,所以其包含的程序量也会很大,在系统加载时并不随系统一起被加载到内存中,但是其命令执行过程是由 shell 程序控制的。
当外部命令执行时,会创建出一个子进程,这种操作称为衍生,forking。
当进程必须进行衍生操作时,它需要话费时间与精力来设置新子进程的环境。所以外部命令还是有一定代价的。
内建命令
与外部命令的区别在于,内建命令不需要使用子进程来执行。它已经作为shell 工具的组成成分而存在了。我们可以利用type
了解某个命令是否为内建命令。
$ type cd
cd is a shell builtin
比如cd
,exit
都是shell内建命令。
相比起外部命令,内建命令既不需要衍生出子进程来执行,也不需要打开程序文件,因此内建命令的执行速度也更快,效率也更高。
这些命令是写在 bash 源码的 builtins 里面的,由 shell 程序识别并在 shell 程序内部完成运行,通常在 Linux 系统加载运行时 shell 就被加载并驻留在系统内存中。
其他
有一些命令有多种实现的方式,它们即有内建命令,也有外建命令。比如pwd
, echo
。
可以通过-a
选项查看。
type -a echo
echo is a shell builtin
echo is /bin/echo
而which
命令则只会显示外部命令文件。
如果我们查看 ls
还会获得另外一种结果。
#得到这样的结果说明是内建命令,正如上文所说内建命令都是在 bash 源码中的 builtins 的.def中
xxx is a shell builtin
#得到这样的结果说明是外部命令,正如上文所说,外部命令在/usr/bin or /usr/sbin等等中
xxx is /usr/bin/xxx
#若是得到alias的结果,说明该指令为命令别名所设定的名称;
xxx is an alias for xx --xxx