news 2026/10/5 2:46:45

Linux查看登录用户:who、w、last、lastlog区别与实战排查

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux查看登录用户:who、w、last、lastlog区别与实战排查

刚接手一台服务器,第一件事我会敲w;有人跟我说"系统有点卡",我第一反应也是w;排查异常登录、清理僵尸会话、写巡检脚本,翻来覆去用的还是那几个命令。但有意思的是,很多做了两三年的运维,被问到"Linux如何查看当前登录用户",能脱口而出who,再问w和who的区别、last和lastlog的差异,就开始含糊了。

这个标题看起来简单,实际是一个非常典型的"一题多解"场景:同一个需求,命令不同、输出不同、适用时机也不同。今天我就把这块掰开揉碎讲清楚,从最基础的who到历史登录审计,再到配合排查实际故障的完整思路,顺便把面试里喜欢追问的细节也一并交代了。

1. 先分清:who、w、users、whoami,到底谁在干"查看登录用户"的活

很多人记命令是死记硬背,who看登录、w看登录、last看登录,但从来不想这些命令背后的设计差异。实际上它们是四个不同的工具,定位完全不同。

1.1 who:最朴素的"现在谁在系统里"

who是最直接的命令,不加任何参数,输出长这样:

$ who root pts/0 2025-01-12 09:23 (192.168.1.10) zhangsan pts/1 2025-01-12 10:02 (192.168.1.23) lisi pts/2 2025-01-12 10:45 (192.168.1.34)

四列信息分别是:用户名、终端类型、登录时间、来源地址。

这里有个细节值得注意:第三列后面的括号里如果是IP,说明是远程SSH登录;如果是:0或者tty1这类,说明是本机物理终端登录。做机房巡检或者排查内网攻击源的时候,这一列就是最重要的线索。

who命令还有很多参数,我常用的一个是who -u,会多显示一个"空闲时间"和"进程ID"。空闲时间这一列在排查"谁挂在服务器上不动"的时候很实用,后面讲实战排查我会细说。

1.2 w:登录名单之外,它连"正在执行什么命令"都给你列出来

你可能要问了,who已经能看登录用户了,为什么还要w?

这就是典型的"够用"和"好用"的区别。w的输出比who丰富得多:

$ w 10:56:32 up 2:14, 3 users, load average: 0.08, 0.03, 0.05 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 192.168.1.10 09:23 1:33 0.12s 0.02s vim /etc/nginx/nginx.conf zhangsan pts/1 192.168.1.23 10:02 4:25 0.05s 0.05s -bash lisi pts/2 192.168.1.34 10:45 0.00s 0.03s 0.02s top

第一行是系统整体状态:当前时间、系统运行时长、用户总数、负载均值。这一行在排查负载问题时可以直接当"开胃菜"。

然后是每个登录用户的详情:

  • IDLE:用户空闲了多久,长时间高数值说明这个会话基本挂死了
  • JCPU:该终端所有进程累计消耗的CPU时间
  • PCPU:当前前台进程消耗的CPU时间
  • WHAT:用户当前正在执行的命令

w和who的关系,我习惯这么理解:who是"点名册",w是"点名册加实时监控"。如果你只有时间记一个命令,记w,它覆盖了who的全部功能还多得多。

1.3 users:简洁到可以写进脚本

如果说who是点名册,那users就是"签到单"——它只输出用户名,一行搞定:

$ users root zhangsan lisi

它的价值主要体现在脚本里。比如我要写一个巡检脚本,判断"是否有除root之外的用户在线",直接解析users的输出比解析who简单得多:

#!/bin/bash # 检查是否有非root用户在线 online_users=$(users) if echo "$online_users" | grep -qv root; then echo "警告:存在非root用户在线:$online_users" fi

注意users输出中的用户名可能有重复,比如同一个用户开了两个终端。如果需要去重,可以用users | tr ' ' '\n' | sort -u。

1.4 whoami:它其实不回答"当前有哪些用户"

whoami严格来说不在"查看登录用户"的范畴里,但我发现新手经常把它和who搞混——who是看系统里有谁,whoami是看"我是谁"。

$ whoami root

这个命令的真实逻辑是读取当前进程的UID,然后映射用户名。它有个很隐蔽的坑:如果你先su - zhangsan切换了用户,再在同一个Shell里执行whoami,输出的是zhangsan而不是root。但如果你用sudo -u zhangsan执行,结果会受sudo配置影响。

所以在排障的时候,如果发现"执行命令的人"和"登录的人"对不上,多半是发生了用户切换。结合后面要讲的last命令,就能拼出完整的操作轨迹。

2. 查看登录用户的底层档案:utmp、wtmp、btmp 三个文件

光会敲命令不算真懂,你得知道这些命令的数据从哪来。Linux 把登录信息存在三个二进制文件里,绝大多数"查登录"的命令都是在读它们:

文件路径记录内容谁来写
utmp/var/run/utmp当前在线会话who、w、users读取它
wtmp/var/log/wtmp历史登录/登出记录last读取它
btmp/var/log/btmp失败登录记录lastb读取它

utmp里的记录是动态的:用户登录时写入、登出时删除,所以它永远只反映"此刻谁在线"。

wtmp是追加写入,只增不减,记录每一次完整的登录和登出会话。这也是为什么重启服务器后,last依然能看到过去的记录——它读的是磁盘里的wtmp,不是内存。

btmp是个容易被忽略的存在,但它恰恰是排查暴力破解的第一手资料。每次SSH密码输错,Linux都会往btmp里写一条失败记录,用lastb可以查看:

$ sudo lastb root ssh:notty 118.31.xx.xx Tue Jan 14 03:22 - 03:22 (00:00) admin ssh:notty 118.31.xx.xx Tue Jan 14 03:22 - 03:22 (00:00)

你不难发现,lastb输出的头几行经常是乱糟糟的一堆陌生IP,后面跟的全是常见用户名,这是典型的自动化爆破特征。所以我的习惯是:每天瞄一眼lastb | head -20,比看什么安全设备告警都来得直接。

还有个文件容易被遗忘:/var/run/utmp在系统重启后会被清空重建,这也是为什么who只能看到本次开机以来的在线用户——重启前的登录会话全部"断线"了,自然就不算"当前登录"。

3. 翻开历史账本:last 和 lastlog 的正确用法

在线用户只是一瞬间的状态,排查问题的时候你往往更关心"谁在什么时候登录过"、"这个账号有没有被使用过"。

3.1 last:完整的登录/登出流水账

last读的是wtmp,输出每次会话的记录:

$ last root pts/0 192.168.1.10 Mon Jan 13 09:23 still logged in zhangsan pts/1 192.168.1.23 Mon Jan 13 10:02 still logged in lisi pts/2 192.168.1.34 Mon Jan 13 10:45 still logged in root pts/0 192.168.1.10 Mon Jan 12 09:23 - 18:30 (09:07) reboot system boot 2.6.32-642.el6 Mon Jan 12 08:00 still running

注意几类特殊输出:

  • still logged in:这次会话还没登出,就是当前在线
  • reboot system boot:系统启动记录,wtmp里会写,所以last能看出系统何时重启过
  • - 18:30表示登出时间,括号里是该会话的总时长

last支持按用户名过滤,比如只看 root 的登录历史:

$ last root

也可以看某个终端的历史:

$ last pts/0

这个命令在审计场景特别有用。举个例子,有次同事说某个配置文件被改了,但都否认是自己改的,我用last拉出最近两天所有登录过这台机器的人,再配合history时间戳一对比,几分钟就定位到了。

3.2 lastlog:每个账号的"最后一次登录"登记表

lastlog读的是/var/log/lastlog,它会列出系统里所有有登录记录的账号(其实是所有UID达到阈值的用户),输出每个账号最后一次登录的时间和来源:

$ lastlog Username Port From Latest root pts/0 192.168.1.10 Mon Jan 13 09:23:28 +0800 2025 daemon **Never logged in** bin **Never logged in** zhangsan pts/1 192.168.1.23 Mon Jan 13 10:02:11 +0800 2025

注意last和lastlog的区别:

  • last看"每一次会话",是流水账
  • lastlog看"每个账号的最后一次",是一张汇总表

lastlog最大的价值在于发现"异常存活的账号"。比如一个系统里有一百个账号,看着都正常,但跑一遍lastlog,发现其中二十个显示**Never logged in**,而这些账号偏偏能SSH登录,这就要警惕了——正常没人用的账号通常会被锁掉。

3.3 登录记录文件会无限增长吗?会,所以要学会管理

wtmp和btmp是追加写入的二进制文件,日子久了体积会膨胀。尤其btmp,如果服务器常年被暴力扫描,可能几个月就长到几个GB。我在生产环境见过 8GB 的btmp,lastb一执行直接卡住。

常规做法是用 logrotate 管理这两个文件。系统一般自带配置,在/etc/logrotate.d/下会有对应规则,但要确认一下实际生效情况。我自己维护的服务器会单独加上按周轮转、保留4周的策略:

/var/log/btmp { weekly rotate 4 compress missingok }

还有个小技巧:日志轮转之后lastb默认只读当前的btmp,要看上一周的得用lastb -f /var/log/btmp.1.gz配合zcat来处理,这个到用的时候再查就行。

4. 实战排查:从"有用户在线"到"定位异常会话"的完整链路

命令都认识了,接下来聊聊真正的工作场景。这里我挑三个最常见的诉求展开:判断卡顿是否与登录用户有关、找出长时间不动的僵尸会话、识别可疑的登录来源。

4.1 系统变卡:先用 w 看负载和现场命令

服务器突然变卡,登录上去第一步我会敲:

$ w 11:30:15 up 30 days, 5:02, 5 users, load average: 15.08, 12.03, 9.05 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 192.168.1.10 09:23 0.00s 0.12s 0.02s w zhangsan pts/1 192.168.1.23 10:02 1:02 12.5s 11.3s python3 /tmp/check.py lisi pts/2 192.168.1.34 10:45 0.05s 0.03s 0.02s top

重点看两个地方:load average和WHAT列。如果负载很高,而某个用户的WHAT列显示一个你不知道的进程持续在跑,十有八九问题就在这个会话上。

上面这个例子,zhangsan在跑/tmp/check.py,CPU时间累计了 12.5 秒,继续跟踪就应该顺着流程去看这个进程到底在干什么:

$ ps -ef | grep check.py $ ls -l /proc/<pid>/cwd

/proc/<pid>/cwd可以显示进程的工作目录,写脚本的服务器上这个技巧几乎每天都要用。

4.2 空会话和僵尸终端:IDLE 高到离谱的会话怎么清理

w输出里的IDLE列,超过几个小时甚至几天的会话,基本可以断定是无用的遗留会话。比如某天你看到:

$ w USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT olduser pts/5 10.0.0.55 2025-01-05 14:20 22:15m 0.02s 0.01s -bash

22:15m表示空闲了22小时15分钟,这种会话占着终端资源,虽然不会直接拖垮系统,但如果批量存在,也会占用大量pts设备号,导致新连接分配不到终端。

处理僵尸会话的步骤我一般这么走:

  1. 先确认该用户的会话数:who -u,看第二列终端号
  2. 确认没有关键任务在跑:ps -ef | grep pts/5,排除掉还在跑的进程
  3. 杀掉会话对应的进程,或者直接踢掉:pkill -9 -t pts/5

这个操作不是随手就能做的。生产服务器上,一个挂着vim没保存的会话被强杀,数据就丢了。所以我给自己定了个规矩:踢会话之前,至少ps -t pts/5看一眼有没有正在编辑的进程。

4.3 可疑来源IP:一眼识别非内网登录

运维的服务器一般只开放了内网SSH,如果w或者who里出现陌生的公网IP,这就要立刻警觉了。

比如:

$ who root pts/0 192.168.1.10 2025-01-13 09:23 admin pts/3 185.220.101.4 2025-01-13 11:05

内网网段是192.168.1.x,突然冒出一个185.x.x.x的登录,来源地明显不对,就要走异常排查流程:

  1. 先看历史记录,确认这个IP是不是第一次出现:last | grep 185.220.101.4
  2. 看失败记录里有没有大量尝试:lastb | grep 185.220.101.4 | wc -l
  3. 看这个会话的WHAT列在做什么命令,立刻决定是否踢出:pkill -9 -t pts/3

再补充一个细节:如果你发现last里某个用户的登录记录全来自陌生IP,而他自己说没登录过,那就要考虑账号密码泄露了,第一时间passwd 用户名重置密码,同时把所有在线会话踢掉,然后去~/.ssh/authorized_keys里检查有没有多出来的公钥。别问我是怎么知道要查这玩意的,都是教训换来的。

4.4 盯着登录动态:watch + 命令组合拳

排查不是一次性动作,很多时候你需要持续观察。我最常用的组合是:

$ watch -n 1 'who; echo "---"; w'

watch -n 1表示每秒钟刷新一次,随时能看到有没有新会话进来、已有会话在跑什么命令。这在多人共用一台测试机、排查"谁又在乱执行命令"的场景里特别好使。

想要记成日志的话,可以加个时间戳追加到文件:

$ while true; do date >> /tmp/login_monitor.log; w >> /tmp/login_monitor.log; sleep 60; done

这种粗糙的方案在应急场景比装监控系统快得多,胜在五分钟内就能跑起来。

5. 面试被追问的隐藏维度:终端类型、切换用户与 "仍然登录中"

这个标题在面试题里出现的频率挺高的,但面试官一般不会只满足于"背命令"。基于我前面讲的内容,有几个经常被追问的细节值得单独拎出来说。

5.1 TTY 和 PTS 到底代表什么

who输出的第二列,pts/0、pts/1、tty1这些,面试时经常被拿来作文章。

  • tty1~tty6:本机物理终端(按下 Ctrl+Alt+F1~F6 切换的那种)
  • pts/N:远程终端或伪终端,SSH登录、xshell、securecrt 连接都属于这类

更底层的说法是,pts是 "pseudo-terminal slave" 的缩写,它由sshd等程序动态分配,所以你SSH登录一次,pts的编号通常会加1。同一个用户多次SSH,会占用多个不同的pts/N,在who里就会有这个用户的多个登录记录。

5.2 reboot 记录为什么也会出现在 last 里

这是一个很能拉开差距的细节。last会输出系统启动记录,是因为wtmp在系统启动时会被写入一条reboot记录。这条记录的 TTY 列显示system boot,FROM 列显示内核版本。

所以当你用last排查问题时可以顺便确认系统何时重启过,比如:

$ last reboot reboot system boot 5.4.0-26-generic Mon Jan 13 08:00 still running

要是想单独看所有重启记录,last reboot是最快的命令,没有之一。

5.3 su 和 sudo 切换后的"表面身份"与"真实身份"

表面上who看到的是登录用户名,但如果你在会话里执行了su或者sudo,后续命令的真实执行身份已经变了。这时候有几个命令可以确认"我到底是以什么身份在干活":

$ id -u # 显示当前有效用户的UID $ whoami # 显示当前有效用户名 $ logname # 显示最初登录的用户名(如果依次su了多次,这个依然是最早那个)

logname是个冷门命令,但它有个独特价值:whoami会随su切换而变化,logname不会。所以在面试里可以这样答:"whoami回答的是当前有效身份,logname回答的是初始登录身份,两个命令在排查提权和身份切换场景时需要配合使用。"

5.4 last 状态全解析:from 里的 IP 和 "still logged in" 的判断逻辑

last的输出有个很容易读错的点:如果会话正常退出,你会看到- 登出时间;如果会话还在线,你会看到still logged in。这两个状态的判断依据就是utmp里的对应记录是否已被清除。所以last和who拿到的是同一套数据,只是last还能对比出"历史完整链路",而who只能看"此刻的快照"。

有次一个同事问我:"为什么last里显示某用户 still logged in,但who里看不到这个人?"这种情况多半是会话异常中断,utmp记录残留了。处理方法是把对应终端的进程清一遍,或者直接重启一下 sshd。反正记住一点:who看不见了,但last还说留着,说明会话异常断开,属于需要清理的"烂尾会话"。

6. 实际维护中我沉淀下来的一套"查登录"习惯

前面讲的知识点比较多,最后分享一点我实际干活时的操作习惯。单独看每个命令都很简单,但组合起来能覆盖绝大多数日常需求。

我自己的例行巡检是这么做的:SSH 上去先执行w,看当前用户、负载、正在执行的命令,这一步能筛出90%的表面问题;然后last | head -20,确认最近有没有异常的登录来源;最后lastb | head -20,看有没有明显的爆破试探。三条命令不到十秒,一台机器的"登录健康度"基本心里有数。

如果是排查具体某个用户的操作轨迹,我会按时间线串联:

  1. last 用户名:定位这个用户最近几次登录的终端、IP、时间
  2. who -u 用户名:确认该用户当前是否在线、在哪个终端
  3. ps -t pts/N:看这个终端的进程列表,尤其是还活着的命令
  4. 需要时翻.bash_history,对照时间戳还原操作

再分享一个很多人忽略的点:如果你管理的服务器较多,建议把常用的"查登录"命令统一封装成一个脚本,输出格式固定,批量执行时能省大量时间。我自己写过一个简单的巡检脚本,核心逻辑就是执行w、last、lastb三个命令,把结果归档到固定目录,每天定时跑一次。不求花哨,胜在稳定省心。

最后想提醒一句,w命令输出的load average是整机的平均负载,它并不是"当前登录用户造成的",两者有可能是巧合。所以看到高负载先别急着怪在线用户,还要结合top、iostat这些工具往下查。这也是面试官最爱挖的坑之一:一上来就说"负载高肯定是因为有人在乱跑命令",这种答案一看就是背出来的,缺少实际排查经验支撑。

把这些命令吃透,不光是为了应付面试,更是为了在服务器真正出问题的时候,你手里有足够多的工具去定位和还原现场。我见过不少运维同行,遇到"有异常登录"第一反应是把密码改了、把用户踢了,但从来没想过先去看last完整还原一遍操作轨迹——这才是这个题目背后真正值钱的东西。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/5 2:46:36

Spring Profile多环境配置实战:从配置文件到部署避坑指南

干了几年Java后端的人&#xff0c;多少都经历过这种崩溃瞬间&#xff1a;本地跑得好好的代码&#xff0c;发到测试环境就报数据库连不上&#xff0c;一看配置才发现IP没改、密码还是本地的、日志级别也完全不对。换到生产环境更紧张&#xff0c;生怕哪个配置没切过来&#xff0…

作者头像 李华
网站建设 2026/10/5 2:46:30

短消息中心业务功能全解析:SMPP接入、重试与话单稽核

简介&#xff1a;这是一份关于短消息中心业务功能的技术培训PPT课件&#xff0c;面向通信网络运维、开发及相关学习者&#xff0c;系统讲解SMS Center在移动网络中的核心作用。内容从短消息提交、转发、优先级与有效期管理讲起&#xff0c;逐项说明重发机制、状态报告、用户鉴权…

作者头像 李华
网站建设 2026/10/5 2:46:13

企业PaaS平台建设指南:从容器编排到成本治理的落地实践

简介&#xff1a;企业PaaS通用能力平台建设方案面向企业IT架构师、运维与研发管理者&#xff0c;聚焦PaaS平台如何解决传统IT应用环境不一致、运维成本高、资源利用率低、技术路线分散和业务响应慢等问题。内容从云计算与PaaS对比切入&#xff0c;梳理标准化环境、自动化运维、…

作者头像 李华
网站建设 2026/10/5 2:46:09

2025线上线下一体化ERP选型指南:技术实力测评与避坑实战

如果你正被“线上库存和门店库存对不上、电商订单要人工导入财务系统、会员在淘宝是天猫会员到了门店又变回陌生人”这类问题缠住&#xff0c;那说明你该重新审视自己的 ERP 选型了。这几年我帮几家企业做过整套系统替换&#xff0c;见过太多销售讲得天花乱坠、实施起来一地鸡毛…

作者头像 李华
网站建设 2026/10/5 2:46:08

从零实现Python Socket:Server/Client通信与粘包处理

1. 项目概述与整体设计思路1.1 核心需求解析这个项目做的是最基础的网络通信骨架&#xff1a;用一个 Python 进程充当 Server&#xff0c;监听端口等待连接&#xff0c;另一个进程充当 Client&#xff0c;主动发起连接并交换数据。很多人觉得 Socket 编程是老古董&#xff0c;现…

作者头像 李华
网站建设 2026/10/5 2:46:05

金融核心系统云架构落地:选型、数据拆分与容灾设计要点

简介&#xff1a;这份PPT以某农业银行控股的中小型寿险公司为例&#xff0c;系统讲解金融核心业务系统云架构的规划与落地路径&#xff0c;适合保险公司、银行等金融机构的架构师、IT负责人及云平台技术选型团队阅读。内容覆盖项目背景、建设目标与实施约束&#xff0c;剖析JDK…

作者头像 李华