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.