loginctl 命令 #
loginctl是一个用于控制 systemd 登录管理器(systemd-logind)的命令行工具。它允许管理用户登录会话、用户席位(seat)和附加设备,提供了查询和管理用户会话的功能,以及控制用户权限和资源分配的能力。
语法 #
loginctl [选项...] 命令 [参数...]
常用命令 #
会话管理 #
| 命令 | 描述 |
|---|---|
list-sessions |
列出所有活动会话 |
session-status [ID...] |
显示会话状态 |
show-session [ID...] |
显示会话属性 |
activate [ID] |
激活会话 |
lock-session [ID...] |
锁定会话屏幕 |
unlock-session [ID...] |
解锁会话屏幕 |
lock-sessions |
锁定所有会话屏幕 |
unlock-sessions |
解锁所有会话屏幕 |
terminate-session [ID...] |
终止会话 |
kill-session [ID...] |
向会话发送信号 |
用户管理 #
| 命令 | 描述 |
|---|---|
list-users |
列出登录用户 |
user-status [USER...] |
显示用户状态 |
show-user [USER...] |
显示用户属性 |
enable-linger [USER...] |
启用用户留存 |
disable-linger [USER...] |
禁用用户留存 |
terminate-user [USER...] |
终止用户的所有会话 |
kill-user [USER...] |
向用户的所有进程发送信号 |
席位管理 #
| 命令 | 描述 |
|---|---|
list-seats |
列出所有席位 |
seat-status [SEAT...] |
显示席位状态 |
show-seat [SEAT...] |
显示席位属性 |
attach [SEAT] [DEVICE...] |
将设备附加到席位 |
flush-devices |
刷新所有设备 |
terminate-seat [SEAT...] |
终止席位的所有会话 |
常用选项 #
| 选项 | 描述 |
|---|---|
-h, --help |
显示帮助信息 |
--version |
显示版本信息 |
--no-pager |
不将输出通过分页器传递 |
-p, --property= |
显示特定属性 |
-a, --all |
显示所有属性,包括空属性 |
-l, --full |
不截断输出 |
--no-legend |
不打印列标题和页脚 |
--no-ask-password |
不询问密码 |
-H, --host= |
在远程主机上操作 |
-M, --machine= |
在本地容器上操作 |
-s, --signal= |
发送指定信号 |
-n, --lines= |
显示的日志条目数 |
-o, --output= |
更改日志输出模式 |
常见用法 #
会话管理 #
1. 列出所有活动会话 #
loginctl list-sessions
输出示例:
SESSION UID USER SEAT TTY
1 1000 user1 seat0 tty1
2 1001 user2 seat0
3 1000 user1 pts/0
3 sessions listed.
2. 显示会话状态 #
loginctl session-status 3
输出示例:
3 - user1 (1000)
Since: Mon 2023-01-16 15:30:45 CET; 2h 5min ago
Leader: 1234 (sshd)
Seat: n/a
TTY: pts/0
Service: sshd; type tty; class user
State: active
Unit: session-3.scope
├─1234 sshd: user1 [priv]
├─1245 sshd: user1@pts/0
├─1246 -bash
└─1890 loginctl session-status 3
3. 显示会话详细属性 #
loginctl show-session 3
输出示例:
Id=3
User=1000
Name=user1
Timestamp=Mon 2023-01-16 15:30:45 CET
TimestampMonotonic=135794920
VTNr=0
Seat=
TTY=pts/0
Remote=yes
RemoteHost=192.168.1.100
Service=sshd
Scope=session-3.scope
Leader=1234
Type=tty
Class=user
Active=yes
State=active
IdleHint=no
IdleSinceHint=0
IdleSinceHintMonotonic=0
4. 激活特定会话 #
loginctl activate 1
这将激活会话 1,使其成为活动会话。
5. 锁定会话屏幕 #
loginctl lock-session 1
6. 解锁会话屏幕 #
loginctl unlock-session 1
7. 终止会话 #
loginctl terminate-session 3
8. 向会话发送信号 #
loginctl kill-session 3 --signal=SIGTERM
用户管理 #
1. 列出登录用户 #
loginctl list-users
输出示例:
UID USER
1000 user1
1001 user2
2 users listed.
2. 显示用户状态 #
loginctl user-status user1
输出示例:
user1 (1000)
Since: Mon 2023-01-16 15:30:45 CET; 2h 10min ago
State: active
Sessions: 1 *3
Linger: no
Unit: user-1000.slice
├─session-1.scope
│ ├─1234 sshd: user1 [priv]
│ ├─1245 sshd: user1@pts/0
│ ├─1246 -bash
│ └─1890 loginctl user-status user1
└─[email protected]
└─init.scope
├─1200 /lib/systemd/systemd --user
└─1201 (sd-pam)
3. 显示用户详细属性 #
loginctl show-user user1
输出示例:
UID=1000
GID=1000
Name=user1
Timestamp=Mon 2023-01-16 15:30:45 CET
TimestampMonotonic=135794920
RuntimePath=/run/user/1000
[email protected]
Slice=user-1000.slice
Display=1
State=active
Sessions=1 3
IdleHint=no
IdleSinceHint=0
IdleSinceHintMonotonic=0
Linger=no
4. 启用用户留存 #
loginctl enable-linger user1
启用用户留存后,即使用户没有活动会话,其用户服务也会继续运行。
5. 禁用用户留存 #
loginctl disable-linger user1
6. 终止用户的所有会话 #
loginctl terminate-user user1
7. 向用户的所有进程发送信号 #
loginctl kill-user user1 --signal=SIGTERM
席位管理 #
席位(seat)是一组硬件设备(如显示器、键盘、鼠标等),允许用户本地登录系统。
1. 列出所有席位 #
loginctl list-seats
输出示例:
SEAT
seat0
1 seats listed.
2. 显示席位状态 #
loginctl seat-status seat0
输出示例:
seat0
Sessions: 1 2
Devices:
├─/sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input0
├─/sys/devices/platform/serial8250/tty/ttyS0
├─/sys/devices/platform/serial8250/tty/ttyS1
├─/sys/devices/platform/serial8250/tty/ttyS2
├─/sys/devices/platform/serial8250/tty/ttyS3
├─/sys/devices/pci0000:00/0000:00:02.0/drm/card0
├─/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1/2-1.1:1.0/input/input3
├─/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/input/input4
└─/sys/devices/pci0000:00/0000:00:1f.3/sound/card0
3. 显示席位详细属性 #
loginctl show-seat seat0
输出示例:
Id=seat0
CanGraphical=yes
CanMultiSession=yes
Sessions=1 2
IdleHint=no
IdleSinceHint=0
IdleSinceHintMonotonic=0
4. 将设备附加到席位 #
loginctl attach seat0 /sys/devices/pci0000:00/0000:00:1f.3/sound/card1
5. 终止席位的所有会话 #
loginctl terminate-seat seat0
高级用法 #
1. 查询特定属性 #
loginctl show-session 3 -p Type -p TTY
输出示例:
Type=tty
TTY=pts/0
2. 检查用户是否启用了留存 #
loginctl show-user user1 -p Linger
输出示例:
Linger=no
3. 查看会话的资源使用情况 #
systemctl status "session-$(loginctl list-sessions --no-legend | awk '{print $1}' | head -n1).scope"
4. 在远程主机上操作 #
loginctl --host=user@remote-server list-sessions
5. 在容器中操作 #
loginctl --machine=container_name list-users
6. 查看会话日志 #
loginctl session-status 3 --no-pager
用户留存(Linger) #
用户留存是 systemd 的一个功能,允许用户的服务在没有活动登录会话的情况下继续运行。这对于运行后台服务、定时任务或长时间运行的进程非常有用。
启用用户留存:
loginctl enable-linger username
禁用用户留存:
loginctl disable-linger username
检查用户留存状态:
loginctl show-user username -p Linger
启用留存后,用户的 systemd 实例将在系统启动时自动启动,并在用户注销后继续运行。
实用示例 #
1. 创建用户会话报告 #
#!/bin/bash
# 生成用户会话报告
echo "Active Sessions Report - $(date)"
echo "================================"
# 获取所有活动会话
SESSIONS=$(loginctl list-sessions --no-legend)
# 遍历每个会话
while read -r session_info; do
# 提取会话ID和用户名
SESSION_ID=$(echo "$session_info" | awk '{print $1}')
USER=$(echo "$session_info" | awk '{print $3}')
# 获取会话详细信息
SESSION_TYPE=$(loginctl show-session "$SESSION_ID" -p Type --value)
SESSION_TTY=$(loginctl show-session "$SESSION_ID" -p TTY --value)
SESSION_REMOTE=$(loginctl show-session "$SESSION_ID" -p Remote --value)
SESSION_TIMESTAMP=$(loginctl show-session "$SESSION_ID" -p Timestamp --value)
echo "Session ID: $SESSION_ID"
echo "User: $USER"
echo "Type: $SESSION_TYPE"
echo "TTY: $SESSION_TTY"
echo "Remote: $SESSION_REMOTE"
echo "Started: $SESSION_TIMESTAMP"
echo "--------------------------------"
done <<< "$SESSIONS"
2. 监控远程登录 #
#!/bin/bash
# 监控远程登录并发送通知
# 获取远程会话
REMOTE_SESSIONS=$(loginctl list-sessions --no-legend | while read -r session_info; do
SESSION_ID=$(echo "$session_info" | awk '{print $1}')
REMOTE=$(loginctl show-session "$SESSION_ID" -p Remote --value)
if [ "$REMOTE" = "yes" ]; then
USER=$(echo "$session_info" | awk '{print $3}')
REMOTE_HOST=$(loginctl show-session "$SESSION_ID" -p RemoteHost --value)
echo "User $USER logged in from $REMOTE_HOST (Session $SESSION_ID)"
fi
done)
# 如果有远程会话,发送通知
if [ -n "$REMOTE_SESSIONS" ]; then
echo "Remote login detected at $(date)" > /tmp/remote_login.log
echo "$REMOTE_SESSIONS" >> /tmp/remote_login.log
# 发送邮件通知
mail -s "Remote Login Alert" [email protected] < /tmp/remote_login.log
fi
3. 自动锁定闲置会话 #
#!/bin/bash
# 自动锁定闲置会话
# 获取图形会话
GRAPHICAL_SESSIONS=$(loginctl list-sessions --no-legend | while read -r session_info; do
SESSION_ID=$(echo "$session_info" | awk '{print $1}')
TYPE=$(loginctl show-session "$SESSION_ID" -p Type --value)
if [ "$TYPE" = "x11" ] || [ "$TYPE" = "wayland" ]; then
IDLE_HINT=$(loginctl show-session "$SESSION_ID" -p IdleHint --value)
if [ "$IDLE_HINT" = "yes" ]; then
echo "$SESSION_ID"
fi
fi
done)
# 锁定闲置的图形会话
for SESSION_ID in $GRAPHICAL_SESSIONS; do
echo "Locking idle session $SESSION_ID"
loginctl lock-session "$SESSION_ID"
done
4. 设置用户资源限制 #
#!/bin/bash
# 为用户设置资源限制
USER=$1
MEMORY_LIMIT=$2 # 例如:2G
if [ -z "$USER" ] || [ -z "$MEMORY_LIMIT" ]; then
echo "Usage: $0 username memory_limit"
echo "Example: $0 user1 2G"
exit 1
fi
# 创建用户特定的systemd配置目录
mkdir -p /etc/systemd/system/user-$USER.slice.d/
# 创建资源限制配置
cat > /etc/systemd/system/user-$USER.slice.d/memory.conf << EOF
[Slice]
MemoryMax=$MEMORY_LIMIT
EOF
# 重新加载systemd配置
systemctl daemon-reload
echo "Memory limit for user $USER set to $MEMORY_LIMIT"
5. 启用用户服务自动启动 #
#!/bin/bash
# 为用户启用服务自动启动
USER=$1
SERVICE=$2 # 例如:myapp.service
if [ -z "$USER" ] || [ -z "$SERVICE" ]; then
echo "Usage: $0 username service_name"
echo "Example: $0 user1 myapp.service"
exit 1
fi
# 启用用户留存
loginctl enable-linger $USER
# 为用户启用服务
sudo -u $USER systemctl --user enable $SERVICE
echo "Service $SERVICE enabled for user $USER with linger"
常见问题排查 #
1. 权限问题 #
Failed to enable linger: Interactive authentication required.
解决方法:使用 sudo 运行命令。
sudo loginctl enable-linger username
2. 无法终止会话 #
可能的原因:
- 会话 ID 不正确
- 权限不足
- 会话已经终止
解决方法:
# 确认会话ID
loginctl list-sessions
# 使用sudo
sudo loginctl terminate-session session_id
# 如果仍然失败,尝试向会话发送SIGKILL信号
sudo loginctl kill-session session_id --signal=SIGKILL
3. 用户留存设置不生效 #
可能的原因:
- systemd 版本过低
- 系统配置禁用了此功能
- 权限问题
解决方法:
# 检查systemd版本
systemctl --version
# 确认留存目录存在
ls -la /var/lib/systemd/linger/
# 手动创建留存标记
sudo mkdir -p /var/lib/systemd/linger/
sudo touch /var/lib/systemd/linger/username
4. 无法在容器中使用 loginctl #
在容器中,loginctl可能无法正常工作,因为容器通常不运行完整的 systemd。
解决方法:
# 在容器主机上使用
sudo loginctl --machine=container_name list-sessions
# 或者在容器内使用nsenter
nsenter -t 1 -m -p loginctl list-sessions
提示 #
- 使用
loginctl list-sessions --no-legend可以获取更容易解析的输出,适合在脚本中使用 - 启用用户留存对于运行用户级服务(如 GNOME、KDE 等桌面环境服务)很有用
- 使用
loginctl show-session和loginctl show-user可以获取详细的会话和用户信息 - 在多用户系统上,定期检查活动会话可以帮助识别未授权访问
- 使用
loginctl lock-sessions可以在离开计算机时快速锁定所有图形会话 - 在远程服务器上,使用
loginctl enable-linger可以确保用户服务在 SSH 会话结束后继续运行 - 结合
systemd-run --user和用户留存,可以为用户创建持久的后台服务 - 使用
loginctl show-seat可以查看系统硬件配置和可用设备 - 在脚本中使用
loginctl show -p PropertyName --value可以轻松提取特定属性 - 在多显示器设置中,使用
loginctl可以管理不同席位上的会话