为什么 Linux wall 命令不会广播字符串参数?

mbb*_*mbb 13 linux command-line

在这里读到这应该有效,但它没有:

# usage: wall [file]
root@sys:~> mesg
is y

root@sys:~> wall "who's out there"
wall: can't read who's out there.
Run Code Online (Sandbox Code Playgroud)

如果mesg设置为y,是什么阻止我广播字符串?请注意,我确实确认文件选项有效:

root@sys:~> wall test
Broadcast Message from root@sys (/dev/pts/1) at 15:23 ... 
Who's out there?
Run Code Online (Sandbox Code Playgroud)

pet*_*eth 22

问题在于链接文章中使用的语法。要了解究竟出了什么问题,让我们来看看man wall

用法来自man wall

wall [file]

Wall displays the contents of file or, by default, its standard input
Run Code Online (Sandbox Code Playgroud)

因此,wall接受任何的两个来源为它的消息。

文件名参数

给定的任何命令行参数wall都必须是文件名。由于没有可靠的方法来判断参数是作为消息名还是文件名,wall将假定它是后者,忽略标准输入中的任何内容,并尝试从该文件读取消息。

在给定的情况下,它尝试从文件中读取who's out there但没有找到它。请注意,读取文件通常仅限于超级用户。如果您wall "who's out there"以非特权用户身份执行,它的输出可能是,wall: will not read who's out there - use stdin.

标准输入

如果它在命令行上没有得到文件名参数,它将开始从标准输入读取。有几种方法可以向命令的标准输入提供信息。一种是使用UNIX 管道。管道将其左侧命令的标准输出连接到其右侧命令的标准输入:

$ echo "who's out there" | wall
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用here 文档。Ahere document是一种 shell 构造,它直接将字符串(最多到其自身一行上的指定结束标记)传递给命令的标准输入,而无需让不同的命令产生该输出的中间步骤:

$ wall << .
who's out there?
.
Run Code Online (Sandbox Code Playgroud)

这将是“对 here 文档的无用使用”,因为默认情况下终端本身将连接到wall的标准输入并wall开始从中读取,直到它收到文件结束字符 ( Ctrl+D):

$ wall
who's out there?
^D
Run Code Online (Sandbox Code Playgroud)

正如Rich Homolka在评论中指出的那样,一些 shell 支持here strings允许传递没有命令或结束标记的文字字符串:

$ wall <<< "who's out there?"
Run Code Online (Sandbox Code Playgroud)

都向wall的标准输入提供一些东西。不同的是,一个管道连接另一个命令给它的输出端,而here documentshere strings直接传递的字符串。后两者的优点是美观,因为echo管道示例中的命令是 shell 内置命令,因此wall在所有情况下都是shell 提供的输入。