0

I'm writing a cloud sync script for Ubuntu 18+ that makes sure some critical files are pulled from the remote as part of the boot process. I'd like it to run after the Plymouth splash screen, but before the user login screen (either with or without a graphical environment).

Delaying login until the script has exited is imperative for this application, because I need to print a message to the console and wait for the user to press a key to acknowledge before they can log in; but I can't seem to get the systemd service unit right.

The example below works for non-graphical environments (systemd default.target = multi-user.target) but not for graphical ones (default.target = graphical.target). What am I missing?

[Unit]
Requires=network-online.target
After=network-online.target plymouth-quit-wait.service
[email protected]

[Service]
Type=oneshot
StandardInput=tty
StandardOutput=tty
StandardError=tty
TTYPath=/dev/tty1
ExecStart=/home/user/myscript.sh

[Install]
WantedBy=multi-user.target
3
  • Maybe try WantedBy= or RequiredBy= in addition to Before=. Oct 8, 2021 at 7:02
  • @HenriMenke Thx! No effect, unfortunately. Same with Conflicts=.
    – ridgek
    Oct 8, 2021 at 19:15
  • Okay, I figured out that the above example actually works for non-graphical environments, so now I just need to figure out how to delay auto-login/graphical.
    – ridgek
    Oct 8, 2021 at 23:48

1 Answer 1

0

The correct order seems to be after plymouth-quit.service, but before display-manager.service, which is the last unit started before plymouth-quit-wait.service. ie, if enabled, the display manager is started before the splash screen goes away.

So, to overcome plymouth without adding overrides to the display manager service, the workaround is to run the new service on tty2 and switch the virtual terminal to tty2 in the script.

[Unit]
Requires=network-online.target
After=network-online.target plymouth-quit.service
Before=display-manager.service

[Service]
Type=oneshot
StandardInput=tty
StandardOutput=tty
StandardError=tty
TTYPath=/dev/tty2
TTYReset=yes
TTYVHangup=yes
ExecStart=/path/to/script.sh

[Install]
WantedBy=multi-user.target
#!/bin/bash

# Change the virtual terminal to tty2
# so user can interact with the script and see its output
chvt 2

# do stuff
echo "Hello, world!"

# Change back to tty1
# so user is shown console login,
# or sent to wherever the display manager decides
chvt 1

This works, but it's not very clean without adding extra logic to the script or writing a wrapper. If I run it anywhere other than from tty1, for example (like a desktop running on tty7), or if tty2 is already occupied.

This should be okay since my script should only be run at boot, but if there is a pure systemd solution that would allow me to just keep everything on tty1 the entire time when default.target is either multi-users.target or graphical.target, I would love to hear about it.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .