9.5 向用户终端发送消息

系统管理员可能需要向网络中所有主机上的所有用户或特定用户的终端发送消息。这则攻略将指导你如何完成这项任务。

9.5.1 新手上路

wall命令用来向所有当前登录用户的终端写入消息。它可以将消息传递给一台服务器中所有的当前登录用户或是多台分散主机中的用户。给所有的用户发送消息未必有用。不过我们可能需要给特定用户或终端发送消息。在Linux系统中,终端是作为设备存在的。因此那些打开的终端在 /dev/pts/ 中都会有对应的设备节点文件。向特定的设备写入数据将会在对应的终端中显示出消息。

9.5.2 实战演练

向终端中所有的当前登录用户发送广播消息:

  1. $ cat message | wall

或者

  1. $ wall < message
  2. Broadcast Message from slynux@slynux-laptop
  3. (/dev/pts/1) at 12:54 ...
  4.  
  5. This is a message

消息概要(message outline)会显示谁(哪个用户、哪台主机)发送了这则消息。如果其他用户发送了消息,只有在“写入消息”选项启用的情况下该消息才会显示在当前终端中。在绝大多数发行版中,“写入消息”选项都是默认启用的。如果消息的发送者是超级用户,那么不管“写入消息”选项是否启用,消息都会显示出来。

要允许写入消息,可以使用:

  1. $ mesg y

要禁止写入消息,可以使用:

  1. $ mesg n

让我们写一个给指定用户终端发送消息的脚本:

  1. #/bin/bash
  2. #文件名: message_user.sh
  3. #用途: 用于向指定用户记录的终端发送信息的脚本
  4. USER=$1
  5. devices=`ls /dev/pts/* -l | awk '{ print $3,$9 }' | grep $USER | awk
  6. '{ print $2 }'`
  7. for dev in $devices;
  8. do
  9. cat /dev/stdin > $dev
  10. done

运行脚本:

  1. ./message_user.sh USERNAME < message.txt
  2. # 通过stdin传递消息,USERNAME作为参数

输出如下:

  1. $ cat message.txt
  2. A message to slynux. Happy Hacking!
  3. # ./message_user.sh slynux < message.txt
  4. # 因为消息要发送给指定的用户,因此要以超级用户身份运行message_user.sh

这时slynux的终端将接收到消息。

9.5.3 工作原理

目录 /dev/pts中包含着对应于终端中每位当前登录用户的字符设备。我们可以通过查看设备文件的属主来得知谁登入了哪个终端。ls-l的输出包含了属主名以及设备路径。这些信息可以用awk提取。然后用grep单独提取对应于指定用户的行。用户名作为脚本的首个参数被存储在变量USER中,然后生成给定用户的终端列表。for循环用来迭代每一个设备路径。/dev/stdin包含传递给当前进程的标准输入数据。通过读取 /dev/stdin,就可以获取数据并将其重定向到对应的终端设备(TTY)。因此消息就得以显示。