wall 命令详解与参数实测(Ubuntu 22.04)
wall 命令逐参数实测详解:无参数全员广播与 Broadcast 横幅逐段解读、文件多行公告、-n 无横幅广播(root 专属)、-g 按接收用户组过滤(实测证明与终端设备属组无关)、-t 写超时、普通用户对 mesg n 终端静默跳过、中文八进制转义与折行,全部回显在 Ubuntu 22.04 实测通过。
wall 命令详解与参数实测(Ubuntu 22.04)
目标:全面掌握 wall 的每一个参数——无参数全员广播与 Broadcast 横幅逐段解读、
< 文件多行公告、-n无横幅广播(root 专属,普通用户报错但消息照发)、-g按组过滤广播(实测证明过滤依据是接收用户的组归属而非终端设备属组)、-t写超时、普通用户对 mesg n 终端的静默跳过行为、中文消息的八进制转义与折行形态,全部命令与回显已在 Ubuntu 22.04 实测通过。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- wall 实现:
/usr/bin/wall(util-linux 的 wall,非软链接,来源确认见 2.3) - wall 版本:util-linux 2.37.2(
wall -V实测;包 bsdutils 1:2.37.2-4ubuntu3.6) - 演示用户:
root(同时「登录」三个终端)与普通用户tester(主组 tty,原因见 3.6 与 write 篇 3.5 的 egid 校验说明) - 演示终端:pts/1、pts/2(mesg 默认允许)与 pts/3(已执行
mesg n),均为script会话模拟的第二终端;会话通过 util-linux 的 utmpdump 登记进 utmp,finger -s可见:
$ finger -s
Login Name Tty Idle Login Time Office Office Phone
root root pts/1 Oct 16 01:09 (10.20.30.40)
root root pts/2 Oct 16 01:09 (10.20.30.40)
root root *pts/3 Oct 16 01:09 (10.20.30.40)
pts/3 行 Tty 列的 * 前缀表示该终端已 mesg n(关闭消息接收)。三个终端的设备权限:
$ ls -l /dev/pts/
total 0
crw--w---- 1 root tty 136, 0 Oct 16 01:09 0
crw--w---- 1 root tty 136, 1 Oct 16 01:09 1
crw--w---- 1 root tty 136, 2 Oct 16 01:09 2
crw------- 1 root tty 136, 3 Oct 16 01:09 3
crw-rw-rw- 1 root root 5, 2 Oct 16 01:09 ptmx
pts/1、pts/2 为 crw--w----(组 tty 可写),pts/3 为 crw-------(仅属主可写)——mesg 开关的全部秘密就在这两个权限位上。接收终端的「屏幕内容」由各 script 会话记录到 /tmp/wl1.log、/tmp/wl2.log、/tmp/wlm.log,下文以 cat/tail 展示。
二、命令概览
2.1 语法与参数总览
wall(write all)把一条消息同时写进所有已登录用户的终端设备,是全员公告的经典工具(shutdown 停机前就是这么通知在线用户的)。它的消息来源非常灵活:位置参数、文件、标准输入三者皆可;全部业务参数只有三个:
| 参数 | 作用 | 本篇实测节 |
|---|---|---|
[<file> | <message>] | 消息来源:文件路径或直接消息文本;全省略时读标准输入 | 3.1 / 3.2 |
-g, --group <group> | 只发给属于指定组的用户(按组名或 GID) | 3.4 |
-n, --nobanner | 不打印 Broadcast 横幅(仅 root 可用) | 3.3 |
-t, --timeout <timeout> | 写终端的超时秒数(防止被某个卡死的终端拖住) | 3.5 |
-h, --help | 帮助 | 2.2 |
-V, --version | 版本 | 2.3 |
完整语法(wall --help 实测):
Usage:
wall [options] [<file> | <message>]
Write a message to all users.
Options:
-g, --group <group> only send message to group
-n, --nobanner do not print banner, works only for root
-t, --timeout <timeout> write timeout in seconds
-h, --help display this help
-V, --version display version
For more details see wall(1).
💡 技术拓展:wall 与 write、mesg 构成经典的「终端消息三件套」——
命令 角色 一句话分工 write 点对点 给某个用户的某个终端发私信 wall 广播 给所有登录终端发同一条公告(shutdown 等维护场景) mesg 开关 控制自己的终端「接不接收」他人消息(改设备权限位) 权限差异(本篇 3.1/3.6 实测):root 广播无视 mesg n;普通用户广播遇到 mesg n 终端则静默跳过(不报错)。选定建议:单人沟通用 write,全员公告用 wall,不想被打扰就 mesg n。
2.2 帮助形态:--help 的实测回显
$ wall --help; echo rc=$?
Usage:
wall [options] [<file> | <message>]
Write a message to all users.
Options:
-g, --group <group> only send message to group
-n, --nobanner do not print banner, works only for root
-t, --timeout <timeout> write timeout in seconds
-h, --help display this help
-V, --version display version
For more details see wall(1).
rc=0
注意三个业务参数的提示措辞:-n 的 works only for root 直接写明 root 专属(3.3 有非 root 的实测对照);-t 是「写终端超时」而不是总超时;-g 支持组名或 GID。
2.3 版本信息
$ which wall; readlink -f $(which wall)
/usr/bin/wall
/usr/bin/wall
$ dpkg -S $(readlink -f $(which wall))
bsdutils: /usr/bin/wall
$ wall -V; echo rc=$?
wall from util-linux 2.37.2
rc=0
$ dpkg -l bsdutils | tail -1
ii bsdutils 1:2.37.2-4ubuntu3.6 amd64 basic utilities from 4.4BSD-Lite
/usr/bin/wall 不是软链接,由 bsdutils 包提供,版本 2.37.2(1:2.37.2-4ubuntu3.6)。Ubuntu 22.04 默认自带该命令,无需安装。
三、参数逐项实测
3.1 无参数:全员广播与 Broadcast 横幅逐段解读
最简用法:把一行文本通过管道交给 wall,它读入标准输入并广播到所有登录终端:
$ echo "system reboot in 10 minutes" | wall; echo rc=$?
rc=0
wall 自身不产生任何输出(静默成功)。三个终端的屏幕记录(含 mesg n 的 pts/3):
$ cat /tmp/wl1.log
Script started on 2026-10-16 01:09:24+00:00 [<not executed on terminal>]
Broadcast message from root@f1034b9326b2 (pts/0) (Fri Oct 16 01:09:25 2026):
system reboot in 10 minutes
$ cat /tmp/wl2.log
Script started on 2026-10-16 01:09:24+00:00 [<not executed on terminal>]
Broadcast message from root@f1034b9326b2 (pts/0) (Fri Oct 16 01:09:25 2026):
system reboot in 10 minutes
$ cat /tmp/wlm.log
Script started on 2026-10-16 01:09:25+00:00 [<not executed on terminal>]
Broadcast message from root@f1034b9326b2 (pts/0) (Fri Oct 16 01:09:25 2026):
system reboot in 10 minutes
pts/3 虽已 mesg n(设备 crw-------),root 的广播照样写入——wall 以 root 身份打开终端设备,权限位拦不住(对比:普通用户广播会被拒,见 3.6)。
接收方屏幕上的横幅逐段解读:
Broadcast message from root@f1034b9326b2 (pts/0) (Fri Oct 16 01:09:25 2026):
Broadcast message from——广播标识,与 write 的Message from区分。root@f1034b9326b2——谁(root)从哪台主机(f1034b9326b2)发出的。(pts/0)——发送者自己的终端(本次实测的主终端)。(Fri Oct 16 01:09:25 2026)——广播发出的完整时间。- 随后一个空行、消息正文、再一个空行——与对方屏幕原有内容隔开。
💡 要点:与 write 不同,wall 的横幅时间带完整日期且不带
...结尾;接收方也不会看到 write 那样的EOF行——广播没有「会话结束」概念,一条消息发完即止。
3.2 wall < 文件:多行公告广播
把公告写成文件再重定向,多行内容原样广播(免交互、可脚本化):
$ printf 'Scheduled maintenance tonight:\n 1. DB failover at 23:00\n 2. API gateway restart at 23:30\nDowntime is expected to be short.\n' > /root/demo/wall/notice.txt
$ wall < /root/demo/wall/notice.txt; echo rc=$?
rc=0
$ tail -9 /tmp/wl1.log
Broadcast message from root@f1034b9326b2 (pts/0) (Fri Oct 16 01:09:26 2026):
Scheduled maintenance tonight:
1. DB failover at 23:00
2. API gateway restart at 23:30
Downtime is expected to be short.
四行公告在一条横幅下完整送达,缩进与行序保持原样。位置参数同样支持文件路径(wall /root/demo/wall/notice.txt),本篇以重定向形态实测为准。
💡 要点:文件重定向是 wall 的生产形态——「写公告文件 →
wall < 公告→ 复盘留档」三步走,公告内容可审计可重放;配合 cron 还能做定时预告(如每日 22:00 广播备份窗口提醒)。交互式wall 回车敲正文适合临时一句话,忘记 Ctrl-D 会一直挂着,脚本场景一律用文件。
3.3 -n / --nobanner:无横幅广播(root 专属)
-n 去掉 Broadcast 横幅,接收方只看到消息正文(适合脚本输出的纯内容场景):
$ printf 'Disk cleanup running; some paths may be slow.\n' > /root/demo/wall/plain.txt
$ wall -n < /root/demo/wall/plain.txt; echo rc=$?
rc=0
$ tail -4 /tmp/wl1.log
Disk cleanup running; some paths may be slow.
接收记录里没有横幅,直接是正文。普通用户使用 -n 则被明确拒绝:
$ su tester -c "script -qfec \"bash /tmp/wx-tn.sh\" /tmp/wx-tn.log >/dev/null 2>&1"
$ cat /tmp/wx-tn.log
Script started on 2026-10-16 01:11:08+00:00 [TTY="/dev/pts/0" COLUMNS="-1" LINES="-1"]
^@wall: --nobanner is available only for root
Script done on 2026-10-16 01:11:08+00:00 [COMMAND_EXIT_CODE="0"]
wall: --nobanner is available only for root——普通用户报错。但注意:报错后广播并未中止,随后接收终端照样收到 tester 的带横幅广播(横幅 Broadcast message from tester@f1034b9326b2 (pts/4) ...,正文即消息内容)。也就是 -n 被拒只影响「去横幅」这一项,广播本身照常执行。
💡 要点:
-n的 root 限制是有意设计——没有横幅的消息看起来像系统级通知,若任何用户都能匿名广播,容易被用来伪造「管理员公告」。
3.4 -g / --group:按组过滤广播(过滤依据实测)
-g 把广播范围限定到指定组。第一组实验:三个终端都属于 root(utmp 里登记的用户是 root),先广播给 tty 组,再广播给 root 组:
$ printf 'group msg to tty\n' > /tmp/wx-msg.txt
$ wall -g tty < /tmp/wx-msg.txt; echo rc=$?
rc=0
$ tail -3 /tmp/wx1.log
$ tail -3 /tmp/wxm.log
$ printf 'group msg to root-only\n' > /tmp/wx-msg2.txt
$ wall -g root < /tmp/wx-msg2.txt; echo rc=$?
rc=0
$ tail -3 /tmp/wx1.log
group msg to root-only
$ tail -3 /tmp/wxm.log
group msg to root-only
-g tty 零送达(两个终端都无新内容),-g root 正常送达。三个终端设备的属组都是 tty(crw--w---- root tty),如果 -g 按设备属组过滤,-g tty 应该全员送达——实测相反。补一组对照实验一锤定音:在 utmp 里登记一个 tester 会话(tester 主组 tty),再广播 -g tty:
$ finger -s
Login Name Tty Idle Login Time Office Office Phone
root root pts/1 Oct 16 01:12 (10.20.30.40)
tester pts/2 Oct 16 01:12 (10.20.30.40)
$ wall -g tty < /tmp/wg-msg.txt; echo rc=$?
rc=0
$ tail -5 /tmp/wg1.log
$ tail -5 /tmp/wg2.log
Broadcast message from root@f1034b9326b2 (pts/0) (Fri Oct 16 01:12:36 2026):
msg to group tty
$ wall -g root < /tmp/wg-msg.txt; echo rc=$?
rc=0
$ tail -5 /tmp/wg1.log
Broadcast message from root@f1034b9326b2 (pts/0) (Fri Oct 16 01:12:37 2026):
msg to group tty
同一次 -g tty 广播:pts/1(utmp 登记为 root)没收到,pts/2(utmp 登记为 tester)收到了。结论明确——-g 按接收用户(utmp 会话记录的用户名)的组归属过滤(该用户的主组或 /etc/group 成员列表命中即送达),与终端设备的属组无关。本例 root 不属 tty 组、tester 主组就是 tty,所以 -g tty 只达 tester 会话。
组名不存在的报错形态:
$ wall -g nosuchgrp < /tmp/wx-msg.txt; echo rc=$?
wall: invalid group argument: 'nosuchgrp'
rc=1
💡 要点:
-g过滤的是「收信人属于哪个组」而不是「终端设备属于哪个组」。想通知某组同事,前提是他们的登录账号真的属于那个组;过滤后零送达时 wall 静默返回(rc=0,无提示),排查时要先核对组员名单。
3.5 -t / --timeout:写终端的超时秒数
-t 给「向每个终端写入」这个动作设超时(防止某个卡死的终端拖住整个广播)。正常路径实测:
$ wall -t 2 < /tmp/wx-msg.txt; echo rc=$?
rc=0
$ tail -3 /tmp/wx2.log
group msg to tty
广播正常送达,行为与不带 -t 一致。无效值直接报错:
$ wall -t abc < /tmp/wx-msg.txt; echo rc=$?
wall: invalid timeout argument: 'abc'
rc=1
wall: invalid timeout argument: 'abc'——非数字秒数被拒绝,退出码 1。
💡 要点:
-t解决的是「广播发到无人值守的僵死终端时 wall 自身被拖住」的问题——写终端操作可能阻塞,给个 5~30 秒上限即可保证广播脚本按时返回。巡检/发布脚本里调用 wall 建议固定带-t 15。
3.6 普通用户广播:mesg n 终端被静默跳过
换 tester 广播:mesg 允许的终端照常收到,mesg n 的 pts/3 则静默跳过——无警告、无报错、退出码 0:
$ su tester -c "script -qfec \"bash /tmp/wx-t2.sh\" /tmp/wx-t2.log >/dev/null 2>&1"
$ cat /tmp/wx-t2.log
Script started on 2026-10-16 01:11:09+00:00 [TTY="/dev/pts/0" COLUMNS="-1" LINES="-1"]
Script done on 2026-10-16 01:11:09+00:00 [COMMAND_EXIT_CODE="0"]
发送侧干净收场(对照 write 的显式报错 write: root has messages disabled on pts/3——write 会拒绝整个投递,wall 只是跳过该终端继续广播其余终端)。接收侧全量对照:
$ cat /tmp/wlm.log
Script started on 2026-10-16 01:11:04+00:00 [<not executed on terminal>]
Broadcast message from root@f1034b9326b2 (pts/0) (Fri Oct 16 01:11:06 2026):
group msg to root-only
Broadcast message from root@f1034b9326b2 (pts/0) (Fri Oct 16 01:11:07 2026):
group msg to tty
pts/3 的完整屏幕记录里只有 root 发的两次广播(3.1/3.4 已证 root 无视 mesg n),tester 的广播从未出现——静默跳过坐实。而 mesg 允许的终端正常收到 tester 的广播(横幅见 3.3 的接收记录:Broadcast message from tester@f1034b9326b2 (pts/4) (Fri Oct 16 01:11:08 2026):)。
💡 要点:wall 对 mesg n 的「静默跳过」与 write 的「显式报错」是刻意的行为差异——广播面向群体,逐个报错毫无意义,只需保证发得出去;点对点的 write 则要让发送方明确知道被拒。这也意味着普通用户的广播无法保证触达所有人,全员必达的公告只有 root 能保证。
3.7 中文消息:八进制转义与折行
wall(util-linux 2.37)对消息中的非 ASCII 字节做可见化转义,且长行按行宽折行。发一条中文:
$ printf "例行维护公告:今晚 23:00 重启数据库\n" | wall; echo rc=$?
rc=0
$ tail -4 /tmp/wl1.log
\344\276\213\350\241\214\347\273\264\346\212\244\345\205\254\345\221\212\357\274
\232\344\273\212\346\231\232 23:00 \351\207\215\345\220\257\346\225\260\346\215
\256\345\272\223
原文 例行维护公告:今晚 23:00 重启数据库 的 UTF-8 字节全部转成 \344\276\213... 形式的八进制序列(ASCII 部分 23:00 原样保留),并被折成三行——每行行尾还填充了空格(上面回显中行尾空白即该填充,宽度对齐终端列宽)。与 write 的对比:write 是单行完整转义不折行(见本专栏 write 篇 3.7),wall 则按行宽折行加填充。两者共同点是:中文内容经三件套传递都会变成八进制转义,不适合中文公告——需要中文请用邮件或改写英文。
💡 要点:wall 的折行按「终端列宽」计算且行尾填空格对齐,多行公告在窄终端上会进一步二次折行——公告正文每行控制在 60 字符内可保证各终端显示不跑版。中文公告的替代方案:把公告写到 /etc/motd(登录即见)或用邮件/IM 渠道。
3.8 技术拓展:系统级广播与通知渠道对比
「让全机用户都知道一件事」的渠道横向对比——
| 渠道 | 触达对象 | 即时性 | 持久性 |
|---|---|---|---|
| wall | 当前在线终端 | 即时(写终端) | 无(刷屏即逝,本文主线) |
| write | 单个在线终端 | 即时 | 无 |
| /etc/motd | 下次起每次登录 | 非即时 | 持久(登录横幅) |
| 任意用户(含离线) | 非即时 | 持久(邮箱留档) | |
| logger → syslog | 运维人员(看日志) | 非即时 | 持久(进日志系统) |
💡 关键差异一句话:wall 是唯一的「全员即时触达」手段,但零持久性。成熟的运维公告组合是「wall 打即时 + mail/motd 留痕」——先 wall 广播当前在线者,再 mail 一份存档给全员(含离线者),重要变更两步缺一不可。
四、实战示例
4.1 维护前全员公告
一行流:直接把公告文本作为参数交给 wall。
$ wall "system reboot in 10 minutes"
(本篇实测以管道/重定向形态为准,回显见 3.1;参数形态与 echo ... | wall 等价。)
4.2 脚本里的多行静默公告
维护脚本里把公告写成文件,以 -n 无横幅广播(脚本输出场景,接收方屏幕不被横幅打断):
$ printf 'Disk cleanup running; some paths may be slow.\n' > /root/demo/wall/plain.txt
$ wall -n < /root/demo/wall/plain.txt; echo rc=$?
rc=0
接收方只见正文(3.3 实测)。root 身份执行即可;普通用户会被 -n 拒绝(报错后消息仍带横幅发出,见 3.3)。
4.3 只通知某个组
按组过滤的运维场景:只通知属于 ops 组的账号(组员名单先核对,-g 按接收用户组过滤,3.4)。
$ echo "ops rotation starts at 18:00" | wall -g ops
过滤后若无任何匹配用户,wall 静默成功(rc=0)——发完记得回访确认触达。
4.4 排查「有人没收到广播」
按三种可能逐一核对:① 对方终端 mesg n 且自己非 root——wall 静默跳过该终端(3.6),可先用 finger -s 看 Tty 列 * 前缀识别;② 用了 -g 但对方账号不在该组(组名拼错则直接 rc=1 报错,3.4)——核对 id 用户名 的组列表;③ 对方根本没登录——wall 只投递 utmp 里的在线会话,离线用户需邮件等离线渠道。root 身份广播可绕过 ①。
五、注意事项与常见问题
Q1:wall 和 write 怎么选?
单人单终端沟通用 write(可指定 user tty 定点投递);面向全员或多人的同一通知用 wall(一条消息投递所有终端)。两者都是直接写终端设备的「插屏」式投递,不保证对方已读;正式通知请补邮件。三件套分工见 2.1 拓展表。
Q2:为什么 mesg n 的用户收到了我(root)的广播,普通同事发的却收不到?
wall 以发送者权限打开终端设备:root 有设备写权限,mesg n 拦不住(3.1/3.6 实测);普通用户打开失败时 wall 静默跳过该终端继续广播其余终端,不报错。这正是「有人没收到」的最常见原因,让对方 mesg y 或改用 root/系统身份广播。
Q3:-n 为什么限制 root?普通用户用了会怎样?
无横幅消息易被当成系统级通知,故 util-linux 限定 root。普通用户实测报错 wall: --nobanner is available only for root,但注意广播本身仍会执行(带横幅送达,3.3)——不是「整个命令失效」。
Q4:-g 到底按什么过滤?
按接收用户的组归属(主组或 /etc/group 成员列表),不是终端设备的属组——三个实验互证:全 root 会话时 -g tty 零送达、-g root 送达;utmp 登记 tester 会话后同一次 -g tty 广播只达 tester 终端(3.4)。另注意 -g 匹配不到任何用户时静默成功,容易误以为已送达。
Q5:广播内容会变 \344\276\213 这样的编码,还会折行?
wall 对非 ASCII 字节做八进制转义(防终端解析混乱),长行按行宽折行并在行尾补空格对齐(3.7 实测)。中文公告会变成不可读的转义序列,建议中文通知走邮件;同一问题的 write 侧形态见 write 篇 3.7。
Q6:shutdown 停机前的公告就是 wall 吗?
是同类场景的鼻祖用例:shutdown/init 等系统程序在停机前向所有登录终端写入停机预告,接收方看到的就是一条广播。日常维护公告用 wall 手工发布即可;系统停机消息由 shutdown 自行广播,无需(也不应)手工模拟。
六、参考链接
- Ubuntu 手册页(wall 1,util-linux 实现):https://manpages.ubuntu.com/manpages/jammy/en/man1/wall.1.html
- write 手册页(点对点私信):https://manpages.ubuntu.com/manpages/jammy/en/man1/write.1.html
- mesg 手册页(终端消息开关):https://manpages.ubuntu.com/manpages/jammy/en/man1/mesg.1.html
- utmp 数据库格式(wall 枚举登录会话的数据来源):https://man7.org/linux/man-pages/man5/utmp.5.html
- util-linux 上游发行说明:https://github.com/util-linux/util-linux