2017-04-01 21 views
2

我对内置shell的定义有点困惑。根据Bash Reference Manual,对于任何内置的,shell都会直接执行该命令,而不会调用另一个程序。究竟是什么意思,“命令直接执行”?例如,让我们来看看内置cdshell内置执行

$ which cd 
/usr/bin/cd 
$ type cd 
cd is a shell builtin 

现在,让我们来看看非内置grep

$ which grep 
/usr/bin/grep 
$ type grep 
grep is /usr/bin/grep 

看来,cd是一个独立的二进制文件。执行cd(或任何其他内置)与执行grep(或任何其他非内建)有什么不同?

+2

'cd'在这里是一个特殊情况,因为它必须是一个内建的任何有用的效果。 '/ usr/bin/cd'实际上是无用的,因为它作为自己独立的进程运行,它改变它自己的目录然后退出 - 但是**不会改变调用它的单独程序的目录。 –

+2

(...如果我们要迂腐的话,那么'/ usr/bin/cd'有一点点用处 - 它决定了你是否可以*通过实验改变到给定的目录。) –

回答

5

某些命令既作为内置的shell存在,也作为单独的程序存在。 which命令(这是一个单独的程序,而不是内置的!)只能找到单独的程序,并且永远不会打扰builtin。尝试使用type readarraywhich readarray来查看仅作为内置函数存在的命令。

重要的是要注意内置版本和外部程序可能会有所不同。在某些情况下,您可能更喜欢依赖内建(即如果您知道脚本将用于何种外壳,但不确定要执行哪个外部版本),或者相反。

您可以使用其完整路径调用外部程序(这将绕过内建)。

当调用一个外部程序时,操作系统将启动一个单独的进程,而内建程序是shell程序本身的一部分,因此会有更低的开销。在很多情况下,这种开销并不重要,但是如果您要多次执行命令,可能会对脚本的性能产生重大影响。

+0

感谢回复!!那很有意思。如果这些二进制文件已经作为内置函数存在,那么这些二进制文件在哪里呢?他们曾经使用过吗? –

+0

@AlexanderKohler,你只能从shell *中使用shell内建*。任何使用'execv'-family系统调用直接执行其他程序的东西都不能使用shell内置函数,而需要外部二进制文件。 –

+1

@AlexanderKohler,...所以,'找到。 -exec foo {} +'总是将'foo'作为一个外部可执行文件调用,而不管这个名字是否存在内置函数(shell函数,别名等)。 –

2

除了弗雷德的正确答案:

我明白您对内建和外部命令的冲突。 cd命令实际上是一个小示范。

例如我的系统上,情况如下:

$ which cd # gives no output 
$ whereis cd # again, no path found 
cd: 
$ type -a cd # verifies that it's a real builtin command 
cd is a shell builtin 

这清楚地表明,在外部程序换算的cd命令没有我的机器上安装。在你的情况下,which cd显示在/usr/bin/cd下安装了额外的cd命令(单独的程序)。

有时不清楚何时输入cd是否打算调用内置命令或外部命令。为了确保,你真的调用内置cd命令,就可以执行以下命令:

$ builtin cd 

从内置cd命令的帮助页面:

$ help builtin 

内置:内置[壳 - 内建[arg ...]] 执行shell内置函数。现在

Execute SHELL-BUILTIN with arguments ARGs without performing command 
lookup. This is useful when you wish to reimplement a shell builtin 
as a shell function, but need to execute the builtin within the function. 

可以看到builtin命令如何使用强制执行shell内建命令的执行。这在特殊情况下非常有用。

此外,还可以(它实际上是显而易见的)期望从内置命令 [source]更好的性能:

在一般情况下,在脚本叉掉一个子进程的外部命令, [*]而猛砸内置呢不。由于这个原因,内置函数更快地执行 ,并使用比它们的外部 等效命令少的系统资源。

+0

Ooo,我不知道这个'builtin'命令。现在这一切都变得更有意义。谢谢!! :) –

+0

呵呵,当我第一次偶然发现'builtin'命令时,事情对我来说就变得更加清晰了。 –