Robert Elz wrote in <3946.1726671...@jacaranda.noi.kre.to>: ... || On Wed, Sep 18, 2024 at 08:05:10 +0300, Oğuz wrote: ||> It boils down to this: ||> f(){ echo $#;}; set "" "" ""; IFS=x; f $* | ||> bash, NetBSD and FreeBSD sh, and ksh88 all agree and print 2. pdksh ||> prints 3 but mksh and oksh print 1. dash, ksh93, yash, and zsh print ||> 0. | |There is no right answer there, 0 and 3 are the most likely results, but |1 and 2 are also possible. ... |And for the example from Oğuz, the value of IFS should be completely |irrelevant, as there's nothing anywhere in that example which actually
And yet it is not for the shells. |needs splitting. The expansion of $* (unquoted, in a context where |field splitting occurs) is supposed to produce 3 fields (since there are |3 set numeric parameters) each of which contains nothing ("") - each of |those is then subject to field splitting, but when there's nothing, there's |nothing. | |The standard says that "any empty fields may be discarded" (that's |actually before the field splitting is to happen, but here it makes no |difference). Note the "any ... may", so the implementation is allowed |to, but not required to, discard any of the three empty fields that |have been produced. So it can discard none, (answer 3) or discard all |of them (answer 0) which are the more reasonable choices, or it can |discard 1 (answer 2) or 2 (answer 1) of the three. Any of those is \ |possible. And then Oğuz simply stops on the way, because if i modify my own thing to a() { echo $#,1=$1,2=$2,3=$3,4=$4,5=$5,6=$6,"$*",$*, } set -- '' 'a' '' IFS=':'; a $* IFS=' '; a $* then not "all agree" and i get #?0|kent:tmp$ bash t.sh 2,1=,2=a,3=,4=,5=,6=,:a, a, 1,1=a,2=,3=,4=,5=,6=,a,a, #?0|kent:tmp$ dash t.sh 1,1=a,2=,3=,4=,5=,6=,a,a, 1,1=a,2=,3=,4=,5=,6=,a,a, #?0|kent:tmp$ busybox.static sh t.sh 1,1=a,2=,3=,4=,5=,6=,a,a, 1,1=a,2=,3=,4=,5=,6=,a,a, #?0|kent:tmp$ ... 3,1=,2=a,3=,4=,5=,6=,:a:, a , 1,1=a,2=,3=,4=,5=,6=,a,a, || Please don't do this in your scripts. ... |Here, as best I can tell, none do - though I know that the shell I |maintain (the NetBSD sh) gets to this point more by a fluke than |anything else, treating the $* as if it were "$*" - except unquoted |and thus subject to field splitting (perhaps bash does the same thing). | |Then the expansion of $* above gives xx (not nothing) which is then |field split, which produces 2 fields (as each x is really a field termin\ |ator, |no field follows the final one). It doesn't matter what IFS[0] is for |this, as long as it isn't white space, the same result will always happen |(the expansion inserts it, field splitting removes it). When IFS[0] is |white space, different rules apply to the field splitting algorithm, which |is why the results differ in that case. 'still trying to align my head with 2.6.5 field splitting, but it seems a matter of "delimination" or not At this point, if the candidate is not empty, or if a sequence of bytes representing an IFS character that is not IFS white space was seen at step 4, then a field is said to have been delimited, and the candidate shall become an output field. |Nothing allows empty fields produced by field splitting to be discarded, |so we end up with 2 fields remaining. | |How 0 or 3 are produced is easy to see (either all, or none, of the empty |fields are discarded, either of which is a reasonable choice) - then field |splitting would happen on the ones not discarded, but cannot split anything |when the fields are empty. | |I'm not sure what the implementation mechanics are which would actually |produce 1 field as the result. | | |So Steffen, if you were writing a shell, then you could do whatever you |like in this case, the value of IFS really should not matter at all, and |either 0 or 3 fields are sensible answers. For a MUA, I think you get |to do whatever you like, and trying to copy the various bizarre shell |behaviour in this case (that different shells implement this differently |is why the standard is so vague about what happens) doesn't make much \ |sense. It seems so, dear Robert. But logically derivable it should be, and thus i am thankful for the efforts of yours. |And certainly, if you're writing a script, just don't do things like this. Field splitting seems to be a fragile concept. Even though i "use" the shell for the quarter of a century, and use it for a bit more than "just maintainance scripting" for way over a decade, the fact that anything but "$@" is nothing but non-portable and very fragile yet escaped me. --End of <3946.1726671...@jacaranda.noi.kre.to> Thank you, and Ciao! --steffen | |Der Kragenbaer, The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)