2

I've learned that this command:

echo -e "\a"

triggers a beep on the local system, whereas this command:

echo -e "\a" >/dev/console

triggers a beep on a remote system.

Why is this? What is the >/dev/console part doing?

Why is it that executing echo -e "\a" on a remote machine triggers the beep locally and not remote ?

Why does "echo" - command don't like sudo ?

Is there a OSI-Layer - like scheme ? Please provide me with some external documentation.

I have only a basic understandig of redirecting stdout/stderr to a file not much more, but the question more likely refers to how is "Gnu/Linux/Kernel" designed in order to requiere redirrection to

" > /dev/console" for a remote beep to work out.

Does a remote echo "Hello World" require a redirection to /dev/console ?

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232

1 Answers1

5

echo writes its output to its stdout. That's its file descriptor 1.

With echo -e '\a', depending on the echo implementation, that will either write a BEL character (0x7 byte value in ASCII) followed by LF (aka newline) or -e \a followed by LF or -e  followed by BEL and LF.

To write a BEL character only, you'd rather write printf '\a'.

That doesn't make much difference to the core of this question anyway. printf, like echo will write what it has to write to its stdout.

If you enter that command at the prompt of an interactive shell without redirection, stdout will be inherited from the shell. If the shell was started by a terminal emulator like xterm or screen, the file descriptor 1 will have been opened (by xterm) on a /dev/pt<something> device file (see lsof -ad1 -p "$$" or readlink -f /proc/self/fd/1 on Linux). That will be the slave side of pseudo-terminal pair.

The only thing important to know about it here is that it's some sort of communication channel. A bit like a pipe except that it has a few more bells and whistles that help with user interaction.

So when printf writes the BEL to that device file, what happens is that it's transmitted to something at the other end. In the xterm case, that's the terminal emulator itself. The BEL character is a control character that make terminal and terminal emulators alert the user in some way (\a is for alert). That can be an audible beep, chime or a visual flashing of the screen or both. xterm will typically use the XBell() X11 API call for that or flash its window if it's been configured to use a visual bell. screen itself would simply forward the BEL to the host terminal(s) it is connected to and where that screen window is active or issue a terminal flash control sequence or "Wuff, Wuff!!" (sic) message depending on how it was configured (see info screen vbell).

If you login on a PC running Linux outside of the graphic session, fd 1 will have been opened (by getty) to a /dev/tty<1-...> device. Here, it's the kernel that implements a terminal emulator and uses the monitor for output and keyboard(s) for input. Same principal, when printf writes that BEL there, the kernel makes the PC speaker beep.

When you run that command at the prompt of an interactive shell over ssh, fd 1 will also be a pseudo-terminal device (/dev/pt<something>), this time started by the ssh server which started the login shell of the remote user on the remote system. At the other end of the pseudo-terminal pair is the ssh server. When receiving that BEL (or anything else for that matters), the ssh server sends that across the encrypted connection to the ssh client, and the ssh client writes it to its stdout, which will eventually make it to the terminal window you're sitting at.

In

printf '\a' > /dev/console

The shell opens the /dev/console file on the file descriptor 1 (stdout) before running printf.

Now /dev/console, at least on Linux, is the tty device file that is meant to receive system messages. /dev/console typically redirects to another tty device. On PC, by default, that's /dev/tty0 which points to the currently active virtual terminal, but that can be changed at boot time using the console=/dev/anything kernel parameter (for instance console=/dev/ttyS0 to make it the first serial device), and it can even be changed (for the output part) later on, using the TIOCCONS ioctl() (see xterm -C).

In any case, that will be a terminal that is typically attached to the machine itself. So outputting a BEL there is meant to alert the administrator of that machine as it's using the channel used to send system messages to the user.

To write a message to all logged in users, you can also use the wall application, or the write application to just one user (one terminal device), provided those users have not disabled those notifications (with mesg n)