TIL: The TTYPath= setting to starting an interactive program on boot
For $WORK
I had to setup a Linux machine (a Raspberry Pi) so that right
after boot, an interactive CLI tool would start, ready to receive input and
show information.
Of course if you start a script at boot, its stdin
is closed and stdout
goes to the Journal. There exists openvt(1) to launch that script in a new VT
(or to take over tty1
). (But then you have to mind that openvt
needs to
run as root to open a new VT, so it should wrap sudo
to drop privileges, and
that get a bit fiddly.)
Then I happened upon the TTYPath
setting, which does exactly what I need;
and of course it combines perfectly fine with settings for User=
or
WorkingDirectory
. I ended up with the following:
[Unit] Description=Interactive script started on boot [Install] WantedBy=multi-user.target [Service] # The magic to have prompts displayed to the user TTYPath=/dev/tty1 StandardInput=tty StandardOutput=tty User=someuser WorkingDirectory=/opt/software/ ExecStart=/opt/software/bin/start_soft # Always restart on exit, disable restart counter, delay a little bit # the restart to avoid spam in case of repeating error Restart=always StartLimitIntervalSec=0 RestartSec=5s
It only occured to me to have a look at how getty.service
is configured, and
indeed it uses the same options:
StandardInput=tty StandardOutput=tty TTYPath=/dev/%I TTYReset=yes # reset $TTYPath before and after execution TTYVHangup=yes # disconnect all clients which have open $TTYPath TTYVTDisallocate=yes # deallocate before and after execution; this ensures screen and scrollback buffer is clear
A inconvenience is that if you start on tty1
, then messages from systemd or
the kernel get mixed up with your program output. If you start on tty2
, I
tried to add ExecStartPre=chvt 2
, but the VT would switch back to tty1
depending on exact boot order.