16 May 2011

Sending Messages to Users

Recently while working on a problem with someone else, I needed to have
them run a series of commands with specific options.  Since we were
both working remotely, it wasn't as simple as telling them to look
over my shoulder.  Though I tried telling them the commands over the
phone, we ran into the issue of parts of the commands being misheard or
misunderstood.  To alleviate any confusion, I resorted to an old friend,
the 'write' command.  While 'write' can be quite useful, it seems many
are unfamiliar with it.  With that in mind, here's how to use 'write'.
Our host details are:
        HOSTS:          sunspot (solaris), berkeley (freebsd), cobblepot (linux)
        PROMPT:         user@host tty [0]
        OS VERSIONS:    Solaris 10, FreeBSD 8.1, CentOS 5.6
        USERS:          calif, troy, root
        NOTE:           'write' has been around for quite a while so the following
                        should easily apply to prior OS versions.  Also, while
                        Solaris is used in the examples, the same setup could have
                        been run on Solaris, FreeBSD, or CentOS.
To start things off, below we see user "calif" connected to tty 1 (pts/1)
and user "troy" on tty 2 (pts/2):
        calif@sunspot pts/1 [0] /usr/bin/tty
        /dev/pts/1 
        calif@sunspot pts/1 [0] /usr/bin/who
        calif       pts/1        May 16 22:31    (glados)
        troy       pts/2        May 16 22:40    (glados)
To show to troy how to use the 'write' command, calif sends troy a
message via 'write':
        calif@sunspot pts/1 [0] /usr/bin/write troy pts/2
        this is an example of using the write command to send a message to a user

        to respond, type: 
                /usr/bin/write calif pts/1
        after hitting [ENTER], start typing.  To finish, hit [ENTER] to a new line
        followed by Ctrl-d
        calif@sunspot pts/1 [0]
After each time calif hits [ENTER], that line appears on troy's terminal.
Once calif enters "Ctrl-d", troy sees <EOT>:
        troy@sunspot pts/2 [0] /usr/bin/tty
        /dev/pts/2
        troy@sunspot pts/2 [0]
                Message from calif on sunspot (pts/1) [ Mon May 16 22:54:20 ] ...
        this is an example of using the write command to send a message to a user

        to respond, type:
                /usr/bin/write calif pts/1
        after hitting [ENTER], start typing.  To finish, hit [ENTER] to a new line
        followed by Ctrl-d
        <EOT>
Hitting [ENTER] will return troy's shell prompt (or Ctrl-l if you are in
vi).  To respond back to calif, troy decides use 'echo' piped to 'write':
        troy@sunspot pts/2 [0] echo "\nok, thanks for the message\n" | /usr/bin/write calif pts/1
        troy@sunspot pts/2 [0]
And calif will see the following:
        calif@sunspot pts/1 [0]
                Message from troy on sunspot (pts/2) [ Mon May 16 22:56:36 ] ...

        ok, thanks for the message

        <EOT>
Great, users can send messages to each other, however, what if a user
doesn't want to receive these messages?  The 'mesg' command can control
write access to one's terminal.  Without options, it will display the
current write status of the terminal.  Below, after seeing that 'write'
access is allowed (is y), troy disables it via 'mesg n' and confirms
the new status (is n):
        troy@sunspot pts/2 [0] /usr/bin/mesg
        is y
        troy@sunspot pts/2 [0] /usr/bin/mesg n
        troy@sunspot pts/2 [1] /usr/bin/mesg
        is n
With messages to troy's terminal disabled, calif attempts to send another
message to troy:
        calif@sunspot pts/1 [0] /usr/bin/write troy pts/2
        Permission denied.
        calif@sunspot pts/1 [1]
The above shows the error to calif under Solaris.  The following is the
error for both FreeBSD and Linux:
        calif@berkeley pts/1 [0] /usr/bin/write troy pts/2
        write: troy has messages disabled on pts/2
        calif@berkeley pts/1 [1]
Of note, root can still send messages to a user regardless of the user's
write status.  User's can also send messages to root, unless root has
disabled write access to his terminal.  Furthermore, in FreeBSD and
Linux, once a user disables write access to their terminal, the user
doesn't have the ability to send messages either:
        troy@cobblepot pts/2 [0] /usr/bin/mesg n
        troy@cobblepot pts/2 [0] /usr/bin/mesg
        is n
        troy@cobblepot pts/2 [0] /usr/bin/write calif pts/1
        write: you have write permission turned off.
        troy@cobblepot pts/2 [1] /usr/bin/mesg y
        troy@cobblepot pts/2 [0] /usr/bin/mesg
        is y
        troy@cobblepot pts/2 [0]
Solaris, however, will still let you send the message, though alerts
you that no reply is possible:
        troy@sunspot pts/2 [0] /usr/bin/write calif pts/1
        Warning: You have your terminal set to "mesg -n". No reply possible.