[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Help-bash] Command Substitution
From: |
Bob Proulx |
Subject: |
Re: [Help-bash] Command Substitution |
Date: |
Sun, 24 Nov 2013 11:58:12 -0700 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
Davide Brini wrote:
> Kevin Connor Arpe wrote:
> > Unless I misunderstand, this sentence is inconsistent with the following:
> > $ bash
> > $ echo $BASH_VERSION
> > 4.2.0(2)-release
> > $ var="data
> > > more data"
> > $ echo $var
> > data more data
>
> This is because word splitting is performed on the unquoted variable $var.
Correct. But I wanted to say a few words here.
$var contains three whitespace separated strings. The shell's IFS
variable is the "input field separator". When the shell does word
splitting it will split based upon the value of the IFS. The IFS
contains space, tab, newline. Both the spaces and the newlines split
words.
If you were to replace the 'echo' above with a 'printargs' script
(non-standard script that people often write themselves) then you
would find that the command is getting three arguments. Here is an
example printargs script. Everyone has something similar but different.
#!/bin/sh
n=0
while [ $# -gt 0 ]; do
n=$(($n+1))
printf "arg%d: %s\n" "$n" "$1"
shift
done
exit 0
That will print out:
arg1: data
arg2: more
arg3: data
With that you will see that 'echo' is getting three distinct arguments.
> > $ echo "[$var]"
> > [data
> > more data]
> > # ^^^ Should be '[data more data]'?
>
> Only if word splitting was performed. But it's not performed, since the
> variable appears within double quotes.
Using a printargs script instead of echo would show:
arg1: [data
more data]
That is one argument. Because it was quoted. Since it was quoted no
word splitting occurred. The string was passed as the first argument
verbatim.
> > $ var2=$(echo "$var")
>
> Word splitting is NOT performed upon assignment (this is noted elsewhere in
> the manual), so var2 is an exact copy of var.
To understand this see that variable=value is completely internal to
the shell. Therefore it can do the assignment with no passing of data
to any external command. It is a direct assignment. No word
splitting is performed upon an assign such as this independent of
whether it is quoted or not.
var1=$var2
That assignment would also not have word splitting. Since assignments
such as that are completely internal and no word splitting is
performed then neither is word splitting performed when the right hand
side is a command substitution.
var1=$(...)
Same thing. Variable assignment. No word splitting.
echo $(...)
That is simply command substitution. Unquoted so word splitting is done.
echo "$(...)"
Command substitution but quoted and since quoted no word splitting is done.
Hope that helps.
Bob