[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
$* within a here-document puts space instead of the first IFS char.
From: |
Damien ISSANCHOU |
Subject: |
$* within a here-document puts space instead of the first IFS char. |
Date: |
Sat, 17 Feb 2024 01:41:11 +0100 |
User-agent: |
Mozilla Thunderbird |
From: Damien Issanchou
To: bug-bash@gnu.org
Subject: $* within a here-document puts space instead of the first IFS char.
Configuration Information:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -g -O2
uname output: Linux AsWhite 4.19.0-20-amd64 #1 SMP Debian 4.19.235-1
(2022-03-17) x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu
Bash Version: 5.2
Patch Level: 26
Release Status: release
Description:
Hi,
When expanding $* within a here-document, bash puts a space between
each positional parameters while I would expect it to put the first
character of the IFS variable (if it contains at least one character) as
per POSIX.1-2017.
Even though the online Bash Reference manual only explicitly states
the POSIX behaviour when the expansion of the special parameter * occurs
within double-quotes, it seems that it is also implemented in other
contexts where field splitting shall not be performed such as within
here strings.
Funnily enough, the expansion of ${array[*]} does make use of the
first IFS character within a here document, making it behave more
POSIX.1-ly that $*.
Maybe bash could implement the POSIX.1 behaviour for $* within
here-documents, which would make the * special parameter and the *
"special" array subscript much more look-alike.
Best Regards,
Damien
Repeat-By:
IFS=xyz
set -- a b c
cat <<EOD
$*
EOD
outputs:
a b c
but POSIX.1-2017 expects:
axbxc
---
IFS=xyz
set -- a b c
cat <<<$*
outputs:
axbxc
as expected.
IFS=xyz
declare -a array
array=(a b c)
cat <<EOD
${array[*]}
EOD
outputs:
axbxc
as expected.
Fix:
The following change seems to implement the desired behaviour, by
treating the expansion of $* no differently within a here-document that
within double quotes.
diff -r -U 7 bash-master.orig/subst.c bash-master/subst.c
--- bash-master.orig/subst.c 2024-01-14 00:27:28.000000000 +0100
+++ bash-master/subst.c 2024-02-16 23:43:37.243819094 +0100
@@ -10358,15 +10358,15 @@
else if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES|Q_PATQUOTE))
{
/* If we have "$*" we want to make a string of the positional
parameters, separated by the first character of $IFS, and
quote the whole string, including the separators. If IFS
is unset, the parameters are separated by ' '; if $IFS is
null, the parameters are concatenated. */
- temp = (quoted & (Q_DOUBLE_QUOTES|Q_PATQUOTE)) ?
string_list_dollar_star (list, quoted, 0) : string_list (list);
+ temp = string_list_dollar_star (list, quoted, 0);
if (temp)
{
temp1 = (quoted & Q_DOUBLE_QUOTES) ? quote_string (temp)
: temp;
if (*temp == 0)
tflag |= W_HASQUOTEDNULL;
if (temp != temp1)
free (temp);
- $* within a here-document puts space instead of the first IFS char.,
Damien ISSANCHOU <=