LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Bash: why is word splitting not effective in an assignment (https://www.linuxquestions.org/questions/programming-9/bash-why-is-word-splitting-not-effective-in-an-assignment-775170/)

catkin 12-12-2009 11:00 AM

Bash: why is word splitting not effective in an assignment
 
Hello :)

When bash expands an expression containing a parameter outside double quotes, it first expands the parameter and then tokenises it into IFS-character-separated words as detailed here.

Thus, in
Code:

x='a    df'; echo $x
the "$x" is first expanded to
Code:

'a    df'
and then tokenised to words 'a' and 'df' as evidenced by these examples
Code:

c:~$ x='a    df'
c:~$ echo $x
a df
[in the echo output the 4 spaces have been reduced to one]
c:~$ for i in $x
do
    echo $i
done
a
df

That being the case y=$x should be equivalent to y=a df but it is not
Code:

c:~$ x='a    df'
c:~$ y=$x
c:~$ y=a    df
Filesystem          1K-blocks      Used Available Use% Mounted on
[snip]

How does that work?!

Best

Charles

druuna 12-12-2009 11:31 AM

Hi,

I do believe that one of the first steps taken by the shell when interpreting a command line is splitting it into tokens, expanding expressions is done a few steps later in the process.

This y=a df will be tokenized as:

1) y=a
2) df

The first part doesn't do anything (echo $y -> empty) but doesn't generate an error (which I don't understand ;) ), the second part is interpreted as a command, and executed if legal.

EDIT
As explained by colucix in the next post: The first part does do something. It sets a temporary environment variable.
/EDIT

colucix 12-12-2009 11:46 AM

Quote:

Originally Posted by druuna (Post 3788949)
but doesn't generate an error (which I don't understand ;)

This is the same as running a command and defining an environment variable before the command itself, e.g.
Code:

$ LANG=it_IT date
sab dic 12 18:45:29 CET 2009

In general every variable assignment before a command is valid and correctly interpreted by the shell.

druuna 12-12-2009 11:49 AM

@colucix: Thanks for the explanation!

catkin 12-12-2009 11:58 AM

Thanks druuna :)

The GNU Bash Reference in the section on Simple Command Expansion explains the construct y=a df, saying "the variables are added to the environment of the executed command and do not affect the current shell environment". Hence
Code:

c:~$ x=a
c:~$ x=b eval echo '$x'
b
c:~$ echo $x
a

The answer to my question is in the GNU Bash Reference in the section on shell parameters in the text where it describes assignments: "name=[value] If value is not given, the variable is assigned the null string. All values undergo tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal (detailed below). [snip]. Word splitting is not performed, with the exception of "$@""

catkin 12-12-2009 12:02 PM

Quote:

Originally Posted by colucix (Post 3788962)
This is the same as running a command and defining an environment variable before the command itself, e.g.
Code:

$ LANG=it_IT date
sab dic 12 18:45:29 CET 2009

In general every variable assignment before a command is valid and correctly interpreted by the shell.

Thanks colucix :)

I didn't see your post while preparing mine. I think it was you who first educated me about this little known shell feature. It allows a horrible interview question: "How can you set an environment variable in bash without using the export keyword?"


All times are GMT -5. The time now is 05:56 AM.