Why won't the Linux wall command broadcast a string argument?
Solution 1:
The problem lies in the syntax used in the linked article. To understand what exactly goes wrong, let's have a look at man wall
:
Usage from man wall
:
wall [file]
Wall displays the contents of file or, by default, its standard input
So wall
accepts either of two sources for its message.
File name argument
Any command line argument given to wall
has to be a file name. As there isn't a reliable way to tell if the argument is meant as message or file name, wall
will assume it's the latter, ignore anything coming in on standard input, and try to read the message from that file.
In the given case, it tries to read from the file who's out there
and does not find it. Note that reading from a file is usually restricted to the superuser. If you'd executed wall "who's out there"
as an unprivileged user, likely its output would have been, wall: will not read who's out there - use stdin.
Standard input
If it doesn't get a file name argument on its command line, it will start reading from standard input. There are several ways to feed information to the standard input of a command. One is to use a UNIX pipe. A pipeline will connect the standard output of its lefthand-side command to the standard input of its righthand-side command:
$ echo "who's out there" | wall
Another way is to use a here document. A here document
is a shell construct that passes a string (up to a specified end marker on a line of its own) directly to the standard input of a command, without the intermediate step of having a distinct command produce that output:
$ wall << .
who's out there?
.
This would be a "useless use of here documents", because by default the terminal itself will be connected to wall
's standard input and wall
will start reading from it until it receives an end-of-file character (Ctrl+D):
$ wall
who's out there?
^D
As Rich Homolka noted in the comments, some shells support here strings
which allow passing a literal string without command or end markers:
$ wall <<< "who's out there?"
All feed something to wall
's standard input. The difference is that a pipeline connects the output of another command to it, while here documents
and here strings
pass the string directly. The latter two's advantage here is an aesthetic one, as the echo
command from the pipe example is a shell built-in command, so it will be the shell providing wall
's input in all cases.