Zan*_*nna 59 command-line bash echo
我注意到/bin/echo我的 Ubuntu MATE 17.04 系统上有一个二进制可执行文件。
我想,这很奇怪,因为
$ type echo
echo is a shell builtinRun Code Online (Sandbox Code Playgroud)
粗略测试表明它/bin/echo与 Bash 内置函数做同样的事情echo:
$ /bin/echo foo
foo
$ /bin/echo $USER
zanna
Run Code Online (Sandbox Code Playgroud)
那么,为什么还有另一个echo独立于 Bash 程序的版本,我为什么或何时要使用它?
Eli*_*gan 93
如果你打开一个bash提示并输入一个echo命令,它使用内置的 shell而不是运行/bin/echo. 它仍然重要的原因/bin/echo是:
echo内置函数。这实际上不是必需的。为了扩展#1,假设您想将名称以abc任意位置开头的所有常规文件移动src到dest. 有几种方法可以做到这一点,但其中之一是:
find src -name 'abc*' -type f -exec mv -nv {} dest/ \;
Run Code Online (Sandbox Code Playgroud)
但是假设您想查看将首先运行的每个命令,而不仅仅是运行它。好吧,那么您可以echo在命令之前添加,就像在其他上下文中一样:
find src -name 'abc*' -type f -exec echo mv -nv {} dest/ \;
Run Code Online (Sandbox Code Playgroud)
但find不使用外壳。那运行/bin/echo。
除了findwith-exec或-execdir,/bin/echo可执行文件将被其他程序调用,这些程序本身运行程序但不通过 shell。这种情况发生与xargs命令(其涉及到find),以及在许多其他情况下,如所述Exec=线的一个.desktop文件。另一个例子是当你运行时sudo echo,它可以方便地测试是否sudo工作。
类似地,一些 shell 具有printf内置但/usr/bin/printf也存在。
您可能故意使用的一个不太常见的可能原因/bin/echo是您是否依赖于它与echo您的 shell 提供的命令之间的差异。man echo文件/bin/echo;help echo在 bash文档中bash内置。echo不是很可移植,因为不同的实现——跨操作系统和跨同一操作系统上的 shell——支持不同的选项(例如,-e)并且在处理反斜杠方面不同。当然,最好避免依赖这些细节,而使用printf它,这样更便携。
在 中bash,您也可以通过将标志传递给它来制作type内置节目/bin/echo- 假设它一直应该/bin在您的作品中:$PATH-a
$ type -a echo
echo is a shell builtin
echo is /bin/echo
Run Code Online (Sandbox Code Playgroud)
mur*_*uru 31
Eliah 在回答这个问题方面做得很好,但我想评论一下“为什么有另一个版本的echo与 Bash 程序分开的版本”部分。那是错误的问题。
正确的问题是:为什么这首先是一个内置命令,而它本来可以(并且现在)是一个完美的外部命令?
为简单起见,看看 dash 中的内置函数,只有 38 个(bash 有 61 个,为了比较,通过 的输出compgen -b):
. continue getopts readonly type
: echo hash return ulimit
[ eval jobs set umask
alias exec kill shift unalias
bg exit local test unset
break export printf times wait
cd false pwd trap
command fg read true
Run Code Online (Sandbox Code Playgroud)
其中有多少需要内置?[,echo,false,printf,pwd,test,和true不要需要是内建的:他们没有做任何事情,只有内置可以做(影响或获得,这不是提供给外部命令外壳状态)。Bashprintf至少利用了作为内置函数的优势:printf -v var将输出保存到变量var. timein bash 也很特别:作为关键字,您可以在 bash 中对任意命令列表进行计时(dash 没有time等效项)。pwd也不需要是内置命令 - 任何外部命令都将继承当前工作目录(它是一个外部命令)。:是一个例外——你需要一个 NOP,:是的。其余的执行外部命令可以轻松执行的操作。
因此,这些内置函数中有五分之一不需要是内置函数。那为什么?手册dash页* 实际上顺便解释了为什么这些是内置函数(强调我的):
内置函数 本节列出了内置命令,因为它们 需要执行一些单独无法执行的操作 过程。除了这些,还有其他几个命令可以 为提高效率而内置(例如 printf(1)、echo(1)、test(1) 等)。
差不多就是这样:这些内置函数之所以存在,是因为它们经常以交互方式和在脚本中使用,而且它们的功能非常简单,shell 可以完成这项工作。所以它发生:一些(?大多数)弹了在工作**回去。在sh从2.9 BSD,你不会找到一个echo内置。
因此,一个最小的 shell 完全有可能跳过实现诸如内置命令之类的命令(不过,我认为当前的任何 shell 都不会这样做)。GNU coreutils 项目不假设您将在特定的 shell 中运行它们,并且 POSIX 需要这些命令。因此,coreutils 无论如何都会提供这些,并跳过那些在 shell 之外没有任何意义的内容。
* 这与Almquist shell 的相应联机帮助页文本几乎相同,这是 dash,Debian Almquist shell 的基础。
**zsh将这个想法发挥到极致:您通过加载各种模块获得的命令,例如zmv,是您认为 shell 甚至不需要进入的东西。那时,真正的问题是:为什么要使用 bash 而不是 zsh,后者具有所有这些内置函数?
| 归档时间: |
|
| 查看次数: |
16445 次 |
| 最近记录: |