Scheduled Maintenance: We are aware of an issue with Google, AOL, and Yahoo services as email providers which are blocking new registrations. We are trying to fix the issue and we have several internal and external support tickets in process to resolve the issue. Please see: viewtopic.php?t=158230

 

 

 

Bash - Variable expansion

New to Debian (Or Linux in general)? Ask your questions here!
Post Reply
Message
Author
RedPieDad
Posts: 20
Joined: 2017-12-08 08:17

Bash - Variable expansion

#1 Post by RedPieDad »

I'm reading about the $IFS environment variable. Word splitting, delimiters, and white space characters. But I don't quite understand how these two commands offer different outputs:

Code: Select all

VAR1="foo
bar
baz"

Code: Select all

echo $VAR1
foo bar baz

Code: Select all

echo "$VAR1"
foo
bar
baz

I see that bash expands the variable and substitutes the parameters to the arguments, then echo outputs the strings to stdout but why doesn't the integrity of the white space characters stay intact in the first example? I'm still reading and trying to find out what exactly is going on here. I'm new to linux and I am currently learning some basic commands but got side tracked with shell expansions. Any help is appreciated.




edit: At the time of posting this question my view of $IFS and it's role in interpreting and setting word boundaries was skewed. $IFS reads and sets word boundaries per its default arguments; "space, tab, and newline". It removes white space characters and splits words into their distinct and separate values i.e. "foo" "bar" "baz". 3 separate words. If double quotes are used on the variable it preserves whitespace characters and leads to a single word output. Unless anyone has another or better explanation this seems to somewhat answer what was happening here.
Last edited by RedPieDad on 2018-05-19 22:03, edited 1 time in total.

User avatar
Head_on_a_Stick
Posts: 14114
Joined: 2014-06-01 17:46
Location: London, England
Has thanked: 81 times
Been thanked: 132 times

Re: Bash - Variable expansion

#2 Post by Head_on_a_Stick »

From mksh(1) (also applies to bash, I think):
If a substitution appears outside of double quotes, the results
of the substitution are generally subject to word or field
splitting according to the current value of the IFS parameter.
So unsetting $IFS gives the same output for quoted and unquoted:

Code: Select all

(animal)empty@animal:~ $ echo $var
foo bar baz
(animal)empty@animal:~ $ export IFS=
(animal)empty@animal:~ $ echo $var
foo
bar
baz
(animal)empty@animal:~ $
deadbang

RedPieDad
Posts: 20
Joined: 2017-12-08 08:17

Re: Bash - Variable expansion

#3 Post by RedPieDad »

Head_on_a_Stick wrote:From mksh(1) (also applies to bash, I think):
If a substitution appears outside of double quotes, the results
of the substitution are generally subject to word or field
splitting according to the current value of the IFS parameter.
So unsetting $IFS gives the same output for quoted and unquoted:

Code: Select all

(animal)empty@animal:~ $ echo $var
foo bar baz
(animal)empty@animal:~ $ export IFS=
(animal)empty@animal:~ $ echo $var
foo
bar
baz
(animal)empty@animal:~ $
But the default value of $IFS is a space, tab, and newline. In both examples the arguments are newline. And in the echo statement the variable also has leading whitespace. The values should be interpreted and output as they were written.I am thinking $IFS looks for spaces but ignores tabs and newlines then outputs as a single string. But I don't understand why this happens... or maybe it's some other reason. And now I'm even more confused. You unset the variable but the whitespace characters are intact in the echo statement. I thought the purpose of this variable was to word split? How does unsetting it let the variable keep it's word boundaries?

edit: Nevermind $IFS can't only read spaces. There is none in the examples above. Only newlines, but it still outputs as a single string in an unquoted echo statement, as opposed to it's original values in the variable. Still not sure why this happens.

User avatar
Head_on_a_Stick
Posts: 14114
Joined: 2014-06-01 17:46
Location: London, England
Has thanked: 81 times
Been thanked: 132 times

Re: Bash - Variable expansion

#4 Post by Head_on_a_Stick »

Yes, your question has illuminated gaps in my knowledge, that's for sure :D

I think this may help us both:

https://www.tldp.org/LDP/abs/html/quotingvar.html
deadbang

RedPieDad
Posts: 20
Joined: 2017-12-08 08:17

Re: Bash - Variable expansion

#5 Post by RedPieDad »

Head_on_a_Stick wrote:Yes, your question has illuminated gaps in my knowledge, that's for sure :D

I think this may help us both:

https://www.tldp.org/LDP/abs/html/quotingvar.html
I'll keep reading and try to find an answer. I see in the link you provided it says that double quotes preserve whitespace characters in the variable enclosed in double quotes. Typically whitespace is stripped and the values are output so:
"foo" "bar" "baz" are left. I'm fairly new and can't test this out atm but that seems to be the case. $IFS removes whitespace and sets word boundaries when you echo without quotes but double quotes preserve and output as a single word. Does that seem right? I need to test this later.

User avatar
Head_on_a_Stick
Posts: 14114
Joined: 2014-06-01 17:46
Location: London, England
Has thanked: 81 times
Been thanked: 132 times

Re: Bash - Variable expansion

#6 Post by Head_on_a_Stick »

Head_on_a_Stick wrote:unsetting $IFS
Sorry OP, I'm such a dumbass — I didn't "unset" $IFS, I set it to a newline :roll:

Your supposition is correct btw.
deadbang

User avatar
debiman
Posts: 3063
Joined: 2013-03-12 07:18

Re: Bash - Variable expansion

#7 Post by debiman »

learning languages requires you to sometimes accept "that's just how it is", not always try to explain and compare.
same goes for computer languages.

you could try #bash on IRC (freenode iirc), lots to learn and good answers if you don't mind getting slapped around a bit.

Post Reply