什么是内部命令和外部命令
Linux命令有内部(建)命令和外部命令之分,内部命令和外部命令功能基本相同,但有些细微差别。所谓的内部和外部其实是相对SHELL自身来讲。Linux系统为了提高系统运行效率,将经常使用的轻量的命令在系统启动时一并加载这些命令到内存中供SHELL随时调用,这部分命令即为内部命令。反之,系统层调用的较重的命令只有当被调用时才会硬盘加载的这部分命令即为外部命令。
(1)内部命令实际上是shell程序的一部分,其中包含的是一些比较简单的linux系统命令,这些命令由shell程序识别并在shell程序内部完成运行,通常在linux系统加载运行时shell就被加载并驻留在系统内存中。内部命令是写在bashy源码里面的,其执行速度比外部命令快,因为解析内部命令shell不需要创建子进程。比如:exit,history,cd,echo等。
(2)外部命令是linux系统中的实用程序部分,因为实用程序的功能通常都比较强大,所以其包含的程序量也会很大,在系统加载时并不随系统一起被加载到内存中,而是在需要时才将其调用内存。通常外部命令的实体并不包含在shell中,但是其命令执行过程是由shell程序控制的。shell程序管理外部命令执行的路径查找、加载存放,并控制命令的执行。外部命令是在bash之外额外安装的,通常放在/bin,/usr/bin,/sbin,/usr/sbin……等等。可通过“echo $PATH”命令查看外部命令的存储路径,比如:ls、vi等。
2. 如何区别内部命令和外部命令
日常工作中,对于系统用户来讲其实很少关注内部命令和外部命令,只要使得顺手正常,很少有人去关注这部分内容。但在环境复杂或系统状态异常(被入侵)等情况下,我们更建议使用绝对路径下的外部命令。当然,Linux系统也提供了相关命令来区别二者,type区分内部命令与外部命令。
使用:type [-a | -t | -p] name 或 type [-all | -type | -path] name。
(1)没有参数的状况下,它会显示出shell如何解译name做为命令。
(2)如果有”-type”,它将会显示alias、 keyword、function、builtin或file。
file:表示为外部指令;
alias:表示该指令为命令别名所设定的名称;
builtin:表示该指令为 bash 内建的指令功能。
(3)如果有”-path”的参数,它将会显示该命令的完整档名(外部指令)或显示为内建指令,找不到的话,不显示任何东西。
(4)如果有”-all”的参数,会将由PATH变量定义的路径中所有含有name指令的路径都列出来,即显示所有可执行name的可能路径。
为什么会内部命令和外部命令
内部命令其实是SHELL程序的一部分,其中包含的是一些比较简练和日常经常会被用到的命令。这些命令通常系统启动时就调入内存,且常驻内存的,由SHELL程序识别并在SHELL程序内部运行,之所以这样做的原因只有一个就是:为了最大化执行效率,提升系统性能。而 外部命令通常是系统的软件功能,该部分程序功能通常较为强大,但包括的程序量也很大,因此并不随系统启动一并加载,只在用户需要时才从硬盘中读入内存。
4. 内部命令和外部命令的区别
因为内部命令是SHELL内置,所以该命令调用时直接使用,无需追踪环境变量,而外部命令则有很大区别,因为外部命令如希望被用户所使用,依然要通过SHELL程序来调用,所以多了一层执行路径的问题,即我们常讲到的环境变量。
外部命令就是由Shell副本(新的进程)所执行的命令,基本的过程如下:
a. 建立一个新的进程。此进程即为Shell的一个副本。
b. 在新的进程里,在PATH变量内所列出的目录中,寻找特定的命令。
/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin为PATH变量典型的默认值。
当命令名称包含有斜杠(/)符号时,将略过路径查找步骤。
c. 在新的进程里,以所找到的新程序取代执行中的Shell程序并执行。
d. 程序完成后,最初的Shell会接着从终端读取下一条命令,和执行脚本里的下一条命令。
通常情况下,脚本中的Bash内建命令在运行的时候是不会fork出一个子进程的。但是脚本中的外部或者过滤命令通常会fork出一个子进程。 一个内建命令通常会与一个系统命令同名,但是Bash在内部重新实现了这些命令。比如,Bash的echo命令与/bin/echo就不尽相同,虽然它们的行为在绝大多数情况下都是一样的。