loginctl命令

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-sessionloginctl show-user可以获取详细的会话和用户信息
  • 在多用户系统上,定期检查活动会话可以帮助识别未授权访问
  • 使用loginctl lock-sessions可以在离开计算机时快速锁定所有图形会话
  • 在远程服务器上,使用loginctl enable-linger可以确保用户服务在 SSH 会话结束后继续运行
  • 结合systemd-run --user和用户留存,可以为用户创建持久的后台服务
  • 使用loginctl show-seat可以查看系统硬件配置和可用设备
  • 在脚本中使用loginctl show -p PropertyName --value可以轻松提取特定属性
  • 在多显示器设置中,使用loginctl可以管理不同席位上的会话