]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
ansi-color: new option SYSTEMD_COLORS=auto-16/auto-256/auto-24bit (#40303)
authorPeter Oliver <github.com@mavit.org.uk>
Fri, 23 Jan 2026 12:54:31 +0000 (12:54 +0000)
committerGitHub <noreply@github.com>
Fri, 23 Jan 2026 12:54:31 +0000 (13:54 +0100)
Setting SYSTEMD_COLORS=auto-16 is like SYSTEMD_COLORS=16 if output is to
a non-dumb TTY, and like SYSTEMD_COLORS=no otherwise.

Relates to
https://github.com/systemd/systemd/issues/15498#issuecomment-1682025186

NEWS
man/common-variables.xml
src/basic/ansi-color.c
src/basic/ansi-color.h
src/test/test-terminal-util.c

diff --git a/NEWS b/NEWS
index db1f32f73c531e9a1426db93a4188d7971e5cf66..c7c45487282ace53a30c48c6583212537e6f512e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -31,6 +31,12 @@ CHANGES WITH 260 in spe:
           rather than the first, to keep these options coherent with other
           unit settings.
 
+        Changes in other components:
+
+        * New options SYSTEMD_COLORS=auto-16 and SYSTEMD_COLORS=auto-256, which
+          are like SYSTEMD_COLORS=16 and SYSTEMD_COLORS=256 respectively when
+          output is to a non-dumb TTY, and like SYSTEMD_COLORS=no otherwise.
+
 CHANGES WITH 259:
 
         Announcements of Future Feature Removals and Incompatible Changes:
index 991946f60df1843a5281a54135f02ecd4d48b4e1..93f18d453e55e6a61e7b59d62e38b60eab3cb3e5 100644 (file)
     <varlistentry id='colors'>
       <term><varname>$SYSTEMD_COLORS</varname></term>
 
-      <listitem><para>Takes a boolean argument. When true, <command>systemd</command> and related utilities
-      will use colors in their output, otherwise the output will be monochrome. Additionally, the variable can
-      take one of the following special values: <literal>16</literal>, <literal>256</literal> to restrict the use
-      of colors to the base 16 or 256 ANSI colors, respectively. This can be specified to override the automatic
-      decision based on <varname>$TERM</varname> and what the console is connected to.</para></listitem>
+      <listitem>
+        <para>Takes a boolean argument, or a special value.</para>
+
+        <variablelist>
+          <varlistentry>
+            <term><option>true</option></term>
+            <listitem><para>The default. <command>systemd</command> and related utilities will use colors in
+            their output if possible. Same as <literal>auto-24bit</literal> if <varname>$COLORTERM</varname>
+            is set to <literal>truecolor</literal> or <literal>24bit</literal>; same as
+            <literal>auto-256</literal> otherwise.</para></listitem>
+          </varlistentry>
+
+          <varlistentry>
+            <term><option>false</option></term>
+            <listitem><para>The output will be monochrome.</para></listitem>
+          </varlistentry>
+
+          <varlistentry>
+            <term><literal>16</literal></term>
+            <term><literal>256</literal></term>
+            <term><literal>24bit</literal></term>
+            <listitem><para>Always use the base 16 ANSI colors, 256 colors, or 24 bit color,
+            respectively.</para></listitem>
+          </varlistentry>
+
+          <varlistentry>
+            <term><literal>auto-16</literal></term>
+            <term><literal>auto-256</literal></term>
+            <term><literal>auto-24bit</literal></term>
+            <listitem><para>Use the given quantity of colours, subject to <varname>$TERM</varname>, and what
+            the console is connected to.</para></listitem>
+          </varlistentry>
+        </variablelist>
+      </listitem>
     </varlistentry>
 
     <!-- This is not documented on purpose, because it is not clear if $NO_COLOR will become supported
     <varlistentry id='no-color'>
       <term><varname>$NO_COLOR</varname></term>
 
-      <listitem><para>If set (to any value), and <varname>$SYSTEMD_COLORS</varname> is not set, equivalent to
+      <listitem><para>If set (to any value), and <varname>$SYSTEMD_COLORS</varname> is not set to
+      <literal>16</literal>, <literal>256</literal>, or <literal>24bit</literal>, equivalent to
       <option>SYSTEMD_COLORS=0</option>. See <ulink url="https://no-color.org/">no-color.org</ulink>.</para>
       </listitem>
     </varlistentry>
index af2aa296d05871ec620604e00b2125fa87c0b00a..5b04199318aaf4c52a1435e14be5bf6c2a6fd787 100644 (file)
@@ -55,7 +55,7 @@ static ColorMode get_color_mode_impl(void) {
 
         /* First, we check $SYSTEMD_COLORS, which is the explicit way to change the mode. */
         ColorMode m = parse_systemd_colors();
-        if (m >= 0)
+        if (IN_SET(m, COLOR_OFF, COLOR_16, COLOR_256, COLOR_24BIT))
                 return m;
 
         /* Next, check for the presence of $NO_COLOR; value is ignored. */
@@ -70,6 +70,13 @@ static ColorMode get_color_mode_impl(void) {
                 return COLOR_OFF;
 
         /* We failed to figure out any reason to *disable* colors. Let's see how many colors we shall use. */
+        if (m == COLOR_AUTO_16)
+                return COLOR_16;
+        if (m == COLOR_AUTO_256)
+                return COLOR_256;
+        if (m == COLOR_AUTO_24BIT)
+                return COLOR_24BIT;
+
         if (STRPTR_IN_SET(getenv("COLORTERM"),
                           "truecolor",
                           "24bit"))
@@ -93,10 +100,13 @@ ColorMode get_color_mode(void) {
 
 
 static const char* const color_mode_table[_COLOR_MODE_MAX] = {
-        [COLOR_OFF]   = "off",
-        [COLOR_16]    = "16",
-        [COLOR_256]   = "256",
-        [COLOR_24BIT] = "24bit",
+        [COLOR_OFF]        = "off",
+        [COLOR_16]         = "16",
+        [COLOR_256]        = "256",
+        [COLOR_24BIT]      = "24bit",
+        [COLOR_AUTO_16]    = "auto-16",
+        [COLOR_AUTO_256]   = "auto-256",
+        [COLOR_AUTO_24BIT] = "auto-24bit",
 };
 
 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(color_mode, ColorMode, COLOR_24BIT);
index c9348cad257deec48b7f930d7ffcd053ea190aa8..fb6b2bba0c25808e66c0aa467fbc2bc32cb97119 100644 (file)
@@ -5,10 +5,13 @@
 
 /* Limits the use of ANSI colors to a subset. */
 typedef enum ColorMode {
-        COLOR_OFF,   /* No colors, monochrome output. */
-        COLOR_16,    /* Only the base 16 colors. */
-        COLOR_256,   /* Only 256 colors. */
-        COLOR_24BIT, /* For truecolor or 24bit color support, no restriction. */
+        COLOR_OFF,        /* No colors, monochrome output. */
+        COLOR_16,         /* Only the base 16 colors. */
+        COLOR_256,        /* Only 256 colors. */
+        COLOR_24BIT,      /* For truecolor or 24bit color support, no restriction. */
+        COLOR_AUTO_16,    /* The "AUTO" modes are as the above, but subject to suitable settings for */
+        COLOR_AUTO_256,   /* the environment variables TERM and NO_COLOR. */
+        COLOR_AUTO_24BIT,
         _COLOR_MODE_MAX,
         _COLOR_MODE_INVALID = -EINVAL,
 } ColorMode;
index ae33a9aeea30675ef04b959c0ed12de928216882..d2bab189499a60881d40b307d97b093b67715c73 100644 (file)
@@ -336,9 +336,19 @@ TEST(get_color_mode) {
         test_get_color_mode_with_env("SYSTEMD_COLORS", "yes",   COLOR_24BIT);
         test_get_color_mode_with_env("SYSTEMD_COLORS", "24bit", COLOR_24BIT);
 
+        test_get_color_mode_with_env("SYSTEMD_COLORS", "auto-16",    terminal_is_dumb() ? COLOR_OFF : COLOR_16);
+        test_get_color_mode_with_env("SYSTEMD_COLORS", "auto-256",   terminal_is_dumb() ? COLOR_OFF : COLOR_256);
+        ASSERT_OK_ERRNO(setenv("COLORTERM", "truecolor", true));
+        test_get_color_mode_with_env("SYSTEMD_COLORS", "auto-24bit", terminal_is_dumb() ? COLOR_OFF : COLOR_24BIT);
+        ASSERT_OK_ERRNO(unsetenv("COLORTERM"));
+        test_get_color_mode_with_env("SYSTEMD_COLORS", "auto-24bit", terminal_is_dumb() ? COLOR_OFF : COLOR_256);
+
         ASSERT_OK_ERRNO(setenv("NO_COLOR", "1", true));
-        test_get_color_mode_with_env("SYSTEMD_COLORS", "42",      COLOR_OFF);
-        test_get_color_mode_with_env("SYSTEMD_COLORS", "invalid", COLOR_OFF);
+        test_get_color_mode_with_env("SYSTEMD_COLORS", "auto-16",    COLOR_OFF);
+        test_get_color_mode_with_env("SYSTEMD_COLORS", "auto-256",   COLOR_OFF);
+        test_get_color_mode_with_env("SYSTEMD_COLORS", "auto-24bit", COLOR_OFF);
+        test_get_color_mode_with_env("SYSTEMD_COLORS", "42",         COLOR_OFF);
+        test_get_color_mode_with_env("SYSTEMD_COLORS", "invalid",    COLOR_OFF);
         ASSERT_OK_ERRNO(unsetenv("NO_COLOR"));
         ASSERT_OK_ERRNO(unsetenv("SYSTEMD_COLORS"));