= Stop Clearing My God Damned Console = If you're like me, the very first thing you see when you boot a new version of your Linux distribution that has switched to `systemd` is that it erases ''everything'' from your console. Obviously, we don't want that! We want to see at least the boot messages. If you're even ''more'' like me, you want to see everything from the previous login session, too. I mean, that's why you removed the `clear` line from your `~/.bash_logout` file, right? In the previous version of your Linux distribution, which probably used some variant of System V init, the screen-clearing was done by `getty` which was configured in `/etc/inittab`. All you had to do was: * Edit `/etc/inittab`, adding the `--noclear` option to each `getty` command * Run `telinit q` to make `init` re-read the file Trying to figure out how to do the same thing in systemd is maddening. There are some documents floating around the Internet that describe ''part'' of the process, but I didn't see any that told you how to do it for ''all'' gettys (usually just the getty on tty1), and ''none'' of them described what the directory names mean, what the file names mean, how you know what to put where, or what command you have to type after you're all done to make systemd re-read the file. That's why I'm writing this. == Services... I mean, units == Apparently systemd doesn't manage ''services'' like you might be used to from other boot systems. It calls its services "units". So a "unit" is a service, and a "unit file" is the configuration (it's not a file -- it's ''multiple files'') that defines that service. The first challenge is to find out the name of the unit that you need to change. It's not as obvious as you think, because there's some sort of inheritance crap going on too. We start with the command '''systemctl -a''' which lists all the units: {{{ $ systemctl -a UNIT LOAD ACTIVE SUB DESCRIPTION proc-sys-fs-binfmt_misc.automount loaded active waiting Arbitrary Execu dev-cdrom.device loaded active plugged hp_CDDVDW_SH-216BB dev-cdrw.device loaded active plugged hp_CDDVDW_SH-216BB dev-disk-by\x2did-ata\x2dhp_CDDVDW_SH\x2d216BB_R8TM6GBC900DM9.device loaded dev-disk-by\x2did-ata\x2dST250DM000\x2d1BD141_9VYJ77MX.device loaded active ... emergency.service loaded inactive dead Emergency Shell exim4.service loaded active running LSB: exim Mail Transpor fcgiwrap.service loaded inactive dead Simple CGI Server getty-static.service loaded inactive dead getty on tty2-tty6 if d getty@tty1.service loaded active running Getty on tty1 getty@tty2.service loaded active running Getty on tty2 getty@tty3.service loaded active running Getty on tty3 getty@tty4.service loaded active running Getty on tty4 getty@tty5.service loaded active running Getty on tty5 getty@tty6.service loaded active running Getty on tty6 ... }}} The output is automatically piped through a pager if you run it on a terminal (at least in Debian), so you may have to page down a few times. Once you've identified a unit you want to look at, you move on the the next command. == Unit files == Now we want to see the "unit file" (configuration) for the unit named `getty@tty1.service`. We run '''systemctl cat unit-name''': {{{ $ systemctl cat getty@tty1.service # /lib/systemd/system/getty@.service # This file is part of systemd. # # systemd is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. [Unit] Description=Getty on %I Documentation=man:agetty(8) man:systemd-getty-generator(8) Documentation=http://0pointer.de/blog/projects/serial-console.html ... [Service] # the VT is cleared by TTYVTDisallocate ExecStart=-/sbin/agetty --noclear %I $TERM Type=idle Restart=always RestartSec=0 UtmpIdentifier=%I TTYPath=/dev/%I TTYReset=yes TTYVHangup=yes TTYVTDisallocate=yes KillMode=process IgnoreSIGPIPE=no SendSIGHUP=yes ... }}} Like `systemctl -a`, this command's output is also piped through a pager by default. Don't let the "cat" in the name fool you. If you actually want `cat`-style output (just a bunch of bytes on stdout), you can use `systemctl cat unit-name | cat`. Now this tells us some interesting things: * The bulk of this "unit file" comes from the actual file `/lib/systemd/system/getty@.service` * The files are written in Microsoft Windows .INI syntax * `TTYVTDisallocate=yes` overrides what the manual page `systemd.exec(5)` says (that the default for this setting is "no") Of course, this doesn't tell you how to change anything. The "obvious" thing to do would be to edit `/lib/systemd/system/getty@.service` but that's not the accepted practice. Instead, you're supposed to create an override file. == Overriding stupid settings == Apparently, if you want to override stupid settings in `/lib/systemd/system/getty@.service` you do so by creating a '''directory''' (not a file!) named `/etc/systemd/system/getty@.service.d` (note that the beginning ''and'' the ending are different -- it's in `/etc` and it ends with `.d`). Then, inside that directory, you create one or more files with little .INI-syntax snippets that mimic the syntax of the file from `/lib` or `/usr/lib`. {{{ # mkdir /etc/systemd/system/getty@.service.d # vi /etc/systemd/system/getty@.service.d/noclear.conf }}} All of the other documents I found seem to agree that the file you create should end with `.conf`. The first part of the name seems to be irrelevant. Inside that file, you create a little miniature version of the .INI-file you're overriding: {{{ [Service] TTYVTDisallocate=no }}} . One reader claims that there must not be an empty line at the end of this file -- and that if an empty line is present, systemd will ignore the file entirely. I can find no evidence that this is true, but I suppose it's possible there are some weird bugs in specific instances of systemd in the wild. As far as I can tell by testing, '''all''' of the various getty units that systemd spawns inherit this same "unit file". That is, `getty@tty1.service` and `getty@tty2.service` and so on all inherit the configuration called `getty@.service`. I don't know how or why that happens. It just does. And it's a good thing, too, because otherwise you'd have to create a whole directory + file for ''every'' getty. Obviously that would be a horrible thing. If you followed some other document that said to create `/etc/systemd/system/getty@tty1.service.d/` then it will only affect the `getty@tty1.service` unit (i.e. the getty running on /dev/tty1) and not the others. If you only wanted to avoid clearing the first console and let the others clear themselves after every login session, you could do it that way. After you've created your override, if you run `systemctl cat getty@tty1.service` again, you'll see your additions: {{{ $ systemctl cat getty@tty1.service # /lib/systemd/system/getty@.service # This file is part of systemd. # ... # /etc/systemd/system/getty@.service.d/noclear.conf [Service] TTYVTDisallocate=no }}} So, you can see all of the files that constitute the "unit file" definition, all at once. But there's one more step to go. == Re-read the file(s) == Now, you have to tell systemd to re-read the files. This step is missing in almost every other document I found. {{{ # systemctl daemon-reload }}} Of course, rebooting will also work. That's what I ended up doing the first time. == Easier Method == This can be done way easier, by using in-built systemd edit command: {{{ # systemctl edit getty@.service }}} ...this will create the correct directory and open /etc/systemd/system/getty@.service.d/override.conf (with the original config commented out for reference). Add your config as described above, save the file and do a daemon-reload ---- CategoryUnix