Bash为什么同时拥有内置的echo命令和独立的echo程序?

huangapple go评论75阅读模式
英文:

Why does Bash have both a built-in echo command and standalone echo programs?

问题

我正在使用Ubuntu 22.04上的Bash shell。

当我运行type -a echo时,我得到以下输出:

Bash为什么同时拥有内置的echo命令和独立的echo程序?

我理解的是,当我运行一个命令,比如echo "Hello Wolrd!",Bash会运行内置的echo命令。我是对的吗

我的第一个问题是:如果Bash默认运行内置的echo命令,那为什么会有独立的echo程序:/usr/bin/echo/bin/echo?有没有特定的情况下需要使用独立的echo程序?

我的第二个问题是:为什么会有两个独立的echo程序,如上面的截图所示?如果我决定运行独立的程序,应该使用哪一个,为什么?

我会感激详细的回答。谢谢。

编辑-1
当我运行readlink命令来检查/bin是否是一个指向/usr/bin的符号链接时,我得到以下结果:

Bash为什么同时拥有内置的echo命令和独立的echo程序?

英文:

I am using a Bash shell on Ubuntu 22.04.

When I run type -a echo, I get the following output:

Bash为什么同时拥有内置的echo命令和独立的echo程序?

What I understand is that when I run a command, let's say echo "Hello Wolrd!", Bash will run the built-in echo command. Am I right?

My first question is: If Bash runs the built-in echo command by default, why there are standalone echo programs: /usr/bin/echo and /bin/echo? Are there specific scenarios when one would prefer to use the standalone programs of echo?

My second question is: Why there are two standalone programs of echo, as shown in the screenshot above? And if I decide to run the standalone program, which one should I use and why?

I would appreciate a detailed answer. Thanks.

Edit-1
This is what I get when I run the readlink command to check whether /bin is a symlink to /usr/bin:

Bash为什么同时拥有内置的echo命令和独立的echo程序?

答案1

得分: 4

Bash仅有内置的echo。您系统中的/bin/echo程序不是来自Bash包/项目。

Bash的echo仅在Bash内部可用。我们无法让操作系统执行echo程序,例如使用C库的execl函数:

没有/bin/echo,例如,这是无法工作的:

execl("/bin/echo", "echo", "foo", (char *) NULL);

只能这样:

execl("/bin/sh", "sh", "-c", "echo foo", (char *) NULL);

但是,为什么您需要执行/bin/echo,而不是只需使用编程语言的I/O库将内容输出到标准输出?这是一个好问题:您不需要。/bin/echo的特定示例除了作为一个Shell内置外,几乎没有用处,而且即使是Shell内置也已经被大部分废弃了。

存在真正的echo命令的主要原因是,嗯,POSIX,咳咳,回应了我上面关于execl的评论。请参阅此处的第1.6节,其中提到了这个要求:

> *但是,所有标准实用程序,包括表格中的常规内置工具,但不包括专用内置工具的描述在专用内置工具中,都应以一种方式实现,以便可以通过在POSIX.1-2008的系统接口卷中定义的exec系列函数来访问,并可以直接由那些需要它的标准实用程序调用(envfindnicenohuptimexargs等)。

这也提供了我们正在寻找的理由:有些实用程序调用其他实用程序,如xargsfind,而不使用Shell,而是使用exec机制。它们不能使用仅作为内置工具的实用程序。

echo的具体情况下,将其与上述任何命令一起使用并不是很有用;但是POSIX不会对echo实用程序做出特殊规定;如果它作为内置工具提供,它仍然必须以exec可执行的形式提供。

唯一允许仅作为内置工具存在的实用程序是那些必须在内置工具中才有意义的实用程序的子集。甚至其中并非所有都是内置工具,例如cd作为外部命令没有意义,因为它不会更改执行它的进程的目录;最多只提供错误检查,看是否能够更改目录。然而,cd不是可以仅作为内置实用程序提供的“专用内置工具”之一;POSIX系统必须具有可执行的cd实用程序。

英文:

Bash has only a built-in echo. The /bin/echo program in your system is not coming from the Bash package/project.

Bash's echo is only available from within bash. We cannot get the operating system to execute an echo program, for instance with the C library execl function:

Without a /bin/echo, for instance, this cannot work:

execl("/bin/echo", "echo", "foo", (char *) NULL);

Only this:

execl("/bin/sh", "sh", "-c", "echo foo", (char *) NULL);

But, why would you ever need to exec /bin/echo, instead of just using the I/O library of the programming language to dump something to standard output? That's a good question: you wouldn't. The specific example of /bin/echo is not a useful program to have other than as a shell built-in. And even that is mostly deprecated.

The main reason why there is a real echo command is that, well, POSIX, ahem, echoes my remarks above about exec. See section 1.6 here where this requirement is given:

> However, all of the standard utilities, including the regular built-ins in the table, but not the special built-ins described in Special Built-In Utilities, shall be implemented in a manner so that they can be accessed via the exec family of functions as defined in the System Interfaces volume of POSIX.1-2008 and can be invoked directly by those standard utilities that require it (env, find, nice, nohup, time, xargs).

This also provides the rationale we are looking for: there are certain utilities which invoke other utilities, like xargs and find, without the use of a shell: just by the exec mechanism. They cannot work with utilities that are built-in only.

In the specific case of echo, using it with any of the above commands is not very useful; but POSIX doesn't make an exception for the echo utility; if it is offered as a built-in, it must still be also provided in exec-able form.

The only utilities that are allowed to exist as built-ins only are those that must necessarily be built-in in order to make sense. And not even all of those, but a subset. For instance cd doesn't make sense as an external command, since it doesn't change the directory of the process which executes it; at best it provides an error check whether it is able to change directory. Yet, cd is not one of the Special Built-In Utilities that can be provided only as built-in utilities; a POSIX system must have an executable cd utility.

答案2

得分: 1

> Am I right?

是的。

> why there are standalone echo programs

因为你可能想要使用它们。

> Are there specific scenarios when one would prefer to use the standalone programs of echo?

是的,当你使用 fork+exec 并希望运行 echo 而不是 bash 时,就像评论中提到的 xargs echo。请注意,默认情况下,不带参数的 xargs 会运行 echo,所以有点像 xargs 取决于存在 echo 可执行文件。

> Why there are two standalone programs of echo, as shown in the screenshot above?

在大多数系统上,/bin 是一个指向 /usr/bin 或其他地方的符号链接。它是同一个文件。

> which one should I use and why?

使用 PATH 中排在第一位的那个。因为 PATH 用于选择要运行的内容。

英文:

> Am I right?

Yes.

> why there are standalone echo programs

Because you might want to use them.

> Are there specific scenarios when one would prefer to use the standalone programs of echo?

Yes, when you fork+exec and want to run echo, not bash. Like xargs echo given in comments. Note that xargs with no arguments by default runs echo, so kind of xargs depends on existence of echo executable.

> Why there are two standalone programs of echo, as shown in the screenshot above?

On most systems, /bin is a symlink to /usr/bin or otherwise. It is the same file.

> which one should I use and why?

Use the one first in PATH. Because PATH is for choosing what to run.

huangapple
  • 本文由 发表于 2023年7月20日 14:35:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76727253.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定