From: Pádraig Brady
Date: Thu, 30 Jul 2026 20:48:22 +0000 (+0100)
Subject: basename: quote problematic names on tty
X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e897dfd023dad6b9173ad457fc9d9110f2403a5f;p=thirdparty%2Fcoreutils.git
basename: quote problematic names on tty
* 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.
---
diff --git a/NEWS b/NEWS
index 7d17ff5e63..0667f4fddc 100644
--- 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.
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index c17fda0f9b..d9b6a8761f 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -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:
diff --git a/src/basename.c b/src/basename.c
index 96bbb71c52..4fc0864355 100644
--- a/src/basename.c
+++ b/src/basename.c
@@ -19,6 +19,7 @@
#include
#include
+#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;
diff --git a/tests/misc/basename.pl b/tests/misc/basename.pl
index 8188817b88..98607b7878 100755
--- a/tests/misc/basename.pl
+++ b/tests/misc/basename.pl
@@ -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.