IFS goes "right through" double quotes in "${#str}"

Run this code TWICE.
Second time with uncommented IFS
Code:
#!/bin/sh


#IFS=20

str='st'

echo 'LEN:'
echo "${#str}"

num=2
echo "$num"
When IFS=20, there is no way to protect ${#str}, no matter how do I escape it!
 
The shell is doing what you ask it to. Basically, after replacing ${#str} with the number 2, the shell then does a pass on parsing out parameters. Since 2 is in the IFS variable, it's expanded as a field separator.

Either unset IFS or use a sane IFS in the first place.
 
IFS is a list of characters. Do you really want "2" and "0" to be field separators?

Code:
#!/bin/sh

fields="abc0def2ghi0jkl2"

IFS=20

for field in $fields; do
  echo $field
done
 
gordon@ said:
... Since 2 is in the IFS variable, it's expanded as a field separator. ...
That I know. The point is, IFS should not kick in, inside of "" double quotes, as they protect each variable from IFS, as well as '' single quotes. (but inside them vars don't expand, as all is literal)
To sum it:
echo "${#str}" -> Should echo '2'
echo ${#str} -> Should echo '' null/empty string

wblock said:
IFS is a list of characters. Do you really want "2" and "0" to be field separators?
...
Yes I want IFS to split string on each char 2 (two) and 0 (zero).
 
Seeker said:
That I know. The point is, IFS should not kick in, inside of "" double quotes, as they protect each variable from IFS, as well as '' single quotes. (but inside them vars don't expand, as all is literal)
To sum it:
echo "${#str}" -> Should echo '2'
echo ${#str} -> Should echo '' null/empty string

That's the case in a shell expansion, but the echo is not a shell expansion, it's a subcommand. The following does what you want:

Code:
#! /bin/sh

set -x

IFS=2

str='st'

echo 'LEN:'
bar="${#str}"
echo "$bar"
 
Thank you gordon.
That works also without ", when putting in var.
Code:
bar=${#str}
echo "$bar"

However, this ones, of a same class, do work by respecting ", when it comes to IFS
Code:
# IFS [B]doesn't[/B] kicks in
echo [B]"[/B]${str%edit*}[B]"[/B]
# IFS [B]does[/B] kick in
echo ${str#*edit}

As well (taken from first post)
Code:
# IFS [B]doesn't[/B] kicks in
echo [B]"[/B]$num[B]"[/B]
# IFS [B]does[/B] kick in
echo $num

So this should follow same rule
Code:
[color="Red"]# IFS goes right through [B]"[/B][/color]
echo [B]"[/B]${#str}[B]"[/B]

I say this is a bug!
 
Yes, I agree this is a bug. I will commit a fix soon, which will revert the incorrect patch done for PR 12137 (the code in head is changed but that is just cosmetic). The change done for PR 56147 also fixes PR 12137 correctly.
 
Back
Top