内置命令与非内置命令有什么区别?


72

内置命令和另一个名义上可以做相同事情的命令之间有本质上的区别吗?

例如。内建函数是否获得“特殊”待遇?...运行它们的开销较少吗?..或者它们只是简单地“内置”;像您的汽车仪表板?

...并且这些内置函数有明确的列表(当前列表)吗?

Answers:


90

从您的评论中,您似乎对外壳到底是什么感到困惑。内核负责管理系统。它是实际加载和运行程序,访问文件,分配内存等的部分。您只能通过使用其他程序作为中介与它进行通信。

外壳程序是一个程序,它会打印提示,从您那里读取一行输入,然后将其解释为一个或多个命令来操作文件或运行其他程序。在GUI发明之前,外壳是OS的主要用户界面。在MS-DOS上,调用了该外壳command.com,很少有人尝试使用其他外壳。但是,在Unix上,长期以来,用户可以从中选择多个shell

它们可以分为3种类型。兼容Bourne的shell使用从原始Bourne shell派生的语法。C Shell使用原始C Shell中的语法。然后是非传统的外壳,它们发明了自己的语法,或者从某种编程语言中借用了它们,并且通常不如前两种类型流行。

内置命令只是shell自己执行的命令,而不是将其解释为加载和运行其他程序的请求。这有两个主要作用。首先,它通常更快,因为加载和运行程序需要时间。当然,命令运行的时间越长,与总运行时间相比,加载时间的重要性就越小(因为加载时间相当恒定)。

其次,内置命令会影响外壳的内部状态。这就是为什么cd 必须内置类似命令的原因,因为外部程序无法更改外壳程序的当前目录。其他命令(例如echo)可能是为提高效率而内置的,但没有内在的原因,它们不能是外部命令。

内置哪些命令取决于您使用的外壳。您必须查阅其文档以获取列表(例如,其bash内置命令在其手册的第4章中列出)。该type命令可以告诉您命令是否是内置命令(如果您的外壳兼容POSIX),因为POSIX要求该命令是内置命令type。如果which您的外壳程序不是内置的,则它可能不会知道您外壳程序的内置程序,而只会查找外部程序。


应用程序实际上通过发出中断与内核进行通信。
内森·奥斯曼

11
@George:应用程序通过发出系统调用与内核进行通信,这些调用取决于操作系统和体系结构,可能使用也可能不使用中断。通常,用户不会发出中断。
Gilles

2
@cjm:当您这样解释时,听起来很简单:)...您当然已经帮助清除了雾...现在只是薄雾..(实际上,今天早晨的天气就是这样)。 ..令人愉快的薄雾;)...谢谢
Peter.O 2011年

@吉尔斯:真的吗?我认为所有用户模式程序都通过中断与内核通信(当然,在某些体系结构上)。
内森·奥斯曼

2
@cjm非常彻底和有益的答案。我从中学到了很多东西。:)
ankush981

37

内置实用程序分为三个级别:

  • 尽管某些实用程序不是保留字,但它们实际上是外壳程序语言的一部分。他们是控制流工具(.:breakcontinuereturntrapexitexeceval),参数相关的实用程序(setunsetshiftexportreadonlylocal¹,typeset¹),别名公用事业(alias²,unalias²)和times³。这些特殊的内置插件得到特殊待遇:

    • 如果将错误的参数传递给特殊的内置程序,则外壳本身可能会中止,而不仅仅是在显示错误消息后跳到下一个命令。
    • 预分配语法foo=bar utility具有不同的含义:这是普通的参数分配(即foo=bar; utility),而不是仅在实用程序期间分配给环境。
  • 一些实用程序需要在Shell内实现,因为它们会作用于Shell的内部设置。这包括:

    • 上壳的当前目录如Act公用事业cddirspushdpopd
    • 作业控制实用程序,如bgdisownfgjobswait;
    • 读取和操控其他壳属性,诸如公用事业builtincommandhashreadtypeulimitumask;
    • 与互动功能相关的实用程序(如fc,,historybind
  • 一些实用程序通常作为内置插件纯粹是为了表现echoprintftesttruefalse

诸如bashkshzsh之类的高级shell 通常具有更多的内置功能,通常用于实现非标准功能(通常用于交互)。每个shell的手册将告诉您内置了哪些命令,尽管某些shell(至少zsh)支持可动态加载的模块,这些模块可以提供更多的内置功能。

¹POSIX 未知,但在ksh和其他几个shell中很特殊。
² 在POSIX中是普通的,但在ksh和其他几个shell中是特殊的。
³ kshtimes是周围的包装time关键字:这是一个别名{ { time;} 2>&1;}。请注意,POSIX可以time是具有常规解析功能的外部实用程序,也可以是适用于整个管道的关键字(它在ksh中,在zsh中是bash)。


3
这些区别是真正重要的区别。
dmckee 2011年

一个简单的问题,那么当我们做“普通参数分配”意味着什么while IFS= read -r line
Sergiy Kolodyazhnyy

@SergiyKolodyazhnyy read不是一个特殊的内置函数,因此IFS=read仅在命令执行期间设置变量。
吉尔斯

10

内置命令是外壳程序提供的命令,而不是外部程序提供的命令。以下是bash的内建程序列表(它们也在bash手册页中列出)和zsh的内建程序列表ksh通过运行提供列表builtin

要了解特定命令是否为内置命令,可以运行type command。尝试type fortype ls看到这一点。


type似乎可以解决问题;谢谢...但是我仍然想知道“ shell提供的”是什么意思...也许我需要更全面地了解shell与内核的关系....但不是凌晨2点。回到这个明天
Peter.O

1

每个发行版和外壳程序都具有与内置外壳程序函数不同的命令集合。通常的想法是,shell内置了最常用和最简单的功能,以节省时间,速度并与其他功能集集成。开销要低得多,因为它不必启动另一个系统进程。但是,可以混合搭配。您可能会运行一个具有内置功能的外壳程序,但在您的系统上也具有该命令。通常,内置命令会优先处理,但是您可以控制它。

您可以通过运行轻松找到特定命令是否为内置命令type mycommand。大多数Shell手册页也包含其内置列表。

编辑:使用type找出一个命令是否是内置的,如果没有which学习的地方将被执行。


@Caleb:谢谢您的评论,但是这让我想知道“系统过程”到底是什么。.我一直在看到关于它的引用,但是我不明白区别在哪里。看看“哪个”是绝对指示器)...例如“哪个回声=>"/bin/echo" and 类型echo =>"echo is a shell builtin", but 'which dd=>“ / bin / dd”和type dd=>“ dd是/ bin / dd” ...所以,我在其中....
Peter.O 2011年

“系统进程”仅表示它正在作为由内核管理的独立应用程序启动。对于内建函数,替代方法是仅在外壳程序已运行的代码中运行子功能。在您提供的示例中,type它可以更好地指示正在运行的内容,但是您注意到echo它既是内置的,也有使用该名称的应用程序。如果您的外壳没有内置系统,则可以运行该系统。
Caleb

2
which不一定是内置命令,如果不是,则不会知道Shell的内置命令。POSIX要求它type是内置命令,因此它始终了解内置命令。
cjm 2011年

许多系统出厂时都带有whichto type或一组选项的别名,例如alias which='type -path'-这可能是造成混乱的原因。
Random832

1
我无法投票,直到which被替换type。我一遍又一遍地使用它,不知道type并且很惊讶,这which只有在决定程序之间时才是正确的。
用户未知,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.