Linux 如何统计系统上各个用户登录(或者登出)记录出现的次数?
命令
last | grep -v "^$" | awk '{ print $1 }' | sort -nr | uniq -c
逐段解析
last
-
从
/var/log/wtmp
(或者对应的系统登录日志)中读取并列出最近的登录、重启、关机等记录。 -
每行开头通常是用户名,例如:
alice pts/0 192.168.1.5 Tue Jul 22 10:15 still logged in
bob tty1 Mon Jul 21 09:00 - 17:00 (08:00)
reboot system boot 5.11.0-27-generic Tue Jul 22 09:00
grep -v “^$”
-
^$
匹配“空行”。 -
-v
表示“取反”,也就是去掉所有空行。 -
这样做主要是防止后面处理时碰到空行导致多余的空白用户名。
awk ‘{ print $1 }’
-
将每一行按空白(空格或制表符)拆分字段,
$1
就是第 1 个字段——用户名(或者特殊条目如reboot
、shutdown
等)。 -
输出后的结果是一列用户名,例如:
alice
alice
bob
reboot
alice
sort -nr
-
sort
用来对前一步的用户名列表进行排序。 -
-n
按“数值”排序,-r
倒序(从大到小)。 -
虽然此处每行都是字符串用户名,不是纯数字,但
sort -nr
会尝试把整行当数字比较,遇到非数字时效果可能与sort -r
接近(把“字母行”视作 0 排在后面)。 -
这里本意是先把相同用户名聚在一起(任何
sort
都可);如果想按照出现次数倒序,应该在uniq -c
后再加一次sort -nr
。
uniq -c
-
uniq
用来把相邻的相同文本行合并,并加上出现次数。 -
-c
选项会在每行前面打印该行重复的次数。 -
例如,将上面的用户名列表:
alice
alice
alice
bob
reboot
经过 uniq -c
会得到:
3 alice1 bob1 reboot
整体作用
-
读取登录记录 →
last
-
去掉空行 →
grep -v "^$"
-
提取用户名 →
awk '{print $1}'
-
(先行)排序以便于计数 →
sort
-
统计每个用户名出现的次数 →
uniq -c
典型应用场景:
-
找出最活跃的用户
-
检测异常频繁登录(如暴力破解)
-
审计系统访问情况
-
统计服务器用户活动频率
最终输出形如:
123 alice45 bob10 charlie2 reboot
表示 alice
的登录/登出记录出现了 123
次,以此类推。可以进一步在输出后面再加一个 | sort -nr
,就能让出现次数多的用户排在最上面,更直观地看到“谁最常登录”:
last | grep -v "^$" | awk '{print $1}' | sort | uniq -c | sort -nr
这样就完成了从登录记录到按频率排名的全流程统计。
对于大型系统,可以使用更高效的工具组合:
last -w | cut -d' ' -f1 | grep -v '^$' | sort | uniq -c | sort -nr
-
-w
:显示完整用户名(避免截断) -
cut -d' ' -f1
:比awk
更轻量级的字段提取工具
实用场景:
安全审计:检测异常登录行为
# 检查root登录
last | grep -v "^$" | awk '$1=="root"{print}' | wc -l
排除系统账户(仅统计真实用户):
last | grep -v -E "^(reboot|wtmp|^$)" | awk '{print $1}' | sort | uniq -c | sort -nr
按时间段统计:
# 统计本月登录
last -s $(date +%Y-%m-01) | grep -v "^$" | awk '{print $1}' | sort | uniq -c | sort -nr