]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
basename: quote problematic names on tty
authorPádraig Brady <P@draigBrady.com>
Thu, 30 Jul 2026 20:48:22 +0000 (21:48 +0100)
committerPádraig Brady <P@draigBrady.com>
Sat, 1 Aug 2026 11:38:28 +0000 (12:38 +0100)
* doc/coreutils.texi (basename invocation): Mention $QUOTING_STYLE
is significant.
* src/basename.c (perform_basename, main): Quote output when
appropriate.
* tests/misc/basename.pl: Add a test case.
* NEWS: Mention the improvement.

NEWS
doc/coreutils.texi
src/basename.c
tests/misc/basename.pl

diff --git a/NEWS b/NEWS
index 7d17ff5e637a84785995f8201456fe3dad57075f..0667f4fddc5e08e5926393c14b3e91da427689e3 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -84,7 +84,7 @@ GNU coreutils NEWS                                    -*- outline -*-
   'install -C' will now avoid updating file metadata when the destination
   already has the appropriate ownership and permissions.
 
-  'realpath' now quotes output in shell-escape style when
+  'basename' and 'realpath' now quote output in shell-escape style when
   standard output is a terminal.  The QUOTING_STYLE environment variable
   can be used to adjust or disable the quoting.
 
index c17fda0f9b567519f98cf7bc83cc61f5a609b057..d9b6a8761f666196df90b32ec8fcd334aaa0878f 100644 (file)
@@ -14193,6 +14193,11 @@ This option implies the @option{-a} option.
 
 @end table
 
+When standard output is a terminal, output is quoted using the
+@samp{shell-escape} style.  The environment variable
+@env{QUOTING_STYLE} specifies the quoting style.  Valid quoting styles are:
+@quotingStyles
+
 @exitstatus
 
 Examples:
index 96bbb71c52c3a3fca86c2bd54c395a1ccf906a6d..4fc08643559ad4bee15a759d7068ef01622ea83d 100644 (file)
@@ -19,6 +19,7 @@
 #include <stdio.h>
 #include <sys/types.h>
 
+#include "argmatch.h"  /* argmatch($QUOTING_STYLE).  */
 #include "system.h"
 #include "quote.h"
 
@@ -27,6 +28,8 @@
 
 #define AUTHORS proper_name ("David MacKenzie")
 
+static bool quote_output;
+
 static struct option const longopts[] =
 {
   {"multiple", no_argument, NULL, 'a'},
@@ -121,7 +124,7 @@ perform_basename (char const *string, char const *suffix, idx_t suffix_len,
       && ! FILE_SYSTEM_PREFIX_LEN (name))
     remove_suffix (name, suffix, suffix_len);
 
-  fputs (name, stdout);
+  fputs (quote_output ? quoteN (name) : name, stdout);
   putchar (use_nuls ? '\0' : '\n');
   free (name);
 }
@@ -188,6 +191,18 @@ main (int argc, char **argv)
         }
     }
 
+  if (!use_nuls && 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;
+        }
+    }
+
   idx_t suffix_len = suffix ? strlen (suffix) : 0;
 
   char **file = argv + optind;
index 8188817b88ad824d9f5687d2ff44c535965e8450..98607b787833e93f390f4bd93711fb6637d88b54 100755 (executable)
@@ -62,12 +62,22 @@ my @Tests =
      ['9', qw(fs ''),      {OUT => 'fs'}],
      ['10', qw(fs/ s/),    {OUT => 'fs'}],
 
+     # QUOTING_STYLE does not affect redirected output.
+     ['q-lit', q{'d/q name'}, {ENV => 'QUOTING_STYLE=literal'},
+      {OUT => 'q name'}],
+     ['q-shell', q{'d/q name'}, {ENV => 'QUOTING_STYLE=shell-always'},
+      {OUT => 'q name'}],
+     ['q-invalid', q{'d/q name'}, {ENV => 'QUOTING_STYLE=invalid'},
+      {OUT => 'q name'}],
+
      # Exercise -z option.
      ['z0', qw(-z a),       {OUT => "a\0"}],
      ['z1', qw(--zero a),   {OUT => "a\0"}],
      ['z2', qw(-za a b),    {OUT => "a\0b\0"}],
      ['z3', qw(-z ba a),    {OUT => "b\0"}],
      ['z4', qw(-z -s a ba), {OUT => "b\0"}],
+     ['z-quote', q{-z 'q name'}, {ENV => 'QUOTING_STYLE=invalid'},
+      {OUT => "q name\0"}],
    );
 
 # Append a newline to end of each expected 'OUT' string.