bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: IFS=: & splitting paths -- (maybe fixed in 4.3?)


From: Eduardo A . Bustamante López
Subject: Re: IFS=: & splitting paths -- (maybe fixed in 4.3?)
Date: Sun, 8 Mar 2015 11:21:41 -0600
User-agent: Mutt/1.5.20 (2009-12-10)

Your code is horrible. Why do you have to alias stuff like declare -p?

Anyways.

> #!/bin/bash
> echo "Using:"
> bash --version|head -1
> shopt -s expand_aliases
> RA='declare -a'
> alias rs="IFS=\ $'\x09'$'\x0a'" 

The fuck? Just use 
alias rs="IFS=\$' \t\n'" or even better, alias rs='unset IFS'

> alias sho='declare -p'
...

> hx(){ ((${#1})) && { printf "%02x " "'${1}"; hx "${1:1}"; } || echo ""; }
> 
> pth=".:/Usr_bin:/system32:/System32_Wbem:/Prog64_NVIDIA GPU Computing 
> Toolkit_CUDA_bin:/Prog_QuickTime"

> echo "1st try to split pth:"
> IFS=: echo $pth
This *obviously* doesn't work.

The FOO=val cmd  notation inserts 'FOO' in the environment of 'cmd', but
if 'cmd' doesn't care about its environment, it will not do anything useful.

In this case, echo only cares about its positional arguments, IFS means nothing
to echo. It's bash the one that does the splitting. Now, since the IFS
assignment affects 'echo' only, you're splitting $pth using the default IFS.

> echo "IFS=$(hx "$IFS")"
> echo "in parens is the same:"
> (IFS=: echo $pth)

Of course it is the same, you should know by know that the parens only
introduce a subshell, the inner command is the same.

> echo "add semi after colon & it works! why didn't local assigment work?"
> (IFS=:; echo $pth)

Because FOO=val; cmd  first sets 'FOO' in the local shell. By the time it
reaches 'cmd', 'FOO' is already set. So, if you do that with IFS, the shell
will consider the new IFS to perform word splitting.

> echo "assign pth to a, try 'let' (to make assigment, IFS still ok):"
> IFS=: let a=($pth)
> echo "IFS=$(hx "$IFS")"
> echo "try assign -- and but IFS is thrashed"
> IFS=: a=($pth)
> echo "'a' became an array, but didn't split on colons"

This is *exactly* the same as the first case, $pth is expanded before the IFS
assignment, and .... well, 'let' doesn't care about IFS

Also, what do you mean by 'IFS is trashed'? The only case where that kind of
assignment can affect the current shell environment is if you have POSIX mode
enabled, and if you use one of the special builtins, listed here:

http://pubs.opengroup.org/onlinepubs/009695399/idx/sbi.html

| address@hidden ~ % bash -c 'IFS=: :; echo "$IFS"'|od -A n -v -c   
|      \t  \n  \n
| address@hidden ~ % bash --posix -c 'IFS=: :; echo "$IFS"'|od -A n -v -c   
|    :  \n


> sho a
> echo "reset IFS then try again:"
> rs
> echo "IFS=$(hx "$IFS")"
> IFS=: a=($pth)
> echo "Now this one works (because 'a' is already an array)"
> sho a

No. It doesn't work because if that, it works because here you set IFS *before*
the $pth parameter is split. But you're basically doing:

a=b c=d, so 'a' is set for the current shell (IFS), I guess that's what you
mean by it getting trashed.

Look what happens when you change the evaluation order:

| address@hidden ~ % bash -c 'x=a:b:c; IFS=: a=($x); declare -p a'
| declare -a a='([0]="a" [1]="b" [2]="c")'
| address@hidden ~ % bash -c 'x=a:b:c; a=($x) IFS=:; declare -p a'
| declare -a a='([0]="a:b:c")'
| address@hidden ~ % bash -c 'x=a:b:c; eval IFS=: a=($x); declare -p a'
| declare -a a='([0]="a:b:c")'
| address@hidden ~ % bash -c 'x=a:b:c; IFS=: eval a=($x); declare -p a'
| declare -a a='([0]="a:b:c")'
| address@hidden ~ % bash -c 'x=a:b:c; IFS=: eval a=(\$x); declare -p a'
| declare -a a='([0]="a" [1]="b" [2]="c")'

> echo "though IFS still got thrashed:"
> echo "IFS=$(hx "$IFS")"
> echo -n "resetting: "
> rs
> echo "IFS=$(hx "$IFS")"
> 
> # so IFS works locally with assignment, but gets trashed.
> # shouldn't:
> #   1) local assignment work w/echo and 'let'
> #   2) shouldn't IFS remain untrashed with the 1 case
> #     it does split properly (assignment)?
> 

I recommend you to read this:
http://pubs.opengroup.org/onlinepubs/9699919799/

Completely. It will solve most of your questions.

Also, in the future, consider showing your issue with the most simple code that
can reproduce the problem. I guess you think that you look smart by
obfuscating your code with aliases and weird names, but it's the opposite
effect. Also, it annoys people that are trying to understand what you say to
help you.



reply via email to

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