You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过systemd oneshot服务延迟登录提示至进程执行完成?

Fixing Systemd Oneshot Service to Block Login Prompt Until Process Completes

Alright, let's tackle this problem. The core issue here is that by default, login managers (like GDM, LightDM, or text gettys) start as soon as their target (graphical.target or multi-user.target) is reached—they don't wait for arbitrary oneshot services to finish. Here's how to configure things so your process completes before the login prompt appears:

Step 1: Configure Your Oneshot Service First

Create or edit your service file (e.g., /etc/systemd/system/pre-login-task.service) with these critical settings:

[Unit]
Description=Pre-login initialization task
# Run after essential system services (adjust based on your process needs)
After=network.target basic.target
# Ensure this runs BEFORE the login manager and system targets that trigger login prompts
Before=graphical.target multi-user.target gdm.service getty@tty1.service
# Optional: If your process must succeed to allow login, use Requires; use Wants for weak dependency
Requires=pre-login-task.service

[Service]
Type=oneshot
# Replace with your actual process/script path
ExecStart=/path/to/your/long-running-process.sh
# Wait for the process to fully exit before marking the service as done
RemainAfterExit=no
# Define acceptable exit codes (adjust if your process uses non-zero success codes)
SuccessExitStatus=0

[Install]
# Tie the service to both graphical and multi-user targets
WantedBy=graphical.target multi-user.target

Key Notes for This Config:

  • Before=graphical.target ... gdm.service getty@tty1.service: Ensures your service starts before the login manager and system targets that trigger login prompts.
  • Type=oneshot: Tells systemd this is a one-time task that must complete before proceeding.
  • RemainAfterExit=no: Cleans up the service state once your process finishes (since it's a one-off task).

Step 2: Force Login Managers to Wait for Your Service

Instead of modifying the original login manager service files (which can be overwritten by updates), use a systemd drop-in file to add dependencies.

For Graphical Login (e.g., GDM):

Create /etc/systemd/system/gdm.service.d/99-wait-pre-login.conf:

[Unit]
# Make GDM wait for your service to finish
After=pre-login-task.service
# Optional: Block GDM if your service fails (remove if you want login prompt even on failure)
Requires=pre-login-task.service

For Text Login (Getty on TTY1):

Create /etc/systemd/system/getty@tty1.service.d/99-wait-pre-login.conf:

[Unit]
After=pre-login-task.service
Requires=pre-login-task.service

Step 3: Apply the Configuration

Run these commands to reload systemd and enable your service:

sudo systemctl daemon-reload
sudo systemctl enable pre-login-task.service

Step 4: Test and Troubleshoot

  • Reboot your system to verify the login prompt only appears after your process finishes.
  • If it's still not working, check the boot order with systemd-analyze plot > boot.svg—open the SVG file to confirm your service completes before the login manager starts.
  • Check service logs with journalctl -u pre-login-task.service to ensure your process is running successfully.

内容的提问来源于stack exchange,提问作者natty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:13:10