Control Who Can Write to Your Linux Terminal with mesg

Somebody runs write at your terminal and text you didn't ask for shows up mid-command: mesg is the switch that stops it. The examples use the system command at /usr/bin/mesg, supplied by util-linux 2.39.3 on this machine. Allow about five minutes. You need a shell attached to a terminal; changing this setting normally needs no elevated privileges.

Safety boundary: mesg changes the write permission on the terminal device tied to standard error. It does not touch login accounts, SSH configuration or any system-wide messaging policy. The setting affects only the terminal you run it in, so keep the command in the window you actually mean.

1. Confirm the command and its version

Check the system binary explicitly. This sidesteps a distracting shell PATH issue: another util-linux installation could supply a different version under the same command name.

$ command -v /usr/bin/mesg
/usr/bin/mesg
$ /usr/bin/mesg --version
mesg from util-linux 2.39.3

The installed manual documents n to disallow messages, y to allow them, and no argument to report the current state.

2. Inspect the current setting

Run the command with no argument:

$ /usr/bin/mesg
is y

is y means messages are allowed, is n means they're blocked. That's the whole output. The exit status carries the same answer, so capture it immediately if a script or a diagnosis depends on it:

$ /usr/bin/mesg
is y
$ status=$?
$ printf 'mesg status: %s\n' "$status"
mesg status: 0

Checkpoint: If you see no useful status, confirm this shell is attached to a terminal before you change anything. Don't test this by copying the command into a pipeline or a background job.

3. Block terminal messages

To stop programs such as write and talk from displaying messages in this terminal, run:

$ /usr/bin/mesg n
$ /usr/bin/mesg
is n
$ printf 'mesg status: %s\n' "$?"
mesg status: 1

This changes the terminal device's write permission for the current session. It doesn't kill an existing shell and doesn't delete any messages: a sender may still get a separate error, depending on the sending program and terminal permissions.

There's no elevated command here. sudo can make the operation less clear and may end up touching a different terminal context, so leave it out.

4. Allow messages again

Use y to restore the permission:

$ /usr/bin/mesg y
$ /usr/bin/mesg
is y
$ printf 'mesg status: %s\n' "$?"
mesg status: 0

This is the undo for the previous step. If you're not sure which state you left behind, run the no-argument check rather than toggling blindly. Unlike older historical implementations, the util-linux command does not invert the state when called with no argument; it reports it.

5. Use the exit status in a script

Branch on the documented status rather than matching the human-readable text. This version keeps the diagnostic output out of the script's own output:

if /usr/bin/mesg >/tmp/mesg-status 2>/tmp/mesg-error; then
    printf '%s\n' 'terminal messages are allowed'
else
    status=$?
    case "$status" in
        1) printf '%s\n' 'terminal messages are blocked' ;;
        *) printf 'mesg failed with status %s\n' "$status" >&2; exit "$status" ;;
    esac
fi
rm -f /tmp/mesg-status /tmp/mesg-error

Status 0 and 1 are both normal results; anything above 1 is an error. The temporary paths above are fine for a small local status check but not for sensitive data, so use a private temporary directory in a real script. There is no documented --quiet option, so don't invent one.

6. Diagnose the non-terminal failure

When standard error isn't connected to a terminal, mesg has nothing to control. The manual says it exits silently with status 2. --verbose asks it to explain that situation instead:

$ /usr/bin/mesg --verbose
$ printf 'mesg status: %s\n' "$?"
mesg status: 2

The exact wording can vary with the invocation and the util-linux release, but status 2 is the reliable diagnostic. Run the command directly in an interactive terminal, not through a command substitution, a redirected standard error, or a CI step with no pseudo-terminal.

Done means