MACHINECTL(1)

๐Ÿ’… MACHINECTL โ€” the machinectl(1) glow-up ๐ŸŽ€

okay so bestie, welcome to the machinectl page โ€” that's the manual for the machinectl command, part of the systemd fam. grab a snack, this one's a whole journey โœจ


๐ŸŒธ NAME ๐ŸŒธ

machinectl โ€” literally the remote control for the systemd machine manager. that's it. that's the vibe. ๐Ÿ‘‘


โœจ SYNOPSIS โœจ

machinectl [OPTIONS...] {COMMAND} [NAME...]

๐Ÿฆ‹ DESCRIPTION ๐Ÿฆ‹

so machinectl is your girl for poking at and steering the state of the systemd(1) virtual machine and container registration manager โ€” that's systemd-machined.service(8) if you're being formal about it. ๐Ÿ’…

you can use machinectl to run operations on machines and images. and "machine" here means a running instance of any of these:

  • Virtual Machines (VMs) โ€” they virtualize hardware so they can run full operating system (OS) instances (their own kernels and everything) inside a virtualized environment sitting on top of the host OS.
  • Containers โ€” these share the hardware and the OS kernel with the host OS, so they run OS userspace instances on top of the host OS instead.
  • The host system itself โ€” yes, the machine you're literally already on. main character energy. ๐Ÿ˜Œ

machines get identified by names, and those names follow the exact same rules as UNIX and DNS hostnames. more on that below, iykyk.

machines are instantiated from disk or file system images, and those images frequently โ€” but not necessarily, no cap โ€” carry the same name as the machines running off them. and an "image" can be:

  • a directory tree containing an OS, top-level dirs like /usr/, /etc/, and so on included.
  • a btrfs subvolume containing an OS tree โ€” basically like a regular directory tree but btrfs-flavored.
  • a binary "raw" disk image file packing MBR or GPT partition tables plus Linux file systems.
  • similarly, a block device packing MBR or GPT partition tables plus file systems.
  • the file system tree of the host OS itself. ๐Ÿซถ

images can be downloaded, imported and exported via the importctl(1) tool. slay.


๐Ÿ”ฅ COMMANDS ๐Ÿ”ฅ

the following commands are understood, bestie. buckle up:

๐ŸŽ€ Machine Commands ๐ŸŽ€

list

lists the currently running (online) virtual machines and containers. if you wanna enumerate machine images that can be started instead, use list-images (it's further down). note that this command hides the special ".host" machine by default โ€” use the --all switch to show it. ๐Ÿ™ˆ

Added in version 206.

status NAME...

shows runtime status info about one or more virtual machines and containers, followed by the most recent log data from the journal. this one is built for human-readable output. if you're hunting for computer-parsable output, use show instead โ€” status is not that girl for parsing. also heads up: the log data shown is reported by the virtual machine or container manager, and it frequently contains console output of the machine, but not necessarily the journal contents of the machine itself. ๐Ÿ˜ญ

Added in version 206.

show [NAME...]

shows properties of one or more registered virtual machines or containers โ€” or of the manager itself. no argument specified? then you get the manager's properties. a NAME specified? then you get that virtual machine's or container's properties. by default empty properties are suppressed โ€” use --all to show those too. and to pick exactly which properties to show, use --property=. this command is the one you reach for whenever computer-parsable output is required, and it does not print the control group tree or journal entries. use status if you want the formatted human-readable glow. โœจ

Added in version 206.

start NAME...

starts a container as a system service, using systemd-nspawn(1). this starts systemd-nspawn@.service, instantiated for the machine name you gave, similar to what systemctl start does on the service name. systemd-nspawn looks for a container image by the specified name in /var/lib/machines/ (and other search paths, see below) and runs it. use list-images (below, bestie) for listing available container images to start. ๐Ÿ’–

note that systemd-machined.service(8) also interfaces with a whole variety of other container and VM managers โ€” systemd-nspawn is just one implementation of it. most of the commands available in machinectl may be used on containers or VMs controlled by other managers, not just systemd-nspawn. starting VMs and container images on those managers requires manager-specific tools though, so like, don't come for machinectl about it. ๐Ÿ™ˆ

also: to interactively start a container on the command line with full access to the container's console, please invoke systemd-nspawn directly. and to stop a running container, use machinectl poweroff.

Added in version 219.

login [NAME]

opens an interactive terminal login session in a container or on the local host. if you supply an argument, it refers to the container machine to connect to. if none is specified, or the container name is specified as the empty string, or the special machine name ".host" (see below) is specified, then the connection is made to the local host instead. this creates a TTY connection to a specific container or the local host and asks for the execution of a getty on it. note that this is only supported for containers running systemd(1) as init system. โœจ

this command opens a full login prompt on the container or the local host, which then asks for username and password. use shell (see below) or systemd-run(1) with the --machine= switch to directly invoke a single command, either interactively or in the background. ๐Ÿซถ

Added in version 209.

shell [[NAME@]NAME [PATH [ARGUMENTS...]]]

opens an interactive shell session in a container or on the local host. the first argument refers to the container machine to connect to. if none is specified, or the machine name is specified as the empty string, or the special machine name ".host" (see below) is specified, the connection is made to the local host instead. this works similarly to login, but it immediately invokes a user process. ๐Ÿ’…

this command runs the specified executable with the specified arguments โ€” or the default shell for the user if none is specified, or /bin/sh if no default shell is found. by default, --uid=, or by prefixing the machine name with a username and an "@" character, a different user may be selected. use --setenv= to set environment variables for the executed process.

note that machinectl shell does not propagate the exit code/status of the invoked shell process. use systemd-run instead if that information is required (see below). ๐Ÿ˜ญ

using the shell command without arguments (so, invoking the executed shell or command on the local host) is in many ways similar to a su(1) session โ€” but, unlike su, it completely isolates the new session from the originating session, so that it shares no process or session properties and is in a clean well-defined state. it gets tracked in a new utmp, login, audit, security, and keyring sessions, and will not inherit any environment variables or resource limits, among other properties. iconic behavior honestly. ๐Ÿ‘‘

note that systemd-run(1) with its --machine= switch may be used in place of the machinectl shell command, and it allows non-interactive operation, more detailed and low-level configuration of the invoked unit, as well as access to runtime and exit code/status information of the invoked shell process. in particular, use systemd-run's --wait switch to propagate exit status information of the invoked process. use systemd-run's --pty switch to acquire an interactive shell, similarly to machinectl shell. in general, systemd-run is preferable for scripting purposes. however โ€” and this is the important part โ€” note that systemd-run might require higher privileges than machinectl shell. โš ๏ธ

Added in version 225.

enable NAME..., disable NAME...

enables or disables a container as a system service to start at system boot, using systemd-nspawn(1). this enables or disables systemd-nspawn@.service, instantiated for the specified machine name, similarly to the effect of systemctl enable or systemctl disable on the service name. ๐ŸŽ€

this command implicitly reloads the system manager configuration after completing the operation. note that this command does not implicitly start or power off the containers that are being operated on. if that's what you want, combine the command with the --now switch. ๐Ÿ”ฅ

Added in version 219.

poweroff NAME...

powers off one or more machines. for VMs managed by systemd-vmspawn(1), this sends an ACPI powerdown request via QMP. for containers, this sends SIGRTMIN+4 to the container's init process, which causes systemd-compatible init systems to shut down cleanly. ๐Ÿ’€

this operation does not work on containers that don't run a systemd(1)-compatible init system โ€” like sysvinit, for example. use stop as an alias for poweroff. and use terminate (see below) to immediately terminate a machine without cleanly shutting it down, if you're feeling feral.

Added in version 212.

reboot NAME...

reboots one or more machines. for VMs managed by systemd-vmspawn(1), this sends a system reset request via QMP. for containers, this sends SIGINT to the container's init process, which is roughly equivalent to pressing Ctrl+Alt+Del on a non-containerized system, and is compatible with containers running any system manager. use restart as alias for reboot. ๐ŸŒˆ

Added in version 209.

pause NAME...

pauses one or more machines. for VMs managed by systemd-vmspawn(1), this freezes vCPU execution at the hypervisor level โ€” the guest operating system is not notified and does not observe an ACPI suspend. from the guest's perspective, time simply stops until the machine is resumed with resume. time freeze, no cap. ๐Ÿงš

Added in version 261.

resume NAME...

resumes one or more previously paused machines. this restarts execution after a pause. welcome back bestie ๐Ÿฆ‹

Added in version 261.

terminate NAME...

immediately terminates a virtual machine or container, without cleanly shutting it down. this kills all processes of the virtual machine or container and deallocates all resources attached to that instance. brutal. use poweroff to issue a clean shutdown request instead. ๐Ÿ’€

Added in version 206.

kill NAME...

sends a signal to one or more processes of the virtual machine or container. and to be clear: that means processes as seen by the host, not the processes inside the virtual machine or container. use --kill-whom= to select which process to kill. use --signal= to select the signal to send. ๐ŸŽฏ

Added in version 206.

bind NAME PATH [PATH]

Bestie, this is how you yeet a file or directory from your host straight into the container. ๐Ÿ’… First PATH = the source file or directory on the host. Second PATH = the destination file or directory in the container.

Omit that second path? Cool, the destination inside the container just mirrors the source path on the host. Easy.

  • Pair it with --read-only and you get a read-only bind mount (no take-backsies, no writes, just vibes).
  • Pair it with --mkdir and the destination path gets created first, before the mount lands. ๐ŸŽ€
Heads up, bestie: this is currently only supported for systemd-nspawn(1) containers, and only if user namespacing (--private-users) is not in use. That's the vibe check, no cap.

It supports bind mounting directories, regular files, device nodes, AF_UNIX socket nodes, and FIFOs. Literally the whole squad. ๐Ÿซถ

Added in version 219.


bind-volume NAME SPEC

Okay so this one goes and grabs a storage volume from a storagectl(1) provider and attaches it to the running machine. Obsessed. โœจ

SPEC is a string shaped like "PROVIDER:VOLUME[:CONFIG][:K=V,...]" โ€” the grammar is identical to the --bind-volume= argument of systemd-vmspawn(1). Same energy, fr fr.

The attached volume gets identified by the name "PROVIDER:VOLUME", and you can detach it at runtime with unbind-volume (see below, queen ๐Ÿ‘‘).

Currently only supported for systemd-vmspawn machines that expose an io.systemd.MachineInstance control socket.

Added in version 261.


unbind-volume NAME STORAGE-NAME

Detaches a storage volume from the running machine. STORAGE-NAME is that "PROVIDER:VOLUME" identifier you specified back at bind-volume time. ๐Ÿฆ‹

Red flag moment: volumes attached at machine startup (like, say, via --bind-volume= on systemd-vmspawn(1)) cannot be detached โ€” that'll fail with io.systemd.MachineInstance.StorageImmutable. No cap, it's immutable, that's literally the name.

Added in version 261.


copy-to NAME PATH [PATH] --force

Copies files or directories from the host system into a running container. Takes a container name, then the source path on the host, then the destination path in the container. If you skip the destination path, it uses the same one as the source. ๐Ÿ’–

Ownership tea ๐Ÿต: if host and container share the same user and group namespace, file ownership by numeric user ID and group ID is preserved for the copy. If they don't share it, everything in the copy ends up owned by the root user and group (UID/GID 0). Simple as that.

Added in version 219.


copy-from NAME PATH [PATH] --force

The mirror image, bestie: copies files or directories from a container into the host system. Container name first, then the source path in the container, then the destination path on the host. Destination omitted? Same as the source path. ๐ŸŒธ

Same ownership rules: shared user and group namespace means numeric user ID and group ID ownership is preserved; otherwise all files and directories in the copy are owned by root, UID/GID 0. ๐Ÿ’€

Added in version 219.


๐ŸŽ€ Image Commands ๐ŸŽ€

list-images

Shows you a list of the locally installed container and VM images โ€” it enumerates all raw disk images plus container directories and subvolumes in /var/lib/machines/ (and other search paths, see below ๐Ÿ‘€).

Then use start (above) to run a container off one of the listed images. Iconic workflow, honestly.

By default, containers whose name begins with a dot (.) are not shown. Want to see those too? Specify --all.

Also note: a special image .host always implicitly exists and refers to the image the host itself is booted from. She's always there, main character energy. ๐Ÿ‘‘

Added in version 219.


image-status [NAME...]

Shows terse status info about one or more container or VM images. This one is for human-readable output, so it's giving pretty printer.

Use show-image (see below) if you need computer-parsable output instead. iykyk.

Added in version 219.


show-image [NAME...]

Shows properties of one or more registered virtual machine or container images โ€” or of the manager itself. If no argument is given, you get the manager's properties. If you pass a NAME, you get that virtual machine's or container image's properties.

  • By default, empty properties are suppressed. Use --all to show those too.
  • Want to pick exactly which properties to show? Use --property=.

This command is for when you need computer-parsable output. If you're looking for formatted human-readable output, use image-status. Don't mix them up, bestie. โœจ

Added in version 219.


edit NAME|FILE

Edits the settings file of the specified machines. For the format of the settings file, refer to systemd.nspawn(5). ๐Ÿ“

If an existing settings file for the given machine can't be found, edit automatically creates a new settings file from scratch under /etc/systemd/nspawn/. She'll just make one, no drama.

Added in version 254.


cat NAME|FILE

Shows the settings file of the specified machines. That's it, that's the whole command. Lowkey a vibe. ๐Ÿฑ

Added in version 254.


clone NAME NAME

Clones a container or VM image. First argument = the name of the image to clone, second = the name of the newly cloned image. ๐Ÿฆ‹

Note that plain directory container images are cloned into btrfs subvolume images with this command, if the underlying file system supports it.
Also note: cloning a container or VM image is optimized for file systems that support copy-on-write, and might not be efficient on others, due to file system limitations. File system limits are so rude. ๐Ÿ˜ญ

โš ๏ธ Real talk: this command leaves hostname, machine ID and all other settings that could identify the instance unmodified. So the original image and the cloned copy share these credentials, and you might need to manually change them in the copy. Fr fr, go fix that.

Combined with --read-only? You get a read-only cloned image.

Added in version 219.


rename NAME NAME

Renames a container or VM image. First argument = the name of the image to rename, second = the new name of the image. Glow-up achieved. ๐Ÿ’…

Added in version 219.


read-only NAME [BOOL]

Marks โ€” or unmarks โ€” a container or VM image read-only. Takes a VM or container image name, followed by a boolean. ๐ŸŽ€

If you omit the boolean, positive is implied, i.e. the image is marked read-only. Silence = yes in this house.

Added in version 219.


remove NAME...

Removes one or more container or VM images. ๐Ÿ—‘๏ธ

The special image .host, which refers to the host's own directory tree, may not be removed. She's protected. Do not even try it.

Added in version 219.


set-limit [NAME] BYTES

Sets the maximum size in bytes that a specific container or VM image โ€” or all images โ€” may grow up to on disk (disk quota).

Takes either one or two parameters:

  1. The first, optional parameter is a container or VM image name. If specified, the size limit of that image is changed. If omitted, the overall size limit of the sum of all images stored locally is changed.
  2. The final argument specifies the size limit in bytes, possibly suffixed by the usual K, M, G, T units. If you want the size limit disabled, specify - as the size.
Note that per-container size limits are only supported on btrfs file systems. Everyone else, sorry bestie. ๐Ÿฅฒ

Added in version 220.


clean

Removes hidden VM or container images (or all of them). This command removes all hidden machine images from /var/lib/machines/, i.e. those whose name begins with a dot. ๐ŸŒˆ

Want to see the full list, hidden ones included? Use machinectl list-images --all.

  • Combined with the --all switch, it removes all images, not just hidden ones. This command effectively empties /var/lib/machines/. Like, fully.

A lil lore drop for you ๐Ÿ“: commands such as importctl pull-tar or importctl pull-raw usually create hidden, read-only, unmodified machine images from the downloaded image first, before cloning a writable working copy of it โ€” all so you don't get duplicate downloads when an image gets reused multiple times. Use machinectl clean to remove old, hidden images created this way. She's the cleanup queen.

Added in version 230.

โœจ OPTIONS โœจ

okay so here's the whole option buffet, bestie โ€” every single one is here, nothing skipped, you're welcome ๐Ÿ’…

  • -p, --property= โ€” when you're showing machine or image properties, this limits the output to only the properties you name in the argument. Don't specify it? Then literally all the set properties show up. The argument is a property name, like "Name". Specify it more than once and you get all the properties with all those names. โœจ Added in version 206.
  • --value โ€” when printing properties with show, this prints only the value and skips the property name and the = sign. Clean, minimal, iconic. ๐Ÿ’– Added in version 230.
  • -P โ€” this is exactly equivalent to --value --property=, i.e. it shows the value of the property without the property name or =. > heads up bestie: using -P even once will also affect all properties listed with -p/--property=. ๐Ÿซถ Added in version 256.
  • -a, --all โ€” three whole moods in one flag:
    • when showing machine or image properties, show all of them regardless of whether they're set or not;
    • when listing VM or container images, don't suppress images that start with a dot character (".");
    • when cleaning VM or container images, remove all images, not just the hidden ones. ๐Ÿ‘‘ Added in version 206.
  • -l, --full โ€” don't ellipsize process tree entries or the table. This implies --max-addresses=full. No more ... jumping out at you ๐Ÿ˜ญ Added in version 206.
  • --kill-whom= โ€” when used with kill, this picks which processes to kill. Has to be one of leader, supervisor, or all โ€” so either only the leader process of the machine, the supervisor process of the machine, or every process of the machine. If you omit it, it defaults to all. ๐Ÿ’€ Added in version 206.
  • -s, --signal= โ€” when used with kill, this picks which signal gets sent to the selected processes. Has to be one of the well-known signal specifiers like SIGTERM, SIGINT or SIGSTOP. If you omit it, it defaults to SIGTERM. ๐ŸŽ€ The special value "help" lists the known values and the program exits immediately, and the special value "list" lists known values along with the numerical signal numbers and the program exits immediately.
  • --uid= โ€” when used with the shell command, this chooses the user ID to open the interactive shell session as. If the argument to the shell command also specifies a user name, this option gets ignored. And if no name is specified either way, "root" is used by default. > note: this switch is not supported for the login command (see below). ๐ŸŒธ Added in version 225.
  • -E NAME[=VALUE], --setenv=NAME[=VALUE] โ€” when used with the shell command, this sets an environment variable for the executed shell. You can use it more than once to set multiple variables. When = and VALUE are omitted, the value of the variable with the same name in the program environment is used. ๐Ÿฆ‹ > note: this option is not supported for the login command. Added in version 230.
  • --mkdir โ€” when used with bind, this creates the destination file or directory before applying the bind mount. > and yes, even though the name sounds like it's only for directories, it also creates the destination file node to mount over if the object you're mounting isn't a directory but a regular file, device node, socket or FIFO. So the name is a little bit of a lie, but she still serves ๐Ÿ’… Added in version 219.
  • --read-only โ€” two vibes: when used with bind, it creates a read-only bind mount; when used with clone, a read-only container or VM image is created. ๐Ÿ”ฅ Added in version 219.
  • -n, --lines= โ€” when used with status, this controls the number of journal lines to show, counting from the most recent ones. Takes a positive integer argument. Defaults to 10. ๐Ÿ“ Added in version 219.
  • -o, --output= โ€” when used with status, this controls the formatting of the journal entries that are shown. For the available choices, see journalctl(1). Defaults to "short". โœจ Added in version 219.
  • --runner=nspawn|vmspawn โ€” when operating on machines, this picks whether to use systemd-nspawn(1) or systemd-vmspawn(1). By default systemd-nspawn(1) is used. ๐ŸŒˆ Added in version 256.
  • -V โ€” -V is just a shorthand for --runner=vmspawn. Periodt. โญ Added in version 256.
  • --now โ€” when used with enable or disable, the containers will also be started or powered off. And the start or poweroff operation only gets carried out when the respective enable or disable operation has actually been successful โ€” no premature celebrating ๐Ÿ™ˆ Added in version 253.
  • --force โ€” replaces the target file when copying files. ๐Ÿ’œ Added in version 219.
  • --max-addresses= โ€” when used with the list-machines command, this limits the number of IP addresses shown for every machine. Defaults to 1. You can ask for all of them with "all". If the limit is 0, the address column isn't shown at all. Otherwise, if the machine has more addresses than are being shown, "..." follows the last address. ๐Ÿ‘‘ Added in version 232.
  • -q, --quiet โ€” suppresses the extra informational output while running. Silent mode activated ๐Ÿคซ Added in version 236.
  • -H, --host= โ€” executes the operation remotely. You give it a hostname, or a username and hostname separated by "@", to connect to. The hostname may optionally be suffixed by a port ssh is listening on, separated by ":", and then a container name, separated by "/", which connects directly to a specific container on the specified host. This uses SSH to talk to the remote machine manager instance. Container names may be enumerated with machinectl -H HOST. Put IPv6 addresses in brackets. ๐Ÿงš
  • -M, --machine= โ€” connects to systemd-machined.service(8) running in a local container, so you can perform the specified operation within the container. ๐Ÿฆ‹ Added in version 235.
  • --no-pager โ€” do not pipe output into a pager. No scrolling, just โœจdump itโœจ.
  • --no-legend โ€” do not print the legend, i.e. the column headers and the footer with hints. Minimalist era.
  • --no-ask-password โ€” do not query the user for authentication for privileged operations. ๐Ÿ˜ค
  • -h, --help โ€” prints a short help text and exits. Classic.
  • --version โ€” prints a short version string and exits. Also classic. ๐Ÿ’–

๐ŸŽ€ MACHINE AND IMAGE NAMES ๐ŸŽ€

okay so machinectl is picky about names, and honestly? she has standards ๐Ÿ’… The tool operates on machines and images whose names must be chosen following strict rules.

Machine names have to be suitable for use as hostnames following a conservative subset of DNS and UNIX/Linux semantics. Specifically:

  • they must consist of one or more non-empty label strings, separated by dots;
  • no leading or trailing dots allowed, bestie;
  • no sequences of multiple dots allowed either;
  • the label strings may only consist of alphanumeric characters as well as the dash;
  • and the maximum length of a machine name is 64 characters.

There's a special machine named ".host" that refers to the running host system itself. Super useful for execution operations, or for inspecting the host system as well. > note that machinectl list will not show this special machine unless the --all switch is specified. ๐ŸŒธ

Image names โ€” the requirements are less strict, however, they must be valid UTF-8, must be suitable as file names (hence not the single or double dot, and not include a slash), and may not contain control characters. Since many operations search for an image by the name of a requested machine, it's recommended to name images in the same strict fashion as machines. iykyk ๐Ÿซถ

There's also a special image named ".host" that refers to the image of the running host system. It conceptually maps to the special ".host" machine name described above. > note that machinectl list-images will not show this special image either, unless --all is specified. โœจ


๐ŸŒˆ FILES AND DIRECTORIES ๐ŸŒˆ

Machine images are preferably stored in /var/lib/machines/, but they're also searched for in /usr/local/lib/machines/ and /usr/lib/machines/. For compatibility reasons, the directory /var/lib/container/ is searched too. ๐Ÿฆ‹

heads up: images stored below /usr/ are always considered read-only.

It's totally possible to symlink machine images from other directories into /var/lib/machines/ to make them available for control with machinectl. ๐Ÿ’ซ

note that some image operations are only supported, efficient or atomic on btrfs file systems. fr fr, filesystem matters.

Disk images are understood by systemd-nspawn(1) and machinectl in three formats:

  • A simple directory tree, containing the files and directories of the container to boot. ๐ŸŒธ
  • Subvolumes (on btrfs file systems), which are similar to the simple directories described above โ€” but they have additional benefits, such as efficient cloning and quota reporting. ๐Ÿ‘‘
  • "Raw" disk images, i.e. binary images of disks with a GPT or MBR partition table. Images of this type are regular files with the suffix ".raw". ๐Ÿ”ฅ

See systemd-nspawn(1) for more info on image formats, in particular its --directory= and --image= options.


๐Ÿ’– EXAMPLES ๐Ÿ’–

Example 1. Download an Ubuntu RAW image, set a root password in it, start it as a service

# importctl pull-raw -mN \
      https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64-disk-kvm.img \
      jammy
# systemd-firstboot --image=/var/lib/machines/jammy.raw --prompt-root-password --force
# machinectl start jammy
# machinectl login jammy

So here's the lore, bestie: this downloads the specified .raw image and makes it available under the local name "jammy". Then a root password is set with systemd-firstboot(1). After that, the machine is started as a system service. And with the last command, a login prompt into the container is requested. she ate and left no crumbs ๐Ÿ’…


โญ EXIT STATUS โญ

On success, 0 is returned, a non-zero failure code otherwise. Simple as that. โœจ

๐ŸŒˆ ENVIRONMENT ๐ŸŒˆ

Okay bestie, env-var time โœจ These are the little knobs that tell machinectl and friends how to log, page, colour, and link stuff. No cap, every one matters ๐Ÿ’…

  • $SYSTEMD_LOG_LEVEL โ€” sets the maximum log level of emitted messages (messages with a higher log level, aka less important ones, get suppressed). It takes a comma-separated list of values. A value may be either one of (in order of decreasing importance) emerg, alert, crit, err, warning, notice, info, debug, or an integer in the range 0...7. See syslog(3) for more info. Each value may optionally be prefixed with one of console, syslog, kmsg, or journal followed by a colon to set the maximum log level for that specific log target โ€” e.g. SYSTEMD_LOG_LEVEL=debug,console:info specifies to log at debug level except when logging to the console, which should be at info level. Note that the global maximum log level takes priority over any per-target maximum log levels. ๐Ÿ‘‘
  • $SYSTEMD_LOG_COLOR โ€” a boolean. If true, messages written to the tty will be coloured according to priority. This setting is only useful when messages are written directly to the terminal, because journalctl(1) and other tools that display logs will colour messages based on the log level on their own. ๐ŸŽจ
  • $SYSTEMD_LOG_TIME โ€” a boolean. If true, console log messages will be prefixed with a timestamp. This setting is only useful when messages are written directly to the terminal or a file, because journalctl(1) and other tools that display logs will attach timestamps based on the entry metadata on their own. โฐ
  • $SYSTEMD_LOG_LOCATION โ€” a boolean. If true, messages will be prefixed with a filename and line number in the source code where the message originates. Note that the log location is often attached as metadata to journal entries anyway. Including it directly in the message text can nevertheless be convenient when debugging programs. ๐Ÿ“
  • $SYSTEMD_LOG_TID โ€” a boolean. If true, messages will be prefixed with the current numerical thread ID (TID). Note that this information is attached as metadata to journal entries anyway. Including it directly in the message text can nevertheless be convenient when debugging programs. ๐Ÿงต
  • $SYSTEMD_LOG_TARGET โ€” the destination for log messages. One of:
    • console โ€” log to the attached tty
    • console-prefixed โ€” log to the attached tty but with prefixes encoding the log level and "facility", see syslog(3)
    • kmsg โ€” log to the kernel circular log buffer
    • journal โ€” log to the journal
    • journal-or-kmsg โ€” log to the journal if available, and to kmsg otherwise
    • auto โ€” determine the appropriate log target automatically, the default
    • null โ€” disable log output
  • $SYSTEMD_LOG_RATELIMIT_KMSG โ€” whether to ratelimit kmsg or not. Takes a boolean. Defaults to "true". If disabled, systemd will not ratelimit messages written to kmsg. ๐Ÿšฆ
  • $SYSTEMD_PAGER, $PAGER โ€” pager to use when --no-pager is not given. $SYSTEMD_PAGER is used if set; otherwise $PAGER is used. If neither $SYSTEMD_PAGER nor $PAGER are set, a set of well-known pager implementations is tried in turn, including less(1) and more(1), until one is found. If no pager implementation is discovered, no pager is invoked. Setting those environment variables to an empty string or the value "cat" is equivalent to passing --no-pager.
    • Note: if $SYSTEMD_PAGERSECURE is not set, $SYSTEMD_PAGER and $PAGER can only be used to disable the pager (with "cat" or ""), and are otherwise ignored.
  • $SYSTEMD_LESS โ€” override the options passed to less (by default "FRSXMK"). Users might want to change two options in particular:
    • K โ€” this option instructs the pager to exit immediately when Ctrl+C is pressed. To allow less to handle Ctrl+C itself to switch back to the pager command prompt, unset this option. If the value of $SYSTEMD_LESS does not include "K", and the pager that is invoked is less, Ctrl+C will be ignored by the executable, and needs to be handled by the pager.
    • X โ€” this option instructs the pager to not send termcap initialization and deinitialization strings to the terminal. It is set by default to allow command output to remain visible in the terminal even after the pager exits. Nevertheless, this prevents some pager functionality from working, in particular paged output cannot be scrolled with the mouse. ๐Ÿ–ฑ๏ธ

Note that setting the regular $LESS environment variable has no effect for less invocations by systemd tools. See less(1) for more discussion.

  • $SYSTEMD_LESSCHARSET โ€” override the charset passed to less (by default "utf-8", if the invoking terminal is determined to be UTF-8 compatible). Note that setting the regular $LESSCHARSET environment variable has no effect for less invocations by systemd tools. ๐Ÿˆถ
  • $SYSTEMD_PAGERSECURE โ€” the security-boundary one, bestie, so listen up ๐Ÿšจ Common pager commands like less(1), in addition to "paging", i.e. scrolling through the output, support opening of or writing to other files and running arbitrary shell commands. When commands are invoked with elevated privileges, for example under sudo(8) or pkexec(1), the pager becomes a security boundary. Care must be taken that only programs with strictly limited functionality are used as pagers, and unintended interactive features like opening or creation of new files or starting of subprocesses are not allowed. "Secure mode" for the pager may be enabled as described below, if the pager supports that (most pagers are not written in a way that takes this into consideration). It is recommended to either explicitly enable "secure mode" or to completely disable the pager using --no-pager or PAGER=cat when allowing untrusted users to execute commands with elevated privileges.
    • This option takes a boolean argument. When set to true, the "secure mode" of the pager is enabled. In "secure mode", LESSSECURE=1 will be set when invoking the pager, which instructs the pager to disable commands that open or create new files or start new subprocesses. Currently only less(1) is known to understand this variable and implement "secure mode".
    • When set to false, no limitation is placed on the pager. Setting SYSTEMD_PAGERSECURE=0 or not removing it from the inherited environment may allow the user to invoke arbitrary commands.
    • When $SYSTEMD_PAGERSECURE is not set, systemd tools attempt to automatically figure out if "secure mode" should be enabled and whether the pager supports it. "Secure mode" is enabled if the effective UID is not the same as the owner of the login session, see geteuid(2) and sd_pid_get_owner_uid(3), or when running under sudo(8) or similar tools ($SUDO_UID is set [1]). In those cases, SYSTEMD_PAGERSECURE=1 will be set and pagers which are not known to implement "secure mode" will not be used at all. Note that this autodetection only covers the most common mechanisms to elevate privileges and is intended as convenience. It is recommended to explicitly set $SYSTEMD_PAGERSECURE or disable the pager.
    • Note: if the $SYSTEMD_PAGER or $PAGER variables are to be honoured, other than to disable the pager, $SYSTEMD_PAGERSECURE must be set too.
  • $SYSTEMD_COLORS โ€” takes a boolean argument, or a special value. By default (unset), systemd and related utilities will use colors in their output if possible. If $COLORTERM is set to "truecolor" or "24bit", 24-bit colors will be enabled, 256 colors otherwise, unless $NO_COLOR or $TERM indicates colors are disabled.
    • true โ€” same as unset, except that $NO_COLOR is ignored.
    • false โ€” the output will be monochrome.
    • "16", "256", "24bit" โ€” always use the base 16 ANSI colors, 256 colors, or 24 bit color, respectively.
    • "auto-16", "auto-256", "auto-24bit" โ€” use the given quantity of colours, subject to $TERM, and what the console is connected to.
  • $SYSTEMD_URLIFY โ€” the value must be a boolean. Controls whether clickable links should be generated in the output for terminal emulators supporting this. This can be specified to override the decision that systemd makes based on $TERM and other conditions. ๐Ÿ”—

๐Ÿ’– SEE ALSO ๐Ÿ’–

Your next deep-dive rotation, in original order: systemd(1), systemd-machined.service(8), systemd-nspawn(1), systemd.special(7), importctl(1), tar(1), xz(1), gzip(1), bzip2(1), zstd(1). Slay, go read โœจ

๐ŸŽ€ NOTES ๐ŸŽ€

  1. It is recommended for other tools to set and check $SUDO_UID as appropriate, treating it as a common interface.

Okay bestie, that's the whole MACHINECTL(1) vibe ๐Ÿ’– Source/version: systemd 261.3; man page: MACHINECTL(1); date: not listed on this footer, so we're not inventing one ๐Ÿ™ˆ mwah ๐Ÿ’‹

๐Ÿ“ฆ where this page comes from