bug-bash
[Top][All Lists]
Advanced

[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);





reply via email to

[Prev in Thread] Current Thread [Next in Thread]