Answers:
答案或多或少ls
是一个外部可执行文件。您可以通过运行查看其位置type -p ls
。
那么为什么不ls
内置到外壳中呢?好吧,为什么呢?Shell的工作不是包含所有可用命令,而是提供一个能够运行它们的环境。某些现代shell具有echo
,printf
和其类似的内建插件,从技术上讲,它们不一定是内建插件,但出于性能方面的考虑,当它们重复运行(主要是在紧密循环中)时才这样做。如果不使它们内置,则外壳将不得不为每次对其调用进行分叉并执行一个新进程,这可能会非常慢。
至少,运行ls
外部可执行文件需要运行exec系列系统调用之一。您可以不用分叉来执行此操作,但是它将替换您正在使用的主shell。通过执行以下操作,您可以查看在该情况下发生的情况:
exec ls; echo "this never gets printed"
由于您的Shell的过程映像已替换,因此执行此操作后将无法再访问当前Shell。为了使外壳程序在运行ls之后能够继续运行,必须将命令内置到外壳程序中。
分叉允许替换不是您的主Shell的进程,这意味着您之后可以继续运行Shell。
echo
,printf
等
cd
没有外部可执行文件?
该猛砸参考手册状态:
内置命令对于实现使用单独的实用工具无法获得或不方便的功能是必需的。
也就是说,shell设计为仅在以下情况下包括内置命令:
该ls
命令不符合以上任何要求。
但是,这里没有编程约束可以防止ls
被实现为内置函数,该约束 在与bash解释器相同的过程中执行。Shell内置命令不被实施的设计原因是:
关于第一个原因-您希望外壳尽可能独立且具有弹性。您不希望外壳卡在ls
“不响应仍在尝试”的NFS挂载上。
关于第二个原因-在许多情况下,您可能希望为使用Busybox或其他ls
实现不同的文件系统的系统使用外壳程序。甚至在具有不同ls
实现的OS中使用相同的Shell源。
关于第三个原因-对于像find . -type d | xargs ls -lad
这样的表达式,很难或不可能ls
在与shell解释器相同的过程中实现。
关于第四个原因-有些ls
命令可能需要很长时间才能完成。您可能希望外壳在此期间继续执行其他操作。
注意:有关类似问题,请参见沃伦·杨(Warren Young)的这篇有用的帖子。
ls
。可以做到,但是会很复杂。
bash
输出alias | grep ls
。输入cat /etc/passwd | while read a; do echo "$a"; done
ls
不需要单独的过程。实际上,很少有命令需要单独的过程:只有那些需要更改特权的命令。
通常,仅当需要将命令实现为内置命令时,shell才将命令实现为内置命令。命令状alias
,cd
,exit
,export
,jobs
,...需要读取或修改壳体内部的一些状态,因此不能单独的程序。没有这样要求的命令可以是单独的命令。这样,可以从任何外壳程序或其他程序中调用它们。
查看bash中的内置程序列表,只有以下内置程序可以实现为单独的命令。对于其中的一些功能,会有些损失。
command
-但是在PATH
可能无法正确设置并且脚本正在将其command
用作设置一部分的情况下,它将失去其用处。echo
—这是提高效率的内置功能。help
—它可以使用单独的数据库,但是将帮助文本嵌入到shell可执行文件中的优点是使shell可执行文件具有独立性。kill
—内置有两个优点:它除了可以识别进程ID外,还可以识别作业指定,并且即使没有足够的资源来启动单独的进程,也可以使用它。printf
—出于与相同的原因echo
,并且还支持-v
将输出放入变量的选项。pwd
—内置函数提供了逻辑当前目录跟踪的附加功能(保持符号链接完整而不是扩展它们)。test
—它是提高效率的内置工具(bash /dev/fd/…
对某些操作系统上调用的文件也起到了神奇作用)。一些外壳程序提供了大量的附加内置函数。有一个sash,它是一个外壳,旨在作为紧急修复的独立二进制文件(某些外部命令可能不可用时)。它有一个内置的ls
,所谓的-ls
,以及其他工具,如-grep
和-tar
。Sash的内置函数比完整的命令要少。Zsh在其zsh / files模块中提供了一些类似的内置函数。它没有ls
,但是通配符扩展(echo *
)zstat
可以起到类似的作用。
我认为人们在这里缺少的是ls
Linux上GNU 程序的复杂性。将Debian系统上和的可执行文件大小ls
与bash
和dash
外壳程序进行比较,我们发现它很大:
graeme@graeme:~$ ls -lh /bin/{ls,bash,dash}
-rwxr-xr-x 1 root root 953K Mar 30 2013 /bin/bash
-rwxr-xr-x 1 root root 115K Dec 25 20:25 /bin/dash
-rwxr-xr-x 1 root root 108K Jul 20 22:52 /bin/ls
包含一个ls
与GNU版本一样的功能,bash
将使可执行文件的大小增加10%。它的大小几乎与整个dash
外壳相同!
之所以选择大多数shell内置程序,是因为它们以外部可执行文件无法与外壳程序集成的方式(问题指出cd
,但另一个示例是kill
与bash作业控件集成的bash版本),或者因为它们是实现起来非常简单的命令,给出较大的速度与大小的收益(true
并且false
就这么简单)。
GNU的ls
开发周期很长,可以实现一些选项来定制显示结果的方式。默认情况下使用内置的ls可能会失去此功能或显着增加外壳的复杂性和尺寸。
ls
是一个外部程序,但echo *
orecho * .*
(取决于shell选项)在不分叉的情况下很好地列出了文件。