A NOTE has been added to this issue. ====================================================================== https://www.austingroupbugs.net/view.php?id=1915 ====================================================================== Reported By: steffen Assigned To: ====================================================================== Project: 1003.1(2016/18)/Issue7+TC2 Issue ID: 1915 Category: Shell and Utilities Type: Clarification Requested Severity: Editorial Priority: normal Status: New Name: steffen Organization: User Reference: Section: 2.5.2 Page Number: 2479 Line Number: 80382 Interp Status: --- Final Accepted Text: ====================================================================== Date Submitted: 2025-03-17 19:17 UTC Last Modified: 2025-03-18 10:31 UTC ====================================================================== Summary: clarification of 2.6.5 field splitting of 2.5.2 special parameter $* ======================================================================
---------------------------------------------------------------------- (0007122) geoffclare (manager) - 2025-03-18 10:31 https://www.austingroupbugs.net/view.php?id=1915#c7122 ---------------------------------------------------------------------- The following is a copy of the Description, with the "code" tags changed to "pre". --------------------------------------------------------------------------------------------------------------- I was implementing a shell expression parser. It was impossible to generate $* splitting compatible compatible with bash, NetBSD sh and NetBSD ksh. The standard defines (p. 2479, lines 80382 ff.) <blockquote> [.]one field for each positional parameter that is set. When the expansion occurs in a context where field splitting will be performed, any empty fields may be discarded and each of the non-empty fields shall be further split as described in Section 2.6.5. </blockquote> So in an example <pre> a() { echo $#,1="$1"/$1,2="$2"/$2,3="$3"/$3,4="$4" echo $#,'*'="$*"/$*, } set -- '' 'a' '' for f in ' ' '' : ': ' ' :'; do IFS=$f ; echo "$*"$* $*; a "$*"$* $*;unset IFS done </pre> my parser was en par with the mentioned shells except for <pre> --- .1 2025-03-15 23:38:31.359307576 +0100 +++ .2 2025-03-15 23:38:32.715974215 +0100 @@ -6,10 +6,10 @@ a a a$ 3,*=aaa/a a a,$ :a: a a$ 4,1=:a:/ a ,2=a/a,3=/,4=a$ -4,*=:a::a::a/ a a a,$ +4,*=:a::a::a/ a a a,$ :a: a a$ 4,1=:a:/ a ,2=a/a,3=/,4=a$ -4,*=:a::a::a/ a a a,$ +4,*=:a::a::a/ a a a,$ a a a$ 3,1= a / a ,2=a/a,3=a/a,4=$ 3,*= a a a/ a a a,$ </pre> After that many months i did not give up and wrote to kre@ and on the bash-bug list: <pre> By the very meaning of this [POSIX words] the fields are split individually, *first*. This is exactly what i do. Hence echo $#,1="$1"/$1,2="$2"/$2,3="$3"/$3,4="$4" -> 4,1=:a:/ a ,2=a/a,3=/,4=a becomes :a: -> '' + a a -> a '' -> discarded (but remembered as it separates fields) a -> a becomes, with IFS=:, when actually creating the argument :a:a::a becomes the actual argument < a a a> </pre> Long story short (initial typo corrected): <pre> + /* In order to be compatible with bash, NetBSD sh and NetBSD ksh, at minimum, we need to + * deviate from POSIX standardized behaviour, and field split the quoted variant instead! + * This applies to $@ as well as $* */ + if(*spcp->spc_ifs != '\0' && !su_cs_is_space(*spcp->spc_ifs)){ + cp = n_var_vlook(n_star, TRU1); + goto jfs_split; + } + + /* In all other cases individually field split the expanded parameters */ </pre> Ie, the mentioned shells use the *quoted* variant of $* to perform the expansion in the mentioned case. This seems to be the case for multiple decades, if not ever. Issue History Date Modified Username Field Change ====================================================================== 2025-03-17 19:17 steffen New Issue 2025-03-18 10:31 geoffclare Note Added: 0007122 ======================================================================
