Score:7

How can I have Ubuntu display the output of a commad in the login screen on Ubuntu Server?

cn flag

I've found this question, but it talks about a version of Ubuntu with a GUI. I'm referring to Ubuntu Server, so no GUI. I've also found this question, but it doesn't look like it will display the output of a command, but instead only static text.

The Ubuntu Server login screen looks something like this:

Ubuntu 22.04 LTS mycomputer tty1
mycomputer login:

However, I'd like it to run a command (either as root or under my account - you can pick), and then I'd like it to print the output of the command before giving the login prompt.

For example, if my command was echo Hello world!, I'd like it to look like this:

Hello world!
Ubuntu 22.04 LTS mycomputer tty1
mycomputer login:

Or this would be fine too:

Ubuntu 22.04 LTS mycomputer tty1
Hello world!
mycomputer login:

While it was in my example, the output of my command can change - it isn't gaurenteed to be the same each time, so I can't hardcode the output of the command into a file (in my case, the command is hostname -i, which prints the IP address).

I often need to check the IP of a machine, and it would be easier if I didn't have to sign in to check it. For the sake of the question, assume this is a personal server on a home network, and so leaking the IP address isn't a concern.

How can I display the output of a command in the command-line login screen?

noisefloor avatar
ec flag
I think there is a mistake in thinking on your end - the login prompt is there once your machine booted, it is just waiting to be connected to. Thus, what you intend to do equals to running a script at boot time -> use a systemd Service Unit. You can run a script after logging in with a systemd User Unit. However, they are both executed in the background, thus any output goes into the logs of journald as a standard.
Raffa avatar
jp flag
Related: [How to run a bash script while Ubuntu is starting up on tty](https://askubuntu.com/q/1319352)
Score:9
hr flag

As you already discovered, the appearance of the server login screen is controlled by a getty program - by default, that's agetty on Ubuntu. The agetty program reads from a file named /etc/issue - and since agetty version 2.35, optionally from files in /etc/issue.d. From man agetty:

ISSUE FILES

   The default issue file is /etc/issue. If the file exists, then agetty
   also checks for /etc/issue.d directory. The directory is optional
   extension to the default issue file and content of the directory is
   printed after /etc/issue content. If the /etc/issue does not exist,
   then the directory is ignored. All files with .issue extension from the
   directory are printed in version-sort order. The directory can be used
   to maintain 3rd-party messages independently on the primary system
   /etc/issue file.

So the procedure is:

  1. create the /etc/issue.d/ directory if it does not already exist

  2. create a script to run your command and write its output to a .issue file in that directory

  3. modify the template getty@.service to execute the script via its ExecStartPre

Proof of concept (tested on a 22.04 desktop VM):

sudo mkdir -p /etc/issue.d

sudo nano /usr/local/sbin/issue

with content

    #!/bin/sh

    /bin/date +'Hello world @ %c' > /etc/issue.d/50hello.issue

(the date command so we can confirm the content is generated dynamically).

sudo chmod +x /usr/local/sbin/issue

Now make a local copy of the agetty@ service file:

sudo cp --no-clobber /lib/systemd/system/getty@.service /etc/systemd/system

Edit the copy with your favorite text editor and add the ExecStartPre instruction:

[Service]
# the VT is cleared by TTYVTDisallocate
# The '-o' option value tells agetty to replace 'login' arguments with an
# option to preserve environment (-p), followed by '--' for safety, and then
# the entered username.

ExecStartPre=-/usr/local/sbin/issue
ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear %I $TERM
.
.
etc.

The leading "-" stops the whole unit from failing if your ExecStartPre command fails from some reason.

It should work right away if you switch to a new TTY - to see the effect in an existing TTY you may need to restart the instance service ex. sudo systemctl restart getty@tty2.service

tty2

muru avatar
us flag
I wonder if you even need the issue file. Just running the command whose output is to be shown in `ExecStartPre` should work, right? It should show the output in the TTY? Or does it go to the journal? Or does getty clear the output?
hr flag
@muru that's a good thought - I'll give it a try
in flag
FWIW I tried (Kubuntu 22.10) putting `$(host -I)` (the switch is capital-i) in /etc/issue but it was echoed (printed without processing) instead of being executed. Per my answer, `\4` worked for all TTY I'd not visited since boot.
in flag
Note files in `issue.d/` need to have an extension like `05-your-filename.issue`, they don't get used otherwise!
Score:2
tn flag

After login motd (not exactly what is needed):

# cat /etc/update-motd.d/00-update
#!/bin/bash
echo
echo "Server IP: $(hostname -i)"

Don't forget

chmod +x /etc/update-motd.d/00-update

Doc:

man update-motd
in flag
I've never used it, but aren't `motd` shown after login, eg as stated here, https://manpages.ubuntu.com/manpages/trusty/en/man5/motd.5.html . OP wants to modify the login prompt itself. Maybe the systemd motd can show before login?? I skimmed and didn't see anything in the man page you linked.
Gilles Quenot avatar
tn flag
If he want to change the motd, just `printf '\n%s\n' "Server IP: $(hostname -i)" > /etc/motd`
GChuf avatar
in flag
As mentioned - motd displays **after** login. This is not the correct answer.
Gilles Quenot avatar
tn flag
Post edited accordingly
Score:1
in flag

Pre-login the banner is provided by /etc/issue.

This file by default for me on Kubuntu 22.10 contains a single line:

Ubuntu 22.10 \n \l

The \char look like escape codes but they're not what you expect, the man issue output has your back here:

The issue files may contain certain escape codes to display the system name, date, time et cetera. All escape codes consist of a backslash (\)
       immediately followed by one of the characters listed below.

       **4 or 4{interface}**
           Insert the IPv4 address of the specified network interface (for example: \4{eth0}). If the interface argument is not specified, then select
           the first fully configured (UP, non-LOCALBACK, RUNNING) interface. If no configured interface is found, fall back to the IP address of the
           machine’s hostname.

       **6 or 6{interface}**
           The same as \4 but for IPv6.

So, adding "\4" (without quotes) to /etc/issue will print the IP address. Neat. Note that it only works on TTY that you haven't yet entered [since the last reboot?]; you can logout of a TTY and it resets the issue banner. Also \n is not a carriage return, whitespace is preserved, but instead is the "nodename" which for me is the same as the output from host.

This is only for TTY's, if you want a banner for remote login then you'll need to look at the program that provides the remote shell, such as SSH (see sshd_config file).

===

Edit: I also had a file called issue.net, but that seems to be vestigial (old and unworking). /etc/issue is from the base-files package. I did not have an /etc/issue.d directory but making one, adding a file with extension ".issue" works. I didn't test extensively; apt-file search "/issue.d" returns only the package freedombox (which I've never heard of).

in flag
Ah, just saw @steeldriver's answer after I researched this. I think I cover some different details so I'll leave it in place.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.