On 02/08/2026 02:10, Collin Funk wrote:
Pádraig Brady <[email protected]> writes:

On 31/07/2026 18:27, Collin Funk wrote:
I haven't looked at the patches yet, but I guess 'id', 'who', etc. might
as well be changed while we are at it. User and group names can
theoretically have bytes that are invalid characters in the current
locale. In practice, if you are using non-ASCII characters you are
probably asking for trouble.
Yes good point.
Though \n and other control chars aren't allowed in practice,
so I'm leaning towards not quoting those as it's redundant.
I'll think a bit more about it.

I also considered whether it may be worth quoting output of 'env' and
'printenv', which could be made ambiguous.

E.g., in the following example only "a" is an environment variable:

     $ env -i $'a=b\nd=c' printenv
     a=b
     d=c

But, I am not sure the quoted output makes it more understandable:

     $ env -i $'a=b\nd=c' ./src/printenv
     'a=b'$'\n''d=c'

Also, if you can't trust your parent process not to insert slop into
your environment variables, you probably have larger problems.

Here was the patch I used, anyways:

diff --git a/src/printenv.c b/src/printenv.c
index c2b1c69cd..a8082b925 100644
--- a/src/printenv.c
+++ b/src/printenv.c
@@ -32,6 +32,7 @@
  #include <sys/types.h>
  #include <getopt.h>
+#include "argmatch.h" /* argmatch($QUOTING_STYLE). */
  #include "system.h"
/* Exit status for syntax errors, etc. */
@@ -44,6 +45,8 @@ enum { PRINTENV_FAILURE = 2 };
    proper_name ("David MacKenzie"), \
    proper_name ("Richard Mlynarik")
+static bool quote_output;
+
  static struct option const longopts[] =
  {
    {"null", no_argument, NULL, '0'},
@@ -107,12 +110,24 @@ main (int argc, char **argv)
          }
      }
+ if (!opt_nul_terminate_output && isatty (STDOUT_FILENO))
+    {
+      int qs = getenv_quoting_style ();
+      if (qs < 0)
+        qs = shell_escape_quoting_style;
+      if (qs != literal_quoting_style)
+        {
+          set_quoting_style (NULL, qs);
+          quote_output = true;
+        }
+    }
+
    bool ok;
    if (optind >= argc)
      {
        for (char **env = environ; *env != NULL; ++env)
          {
-          fputs (*env, stdout);
+          fputs (quote_output ? quoteN (*env) : *env, stdout);
            putchar (opt_nul_terminate_output ? '\0' : '\n');
          }
        ok = true;
@@ -137,7 +152,7 @@ main (int argc, char **argv)
                  {
                    if (*ep == '=' && *ap == '\0')
                      {
-                      fputs (ep + 1, stdout);
+                      fputs (quote_output ? quoteN (ep + 1) : ep, stdout);
                        putchar (opt_nul_terminate_output ? '\0' : '\n');
                        matched = true;
                        break;

Collin

This actually makes lots of sense.
This is a very common issue actually, one that I hit all the time.
as I have this in my .bashrc:

  # Adjust the less highlight colors
  export LESS_TERMCAP_so="$(printf 'rev\nbold\nsetaf 3\n' | tput -S)"
  export LESS_TERMCAP_se="$(tput sgr0)"

That results in messed up colors when printing my environment.

I've just realized I didn't notice that in a while,
and now I see that `set` in bash quotes output.
zsh, and ksh also quote, while dash does not.

So therefore for pragmatic reasons I do think printenv should quote on tty as 
you've done.
Also env(1) without a command prints the environment, and should also quote.

cheers,
Padraig

Reply via email to