Linux命令的执行必须依赖于Shell命令解释器。Shell实际上是在Linux系统中运行的一种特殊程序,它位于操作系统内核与用户之间,负责接受用户输入的命令并进行解释,将需要执行的操作传递给系统内核执行,Shell在用户和内核之间充当了一个“翻译官”的角色。当用户登陆到Linun系统时,会自动加载一个Shell程序,以便给用户提供可以输入命令的操作环境。

Bash是Linux系统中默认使用的Shell程序,文件位于/bin/bash。根据Linux命令与Shell程序的关系,一般分为以下两种类型:

内部命令:指的是集成于Shell解释器程序(如Bash)内部的一些特殊指令,也成为内建(Built-IN)指令。内部命令属于Shell的一部分,所以并没有单独对应的系统文件,只要Shell解释器被运行,内部指令也就自动载入内存了,用户可以直接使用。内部命令无需从硬盘中重新读取文件,因此执行效率更高。

外部命令:指的是Linux系统中能够完成特定功能的脚本文件或二进制程序,每个外部命令对应了系统中的一个文件,是属于Shell解释器程序之外的命令,所以称为外部命令。Linux系统必须知道外部命令对应的文件位置,才能够由Shell加载并执行。

Linux系统默认会将存放外部命令、程序的目录(如/bin、/usr/bin、/usr/local/bin等)添加到用户的“搜索路径”中,当使用位于这些目录中的外部命令时,用户不需要指定具体的位置。因此在大多数情况下,不用刻意去分辨内部、外部命令,其使用方法是基本类似的。


对于Shell来说,可以识别三种基本命令:内建命令、Shell函数以及外部命令。
(1)内建命令就是由Shell本身所执行的命令。
有些命令是由于其必要性才内建的,例如cd用来改变目录,read会将来自用户(和文件)的输入数据传给Shell外亮。
另一种内建命令的存在则是为了效率,其中最典型的就是test命令,编写脚本时经常会用到它。另外还有I/O命令,例如echo于printf.
(2)Shell函数是功能健全的一系列程序代码,以Shell语言写成,它们可以像命令那样引用。
(3)外部命令就是由Shell副本(新的进程)所执行的命令,基本的过程如下:
a. 建立一个新的进程。此进程即为Shell的一个副本。
b. 在新的进程里,在PATH变量内所列出的目录中,寻找特定的命令。
/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin为PATH变量典型的默认值。
当命令名称包含有斜杠(/)符号时,将略过路径查找步骤。
c. 在新的进程里,以所找到的新程序取代执行中的Shell程序并执行。
d. 程序完成后,最初的Shell会接着从终端读取下一条命令,和执行脚本里的下一条命令。

使用type可以查看是否是内建命令:
type (不带参数)会显示命令是内建命令还是外部命令
-t :file 外部命令;alias 命令别名;builtin 内置命令
-a :会将命令PATH路径显示出来
如何执行交互式命令:
用户在命令行输入命令后,一般情况下Shell会fork并exec该命令,但是Shell的内建命令例外,执行内建命令相当于调用Shell进程中的一个函数,并不创建新的进程.
比如:cd、alias、umask、exit等命令即是内建命令,凡是用which命令查不到程序文件所在位置的命令都是内建命令,内建命令没有单独的man手册,要在man手册中查看内建命令,应该man bash-builtins,内建命令虽然不创建新的进程,但也会有Exit Status,通常也用0表示成功非零表示失败,虽然内建命令不创建新的进程,但执行结束后也会有一个状态码,也可以用特殊变量$?读出


Linux/Unix命令通常被分为两类:内部命令:cd、source、fg外部命令:ls、cat我们来看看它们的区别。内部命令:内部命令被构建在shell之中。当执行shell命令时,内部命令的执行速度非常快。这是因为没有其他的进程因为执行这条命令而被创建。比如说,当我们执行“cd”命令时,没有进程被创建。在执行过程中只是简单的改变当前的目录。外部命令:外部命令并没有被构建在shell中。这些可执行的外部命令保存在一个独立的文件当中。当一个外部命令被执行时,一个新的进程即被创建同时命令被执行。比如说,当我们执行“cat”(通常被保存在/usr/bin目录下)命令时,然后/usr/bin/cat被执行。如何得到内部命令列表?如果你使用的是bash shell,你可以通过“help”命令得到所有内部命令列表

  1. $ help

  2. alias [-p] [name[=value] ... ] bg [job_spec ...]

  3. bind [-lpvsPVS] [-m keymap] [-f fi break [n]

  4. builtin [shell-builtin [arg ...]] caller [EXPR]

  5. case WORD in [PATTERN [| PATTERN]. cd [-L|-P] [dir]

  6. command [-pVv] command [arg ...] compgen [-abcdefgjksuv] [-o option

  7. .....

如何知道一个命令是内部命令还是外部命令?你可以使用type命令:
  1. $ type cd

  2. cd is a shell builtin

  3. $ type cat

  4. cat is /bin/cat

如果命令为内部命令,则type命令会明确的指出该命令是shell内嵌的。如果命令时外部命令,type则会给出该命令的执行路径。内部VS外部?我们该使用外部命令还是内部命令或者哪一种命令更好?像这样的问题是没有任何意义的。因为大多数情况下我们只要达成我们的目标,而不必在意使用的是内部命令还是外部命令。内部命令和外部命令最大的区别之处就是性能。内部命令由于构建在shell中而不必创建多余的进程,要比外部命令执行快得多。因此和执行更大的脚本道理一样,执行包含很多外部命令的脚本会损害脚本的性能。我们并不是总要面对内部命令与外部命令的选择。但是在我们脚本联系的过程中只要我们认真的观察,我们可以发现有些地方我们可以避免使用外部命令。比如说:将变量x与变量y求和赋予变量z。

外部命令:

  1. z=`expr $x+$y`

内部命令

  1. let z=x+y

let命令是shell的内嵌命令,然而expr则是外部命令。使用expr执行速度要慢一些。或许在一次性实例中这看起来微不足道。但是如果在执行大文件时,其区别则是显而易见的。


UNIX 命令有内部命令和外部命令之分。内部命令实际上是shell程序的一部分,其中包含的是一些比较简练的UNIX系统命令,这些命令由shell程序识别并在shell程序内部完成运行,通常在UNIX系统加载运行时shell就被加载并驻留在系统内存中。外部命令是UNIX系统中的实用程序部分,因为实用程序的功能通常都比较强大,所以它们包含的程序量也会很大,在系统加载时并不随系统一起被加载到内存中,而是在需要时才将其调进内存。通常外部命令的实体并不包含在shell中,但是其命令执行过程是由shell 程序控制的。shell程序管理外部命令执行的路径查找、加载存放,并控制命令的执行。内部命令要比外部命令的反应时间快一些,内部命令不用启动一个子shell来运行。

查看shell内部命令:[...]#man builtins

判断某命令是否是内部命令:[...]#type -a command

[...]#command --help 查看外部命令的帮助文件

[...]#help command 查看内部命令的帮助文件


资料来自网上整理,原文链接如下:

http://blog.sina.com.cn/s/blog_68b67a3b0100zy4n.html

http://www.cnblogs.com/xkfz007/archive/2011/10/13/2209571.html

http://blog.chinaunix.net/uid-25679817-id-3158845.html

http://tanghuimin0713.blog.51cto.com/4159848/755532