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



## Seeker (Apr 11, 2011)

Run this code *TWICE*.
*Second time* with uncommented IFS

```
#!/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!


----------



## gordon@ (Apr 11, 2011)

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.


----------



## wblock@ (Apr 12, 2011)

IFS is a list of characters.  Do you really want "2" and "0" to be field separators?


```
#!/bin/sh

fields="abc0def2ghi0jkl2"

IFS=20

for field in $fields; do
  echo $field
done
```


----------



## Seeker (Apr 12, 2011)

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).


----------



## gordon@ (Apr 12, 2011)

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:


```
#! /bin/sh

set -x

IFS=2

str='st'

echo 'LEN:'
bar="${#str}"
echo "$bar"
```


----------



## Seeker (Apr 13, 2011)

Thank you gordon.
That works also without ", when putting in var.

```
bar=${#str}
echo "$bar"
```

However, this ones, of a same class, do work by respecting ", when it comes to IFS

```
# 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)

```
# 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

```
[color="Red"]# IFS goes right through [B]"[/B][/color]
echo [B]"[/B]${#str}[B]"[/B]
```

I say this is a bug!


----------



## jilles@ (Apr 15, 2011)

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.


----------



## Seeker (Apr 15, 2011)

He he ...
You've _"*boosted my points*"_


----------



## jilles@ (May 6, 2011)

This is now fixed in 9-current (r220903) and 8-stable (r221522).


----------

