概述

Linux 命令有内部命令(内建命令)和外部命令之分,内部命令和外部命令功能基本相同,但工作机制相差很大。

一、内部命令(内建命令)

内部命令,实际上是 shell 程序的一部分,其中包含的是一些比较简单的 linux 系统命令,这些命令由 shell 程序识别并在 shell 程序内部完成运行,通常在 linux 系统加载运行时 shell 就被加载并驻留在系统内存中。内部命令是写在 bash 源码里面的,其执行系统比外部命令快,因为解析内部命令 shell 不需要创建子进程。比如:exit、history、cd、echo 等。

所以在内部命令被执行的时候是先去内存里面查找,然后再被执行。

二、外部命令

外部命令是 linux 系统中的实用程序部分,因为实用程序的功能通常都比较强大,所以其包含的程序量也会很大,因此系统加载时并不随系统一起被加载到内存中。只有在需要时才被系统调用到内存。通常外部命令的实体并不包含在 shell 中,但是其命令执行过程是由 shell 程序控制的。shell 程序管理外部命令执行的路径查找、加载存放,并控制命令的执行。外部命令是在 bash 之外额外安装的,通常放在 /bin、/usr/bin、/sbin、/usr/sbin 等等。可通过 echo $PATH 命令查看外部命令的存储路径,比如:ls、vi 等。

三、如何区分二者

判断一个命令是内部命令还是外部命令的方法是:type command

$ type cd
cd 是 shell 内建
$ type vim
vim 是 /usr/bin/vim

显示 builtin/内建 就表示该命令是内部命令(内建命令),显示出执行路径的命令就是外部命令。

四、二者的执行过程

  • 内部命令被用户执行时,系统会从内存中去调用,调用的速率快。
  • 外部命令被用户执行时,系统会读取环境变量文件,去找 PATH 路径,然后调用执行。

然后再提一下命令的调用,有些外部命令被使用过后,会存在 hash 表中,当你再次输入该命令,它的调用是这样一个过程:hash --> 内建命令 --> PATH,hash 的优先级最高,然后是内部命令,最后是外部命令。

$ hash -l
builtin hash -p /usr/bin/mv mv
builtin hash -p /usr/bin/cp cp
builtin hash -p /usr/bin/whereis whereis
builtin hash -p /usr/bin/elinks elinks
builtin hash -p /usr/bin/pwd pwd
builtin hash -p /usr/bin/emacs emacs
builtin hash -p /usr/bin/dpkg-deb dpkg-deb
builtin hash -p /usr/bin/sudo sudo
builtin hash -p /usr/bin/ed ed
builtin hash -p /usr/bin/eject eject
builtin hash -p /usr/bin/ls ls
builtin hash -p /usr/sbin/e2fsck e2fsck
$ type mv
mv 已被录入哈希表 (/usr/bin/mv)
$ type ping
ping 是 /usr/bin/ping
$ ping www.baidu.com
PING www.a.shifen.com (180.101.49.11) 56(84) bytes of data.
64 bytes from 180.101.49.11 (180.101.49.11): icmp_seq=1 ttl=53 time=8.34 ms
64 bytes from 180.101.49.11 (180.101.49.11): icmp_seq=2 ttl=53 time=8.90 ms
^C
--- www.a.shifen.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 8.335/8.618/8.902/0.283 ms
$ type ping
ping 已被录入哈希表 (/usr/bin/ping)

参考

linux的内建命令和外部命令