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.