who 命令用于显示当前登录系统的用户信息。它可以显示登录用户名、终端设备、登录时间、来源IP地址等,是系统管理员监控用户登录情况的重要工具。
who [选项] [文件]
| 选项 | 说明 |
|---|---|
-a 或 --all |
显示所有信息(相当于 -b -d --login -p -r -t -T -u) |
-b 或 --boot |
显示系统最近启动时间 |
-d 或 --dead |
显示已终止的进程 |
-H 或 --heading |
显示列标题 |
-l 或 --login |
显示系统登录进程 |
-m |
仅显示当前终端相关的用户信息 |
-p 或 --process |
显示由init生成的活动进程 |
-q 或 --count |
显示登录用户总数(快速模式) |
-r 或 --runlevel |
显示当前运行级别 |
-s |
显示简短信息(默认) |
-t 或 --time |
显示系统时钟上次修改时间 |
-T 或 --mesg |
显示用户的消息状态(+ 允许,- 禁止) |
-u 或 --users |
显示已登录用户列表 |
--version |
显示版本信息 |
--help |
显示帮助信息 |
who
输出示例:
alice pts/0 2024-01-12 09:30 (192.168.1.100)
bob tty2 2024-01-12 10:15
charlie pts/1 2024-01-12 11:00 (192.168.1.101)
who -uH
输出示例:
名称 线路 时间 空闲 进程号 备注
alice pts/0 2024-01-12 09:30 . 12345 (192.168.1.100)
bob tty2 2024-01-12 10:15 01:30 23456
charlie pts/1 2024-01-12 11:00 00:15 34567 (192.168.1.101)
who -aH
显示包括系统启动时间、运行级别等在内的所有信息。
who -T
输出示例:
alice + pts/0 2024-01-12 09:30 (192.168.1.100)
bob - tty2 2024-01-12 10:15
charlie + pts/1 2024-01-12 11:00 (192.168.1.101)
消息状态说明:+表示允许接收消息,-表示禁止接收消息。
who -q
输出示例:
alice bob charlie
# 用户数=3
# 查看指定用户的登录信息
who | grep alice
# 查看root用户的登录信息
who | grep '^root'
# 查看所有远程登录的用户
who | grep -v '(:0)' | grep -v 'tty'
# 或者查看有IP地址的用户
who | awk '{if ($5 != "") print $0}'
# 统计每个用户的登录次数
who | awk '{print $1}' | sort | uniq -c | sort -rn
# 按用户统计并排序
who | cut -d' ' -f1 | sort | uniq -c | sort -rn
#!/bin/bash
# 系统安全监控脚本:检查异常登录
LOG_FILE="/var/log/user_monitor.log"
ALERT_THRESHOLD=3 # 同一用户最大登录数
echo "=== 用户登录监控报告 $(date) ===" >> $LOG_FILE
# 检查当前登录用户数
USER_COUNT=$(who | wc -l)
echo "当前登录用户数: $USER_COUNT" >> $LOG_FILE
# 检查每个用户的登录次数
echo -e "\n用户登录统计:" >> $LOG_FILE
who | awk '{print $1}' | sort | uniq -c | while read count user; do
echo " $user: $count 个会话" >> $LOG_FILE
# 如果同一用户登录次数过多,发出警告
if [ $count -gt $ALERT_THRESHOLD ]; then
echo "警告: 用户 $user 有 $count 个并发会话!" >> $LOG_FILE
echo "发送警报邮件..."
echo "用户 $user 有 $count 个并发会话" | mail -s "安全警报: 异常登录" admin@example.com
fi
done
# 检查远程登录
echo -e "\n远程登录用户:" >> $LOG_FILE
who | awk '$5 ~ /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ {print $1, $5}' | sort -u >> $LOG_FILE
echo -e "\n监控完成\n" >> $LOG_FILE
#!/bin/bash
# 工作时间用户活动监控
REPORT_FILE="/var/log/daily_login_report.txt"
WORK_START="09:00"
WORK_END="18:00"
echo "每日登录报告 - $(date)" > $REPORT_FILE
echo "==========================" >> $REPORT_FILE
# 获取当前时间
CURRENT_HOUR=$(date +%H)
CURRENT_MIN=$(date +%M)
CURRENT_TIME="$CURRENT_HOUR:$CURRENT_MIN"
echo -e "\n1. 当前登录用户 ($CURRENT_TIME):" >> $REPORT_FILE
who -uH >> $REPORT_FILE
echo -e "\n2. 今日登录历史:" >> $REPORT_FILE
last | grep "$(date +'%Y-%m-%d')" | head -20 >> $REPORT_FILE
echo -e "\n3. 工作时间活跃用户统计:" >> $REPORT_FILE
# 这里可以添加更复杂的逻辑来分析用户在岗时间
echo -e "\n报告生成完成" >> $REPORT_FILE
echo "报告已保存到: $REPORT_FILE"
#!/bin/bash
# 基于用户登录情况的资源分配脚本
MIN_USERS=1
MAX_USERS=10
CURRENT_USERS=$(who -q | tail -1 | awk -F= '{print $2}')
echo "当前登录用户数: $CURRENT_USERS"
# 根据用户数调整资源分配
if [ $CURRENT_USERS -lt $MIN_USERS ]; then
echo "用户数较少,进入节能模式..."
# 降低CPU频率
sudo cpupower frequency-set -g powersave
# 关闭不必要的服务
sudo systemctl stop unattended-upgrades
elif [ $CURRENT_USERS -gt $MAX_USERS ]; then
echo "用户数较多,进入高性能模式..."
# 提高CPU频率
sudo cpupower frequency-set -g performance
# 启动额外服务
sudo systemctl start nginx
sudo systemctl start mysql
else
echo "用户数正常,保持当前配置..."
fi
| 命令 | 功能 | 特点 | 适用场景 |
|---|---|---|---|
who |
显示当前登录用户 | 简单、快速、信息较少 | 快速查看谁在线 |
w |
显示登录用户及活动 | 显示用户正在执行的命令 | 查看用户当前活动 |
last |
显示登录历史 | 历史记录、详细时间 | 审计和调查 |
lastlog |
显示用户最后登录时间 | 所有用户最后登录时间 | 检查不活跃账户 |
users |
显示登录用户名 | 极简、只显示用户名 | 快速用户计数 |
finger |
显示用户详细信息 | 用户个人信息、计划等 | 获取用户完整信息 |
# who - 当前登录用户
$ who
alice pts/0 2024-01-12 09:30 (192.168.1.100)
bob tty2 2024-01-12 10:15
# w - 用户及活动
$ w
11:20:15 up 2:30, 2 users, load average: 0.15, 0.10, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
alice pts/0 192.168.1.100 09:30 0.00s 0.10s 0.05s sshd: alice [priv]
bob tty2 - 10:15 1:05m 0.05s 0.05s -bash
# last - 登录历史
$ last | head -5
alice pts/0 192.168.1.100 Fri Jan 12 09:30 still logged in
bob tty2 Fri Jan 12 10:15 still logged in
charlie pts/1 192.168.1.101 Thu Jan 11 14:20 - 17:45 (03:25)
# lastlog - 最后登录时间
$ lastlog | head -5
用户名 端口 来自 最后登录时间
root **从未登录过**
alice pts/0 192.168.1.100 五 1月 12 09:30:00 +0800 2024
bob tty2 五 1月 12 10:15:00 +0800 2024
| 文件 | 作用 |
|---|---|
/var/run/utmp |
当前登录用户信息(who命令的主要数据源) |
/var/log/wtmp |
历史登录记录(last命令的数据源) |
/var/log/btmp |
失败的登录尝试记录 |
/proc/self/sessionid |
当前会话ID |
# 使用utmpdump查看utmp文件内容
sudo utmpdump /var/run/utmp
# 查看wtmp文件(历史记录)
sudo utmpdump /var/log/wtmp | head -20
# 查看btmp文件(失败登录)
sudo utmpdump /var/log/btmp | head -10
# 统计登录失败次数
sudo utmpdump /var/log/btmp | wc -l
# 检查utmp文件是否存在
ls -la /var/run/utmp
# 检查文件权限
ls -la /var/run/utmp
# 修复utmp文件
sudo touch /var/run/utmp
sudo chmod 664 /var/run/utmp
sudo chown root:utmp /var/run/utmp
# 重启系统服务
sudo systemctl restart systemd-logind
# 使用-a选项显示所有信息
who -a
# 检查是否使用sudo权限
sudo who -a
# 检查其他登录方式
last
w
# 检查所有伪终端
ls /dev/pts/
# 检查系统时区
timedatectl
# 设置正确时区
sudo timedatectl set-timezone Asia/Shanghai
# 检查系统时间
date
hwclock
# 同步时间
sudo ntpdate -u pool.ntp.org
#!/bin/bash
# 综合安全监控脚本
LOG_DIR="/var/log/security_monitor"
mkdir -p $LOG_DIR
DAILY_REPORT="$LOG_DIR/daily_report_$(date +%Y%m%d).txt"
echo "=== 每日安全监控报告 ===" > $DAILY_REPORT
echo "生成时间: $(date)" >> $DAILY_REPORT
echo "=========================" >> $DAILY_REPORT
# 1. 当前登录状态
echo -e "\n1. 当前登录用户:" >> $DAILY_REPORT
who -uH >> $DAILY_REPORT
# 2. 今日登录统计
echo -e "\n2. 今日登录统计:" >> $DAILY_REPORT
last | grep "$(date +'%Y-%m-%d')" | wc -l | xargs echo "今日登录次数: " >> $DAILY_REPORT
# 3. 失败登录尝试
echo -e "\n3. 失败登录尝试:" >> $DAILY_REPORT
sudo lastb | head -10 >> $DAILY_REPORT
# 4. 异常登录检测
echo -e "\n4. 异常登录检测:" >> $DAILY_REPORT
# 检测非工作时间登录
CURRENT_HOUR=$(date +%H)
if [ $CURRENT_HOUR -lt 6 ] || [ $CURRENT_HOUR -gt 22 ]; then
echo "警告: 当前为非工作时间 ($CURRENT_HOUR:00)" >> $DAILY_REPORT
who >> $DAILY_REPORT
fi
# 5. 用户登录频率
echo -e "\n5. 用户登录频率:" >> $DAILY_REPORT
who | awk '{print $1}' | sort | uniq -c | sort -rn >> $DAILY_REPORT
echo -e "\n报告生成完成" >> $DAILY_REPORT
echo "报告保存至: $DAILY_REPORT"
#!/bin/bash
# 实时登录监控面板
while true; do
clear
echo "=== 实时登录监控面板 ==="
echo "时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "========================="
echo ""
# 当前登录用户
echo "当前登录用户:"
who -uH
echo ""
echo "用户活动摘要:"
w | tail -n +3
echo ""
echo "系统状态:"
echo "运行时间: $(uptime -p)"
echo "负载: $(uptime | awk -F'load average:' '{print $2}')"
sleep 5
done
#!/bin/bash
# 自动化登录审计系统
AUDIT_DB="/var/log/login_audit.db"
# 初始化数据库
if [ ! -f "$AUDIT_DB" ]; then
echo "创建登录审计数据库..."
sqlite3 $AUDIT_DB "CREATE TABLE logins (
id INTEGER PRIMARY KEY,
username TEXT,
terminal TEXT,
login_time TEXT,
remote_host TEXT,
session_duration TEXT
);"
fi
# 收集当前登录信息
collect_logins() {
who -u | while read line; do
username=$(echo $line | awk '{print $1}')
terminal=$(echo $line | awk '{print $2}')
login_time=$(echo $line | awk '{print $3 " " $4}')
remote_host=$(echo $line | awk '{print substr($0, index($0,$5))}')
# 插入数据库
sqlite3 $AUDIT_DB "INSERT INTO logins (username, terminal, login_time, remote_host)
VALUES ('$username', '$terminal', '$login_time', '$remote_host');"
done
}
# 生成审计报告
generate_report() {
echo "=== 登录审计报告 ==="
echo "生成时间: $(date)"
echo ""
echo "1. 今日登录统计:"
sqlite3 $AUDIT_DB "SELECT username, COUNT(*) as count FROM logins
WHERE DATE(login_time) = DATE('now')
GROUP BY username ORDER BY count DESC;"
echo ""
echo "2. 最近登录记录:"
sqlite3 $AUDIT_DB "SELECT * FROM logins ORDER BY login_time DESC LIMIT 10;"
}
# 执行收集和报告
collect_logins
generate_report
#!/bin/bash
# 基于登录状态的动态资源管理
CONFIG_FILE="/etc/login_based_resources.conf"
# 默认配置
MIN_CPU_FREQ="800MHz"
MAX_CPU_FREQ="3.5GHz"
IDLE_TIMEOUT=1800 # 30分钟
# 监控循环
while true; do
# 获取当前登录用户数
USER_COUNT=$(who | wc -l)
# 获取用户空闲时间
IDLE_USERS=0
who -u | awk '{print $5}' | while read idle; do
if [[ "$idle" =~ ^[0-9]+:[0-9]+$ ]]; then
# 转换空闲时间为秒
minutes=$(echo $idle | cut -d: -f1)
seconds=$(echo $idle | cut -d: -f2)
total_seconds=$((minutes * 60 + seconds))
if [ $total_seconds -gt $IDLE_TIMEOUT ]; then
IDLE_USERS=$((IDLE_USERS + 1))
fi
fi
done
ACTIVE_USERS=$((USER_COUNT - IDLE_USERS))
echo "用户状态: 总数=$USER_COUNT, 活跃=$ACTIVE_USERS, 空闲=$IDLE_USERS"
# 根据活跃用户数调整资源
if [ $ACTIVE_USERS -eq 0 ]; then
echo "无活跃用户,进入深度节能模式"
sudo cpupower frequency-set -d $MIN_CPU_FREQ -u $MIN_CPU_FREQ
sudo systemctl stop apache2
elif [ $ACTIVE_USERS -lt 3 ]; then
echo "少量活跃用户,启用平衡模式"
sudo cpupower frequency-set -g powersave
else
echo "多活跃用户,启用性能模式"
sudo cpupower frequency-set -g performance
sudo systemctl start apache2
fi
sleep 300 # 每5分钟检查一次
done
who -b 快速查看系统启动时间watch who 实时监控登录变化who -q 快速获取用户数用于脚本who | wc -l 统计在线用户数last 和 lastlog 获取历史登录信息