Does variable expansion work differently depending on the context the variable is in?
Clash Royale CLAN TAG#URR8PPP
up vote
0
down vote
favorite
Say I did the following:
IFS=,
x="hello,hi,world"
y=$x
y
will have the string hello hi world
, so it's like y=$x
was replaced by:
y="hello hi world"
Now say I have the following script:
IFS=,
x="hello,hi,world"
if [ $x = "hello hi world" ]
then
echo "equal"
fi
When running the above script, I get the following error:
test.sh: line 3: [: too many arguments
I assume that I got this error because the statement if [ $x = "hello hi world" ]
was replaced by if [ hello hi world = "hello hi world" ]
and not by if [ "hello hi world" = "hello hi world" ]
upon execution.
So this means that the variable $x
was expanded in two different ways depending on the context it was in (one time it was expanded with double quotes, and another time it was expanded without double quotes).
Am I correct?
linux bash
add a comment |Â
up vote
0
down vote
favorite
Say I did the following:
IFS=,
x="hello,hi,world"
y=$x
y
will have the string hello hi world
, so it's like y=$x
was replaced by:
y="hello hi world"
Now say I have the following script:
IFS=,
x="hello,hi,world"
if [ $x = "hello hi world" ]
then
echo "equal"
fi
When running the above script, I get the following error:
test.sh: line 3: [: too many arguments
I assume that I got this error because the statement if [ $x = "hello hi world" ]
was replaced by if [ hello hi world = "hello hi world" ]
and not by if [ "hello hi world" = "hello hi world" ]
upon execution.
So this means that the variable $x
was expanded in two different ways depending on the context it was in (one time it was expanded with double quotes, and another time it was expanded without double quotes).
Am I correct?
linux bash
2
"y will have the string hello hi world" That is not correct.
â Hauke Laging
Jan 4 at 20:38
add a comment |Â
up vote
0
down vote
favorite
up vote
0
down vote
favorite
Say I did the following:
IFS=,
x="hello,hi,world"
y=$x
y
will have the string hello hi world
, so it's like y=$x
was replaced by:
y="hello hi world"
Now say I have the following script:
IFS=,
x="hello,hi,world"
if [ $x = "hello hi world" ]
then
echo "equal"
fi
When running the above script, I get the following error:
test.sh: line 3: [: too many arguments
I assume that I got this error because the statement if [ $x = "hello hi world" ]
was replaced by if [ hello hi world = "hello hi world" ]
and not by if [ "hello hi world" = "hello hi world" ]
upon execution.
So this means that the variable $x
was expanded in two different ways depending on the context it was in (one time it was expanded with double quotes, and another time it was expanded without double quotes).
Am I correct?
linux bash
Say I did the following:
IFS=,
x="hello,hi,world"
y=$x
y
will have the string hello hi world
, so it's like y=$x
was replaced by:
y="hello hi world"
Now say I have the following script:
IFS=,
x="hello,hi,world"
if [ $x = "hello hi world" ]
then
echo "equal"
fi
When running the above script, I get the following error:
test.sh: line 3: [: too many arguments
I assume that I got this error because the statement if [ $x = "hello hi world" ]
was replaced by if [ hello hi world = "hello hi world" ]
and not by if [ "hello hi world" = "hello hi world" ]
upon execution.
So this means that the variable $x
was expanded in two different ways depending on the context it was in (one time it was expanded with double quotes, and another time it was expanded without double quotes).
Am I correct?
linux bash
asked Jan 4 at 20:17
user267935
1753
1753
2
"y will have the string hello hi world" That is not correct.
â Hauke Laging
Jan 4 at 20:38
add a comment |Â
2
"y will have the string hello hi world" That is not correct.
â Hauke Laging
Jan 4 at 20:38
2
2
"y will have the string hello hi world" That is not correct.
â Hauke Laging
Jan 4 at 20:38
"y will have the string hello hi world" That is not correct.
â Hauke Laging
Jan 4 at 20:38
add a comment |Â
4 Answers
4
active
oldest
votes
up vote
4
down vote
y
will have the stringhello hi world
No, it won't. Expansions in variable assignments are not subject to word splitting or filename globbing. (In a sense, they always act like they were double-quoted.) See: When is double-quoting necessary?
$ IFS=,
$ x="hello,hi,world"; y=$x
$ echo "$y"
hello,hi,world
I assume that I got this error because the statement
if [ $x = "hello hi world" ]
was replaced byif [ hello hi world = "hello hi world" ]
Yes, sort of. It's not a text-based replacement, but since $x
was not quoted here, it does go through word splitting, and the [
command sees six distinct arguments (hello
, hi
, world
, =
, hello hi world
, and ]
), not the four it expects.
add a comment |Â
up vote
0
down vote
Variables indeed behave differently with respect to quoting if they are used in assignments. In
y=$x
no word splitting is performed i.e. it is equivalent to
y="$x"
But in a normal parameter expansion like
if [ $x =
it does make a difference whether there are quotes. BTW: With quotes $x
would not have been expanded to "hello hi world"
but "hello,hi,world"
.
add a comment |Â
up vote
0
down vote
Word splitting does not happen during variable assignment, so y
contains hello,hi,world
. However, word splitting does happen inside , and since you set
IFS=,
it is expanded to hello
hi
world
as separate words.
The problem is that [
expects a specific number of arguments, and it's telling you it received too many because of the word splitting. Since you tagged this with bash
, you can use its superior [[ ]]
command to disable word splitting and you won't get the error.
If you actually do want to do word splitting on x
, you can do it like this: y="$(IFS=','; echo $x)"
. That will assign hello hi world
as one word to y
.
add a comment |Â
up vote
0
down vote
You are having quoting issues:
Variable expansion:
y will have the string hello hi world
No it won't. But an echo unquoted will print such value:
$ IFS=,
$ x="hello,hi,world"
$ y=$x
$ echo $y
hello hi worldYes, the IFS character (
,
) splits the variable expansion and echo places an space between the arguments, look at this to see it in detail:$ printf '<%s>n' $y
<hello>
<hi>
<world>However, a quoted expansion will not be changed by IFS nor split:
$ echo "$y"
hello,hi,world
$ printf '<%s>n' "$y"
<hello,hi,world>Test line
[ $x = "hello hi world" ]
The same quoting problem happens here, the variable gets expanded and split into words. The line becomes:
[ hello hi world = "hello hi world" ]
The three arguments "hello", "hi" and "world" can not be parsed into a correct test construct.
This, however, does:
$ y=hello,=,world,-o,hello
$ [ $y = "hello" ] && echo yes || echo no
yesbecause what got executed was:
[ hello = world -o hello = "hello" ] && echo yes || echo no
Quoting avoids the splitting:
$ y=hello,hi,world
$ [ "$y" = "hello,hi,world" ] && echo yes || echo no
yesAs using the
[[
construct also avoids splitting:$ y=hello,hi,world
$ [[ $y == "hello,hi,world" ]] && echo yes || echo no
yesYour question:
Am I correct?
No, each time the variable got expanded in the same way.
TL;DR
Quote your expansions.
add a comment |Â
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
4
down vote
y
will have the stringhello hi world
No, it won't. Expansions in variable assignments are not subject to word splitting or filename globbing. (In a sense, they always act like they were double-quoted.) See: When is double-quoting necessary?
$ IFS=,
$ x="hello,hi,world"; y=$x
$ echo "$y"
hello,hi,world
I assume that I got this error because the statement
if [ $x = "hello hi world" ]
was replaced byif [ hello hi world = "hello hi world" ]
Yes, sort of. It's not a text-based replacement, but since $x
was not quoted here, it does go through word splitting, and the [
command sees six distinct arguments (hello
, hi
, world
, =
, hello hi world
, and ]
), not the four it expects.
add a comment |Â
up vote
4
down vote
y
will have the stringhello hi world
No, it won't. Expansions in variable assignments are not subject to word splitting or filename globbing. (In a sense, they always act like they were double-quoted.) See: When is double-quoting necessary?
$ IFS=,
$ x="hello,hi,world"; y=$x
$ echo "$y"
hello,hi,world
I assume that I got this error because the statement
if [ $x = "hello hi world" ]
was replaced byif [ hello hi world = "hello hi world" ]
Yes, sort of. It's not a text-based replacement, but since $x
was not quoted here, it does go through word splitting, and the [
command sees six distinct arguments (hello
, hi
, world
, =
, hello hi world
, and ]
), not the four it expects.
add a comment |Â
up vote
4
down vote
up vote
4
down vote
y
will have the stringhello hi world
No, it won't. Expansions in variable assignments are not subject to word splitting or filename globbing. (In a sense, they always act like they were double-quoted.) See: When is double-quoting necessary?
$ IFS=,
$ x="hello,hi,world"; y=$x
$ echo "$y"
hello,hi,world
I assume that I got this error because the statement
if [ $x = "hello hi world" ]
was replaced byif [ hello hi world = "hello hi world" ]
Yes, sort of. It's not a text-based replacement, but since $x
was not quoted here, it does go through word splitting, and the [
command sees six distinct arguments (hello
, hi
, world
, =
, hello hi world
, and ]
), not the four it expects.
y
will have the stringhello hi world
No, it won't. Expansions in variable assignments are not subject to word splitting or filename globbing. (In a sense, they always act like they were double-quoted.) See: When is double-quoting necessary?
$ IFS=,
$ x="hello,hi,world"; y=$x
$ echo "$y"
hello,hi,world
I assume that I got this error because the statement
if [ $x = "hello hi world" ]
was replaced byif [ hello hi world = "hello hi world" ]
Yes, sort of. It's not a text-based replacement, but since $x
was not quoted here, it does go through word splitting, and the [
command sees six distinct arguments (hello
, hi
, world
, =
, hello hi world
, and ]
), not the four it expects.
answered Jan 4 at 20:58
ilkkachu
49.9k674137
49.9k674137
add a comment |Â
add a comment |Â
up vote
0
down vote
Variables indeed behave differently with respect to quoting if they are used in assignments. In
y=$x
no word splitting is performed i.e. it is equivalent to
y="$x"
But in a normal parameter expansion like
if [ $x =
it does make a difference whether there are quotes. BTW: With quotes $x
would not have been expanded to "hello hi world"
but "hello,hi,world"
.
add a comment |Â
up vote
0
down vote
Variables indeed behave differently with respect to quoting if they are used in assignments. In
y=$x
no word splitting is performed i.e. it is equivalent to
y="$x"
But in a normal parameter expansion like
if [ $x =
it does make a difference whether there are quotes. BTW: With quotes $x
would not have been expanded to "hello hi world"
but "hello,hi,world"
.
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Variables indeed behave differently with respect to quoting if they are used in assignments. In
y=$x
no word splitting is performed i.e. it is equivalent to
y="$x"
But in a normal parameter expansion like
if [ $x =
it does make a difference whether there are quotes. BTW: With quotes $x
would not have been expanded to "hello hi world"
but "hello,hi,world"
.
Variables indeed behave differently with respect to quoting if they are used in assignments. In
y=$x
no word splitting is performed i.e. it is equivalent to
y="$x"
But in a normal parameter expansion like
if [ $x =
it does make a difference whether there are quotes. BTW: With quotes $x
would not have been expanded to "hello hi world"
but "hello,hi,world"
.
answered Jan 4 at 21:00
Hauke Laging
53.5k1282130
53.5k1282130
add a comment |Â
add a comment |Â
up vote
0
down vote
Word splitting does not happen during variable assignment, so y
contains hello,hi,world
. However, word splitting does happen inside , and since you set
IFS=,
it is expanded to hello
hi
world
as separate words.
The problem is that [
expects a specific number of arguments, and it's telling you it received too many because of the word splitting. Since you tagged this with bash
, you can use its superior [[ ]]
command to disable word splitting and you won't get the error.
If you actually do want to do word splitting on x
, you can do it like this: y="$(IFS=','; echo $x)"
. That will assign hello hi world
as one word to y
.
add a comment |Â
up vote
0
down vote
Word splitting does not happen during variable assignment, so y
contains hello,hi,world
. However, word splitting does happen inside , and since you set
IFS=,
it is expanded to hello
hi
world
as separate words.
The problem is that [
expects a specific number of arguments, and it's telling you it received too many because of the word splitting. Since you tagged this with bash
, you can use its superior [[ ]]
command to disable word splitting and you won't get the error.
If you actually do want to do word splitting on x
, you can do it like this: y="$(IFS=','; echo $x)"
. That will assign hello hi world
as one word to y
.
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Word splitting does not happen during variable assignment, so y
contains hello,hi,world
. However, word splitting does happen inside , and since you set
IFS=,
it is expanded to hello
hi
world
as separate words.
The problem is that [
expects a specific number of arguments, and it's telling you it received too many because of the word splitting. Since you tagged this with bash
, you can use its superior [[ ]]
command to disable word splitting and you won't get the error.
If you actually do want to do word splitting on x
, you can do it like this: y="$(IFS=','; echo $x)"
. That will assign hello hi world
as one word to y
.
Word splitting does not happen during variable assignment, so y
contains hello,hi,world
. However, word splitting does happen inside , and since you set
IFS=,
it is expanded to hello
hi
world
as separate words.
The problem is that [
expects a specific number of arguments, and it's telling you it received too many because of the word splitting. Since you tagged this with bash
, you can use its superior [[ ]]
command to disable word splitting and you won't get the error.
If you actually do want to do word splitting on x
, you can do it like this: y="$(IFS=','; echo $x)"
. That will assign hello hi world
as one word to y
.
answered Jan 4 at 21:11
m0dular
63115
63115
add a comment |Â
add a comment |Â
up vote
0
down vote
You are having quoting issues:
Variable expansion:
y will have the string hello hi world
No it won't. But an echo unquoted will print such value:
$ IFS=,
$ x="hello,hi,world"
$ y=$x
$ echo $y
hello hi worldYes, the IFS character (
,
) splits the variable expansion and echo places an space between the arguments, look at this to see it in detail:$ printf '<%s>n' $y
<hello>
<hi>
<world>However, a quoted expansion will not be changed by IFS nor split:
$ echo "$y"
hello,hi,world
$ printf '<%s>n' "$y"
<hello,hi,world>Test line
[ $x = "hello hi world" ]
The same quoting problem happens here, the variable gets expanded and split into words. The line becomes:
[ hello hi world = "hello hi world" ]
The three arguments "hello", "hi" and "world" can not be parsed into a correct test construct.
This, however, does:
$ y=hello,=,world,-o,hello
$ [ $y = "hello" ] && echo yes || echo no
yesbecause what got executed was:
[ hello = world -o hello = "hello" ] && echo yes || echo no
Quoting avoids the splitting:
$ y=hello,hi,world
$ [ "$y" = "hello,hi,world" ] && echo yes || echo no
yesAs using the
[[
construct also avoids splitting:$ y=hello,hi,world
$ [[ $y == "hello,hi,world" ]] && echo yes || echo no
yesYour question:
Am I correct?
No, each time the variable got expanded in the same way.
TL;DR
Quote your expansions.
add a comment |Â
up vote
0
down vote
You are having quoting issues:
Variable expansion:
y will have the string hello hi world
No it won't. But an echo unquoted will print such value:
$ IFS=,
$ x="hello,hi,world"
$ y=$x
$ echo $y
hello hi worldYes, the IFS character (
,
) splits the variable expansion and echo places an space between the arguments, look at this to see it in detail:$ printf '<%s>n' $y
<hello>
<hi>
<world>However, a quoted expansion will not be changed by IFS nor split:
$ echo "$y"
hello,hi,world
$ printf '<%s>n' "$y"
<hello,hi,world>Test line
[ $x = "hello hi world" ]
The same quoting problem happens here, the variable gets expanded and split into words. The line becomes:
[ hello hi world = "hello hi world" ]
The three arguments "hello", "hi" and "world" can not be parsed into a correct test construct.
This, however, does:
$ y=hello,=,world,-o,hello
$ [ $y = "hello" ] && echo yes || echo no
yesbecause what got executed was:
[ hello = world -o hello = "hello" ] && echo yes || echo no
Quoting avoids the splitting:
$ y=hello,hi,world
$ [ "$y" = "hello,hi,world" ] && echo yes || echo no
yesAs using the
[[
construct also avoids splitting:$ y=hello,hi,world
$ [[ $y == "hello,hi,world" ]] && echo yes || echo no
yesYour question:
Am I correct?
No, each time the variable got expanded in the same way.
TL;DR
Quote your expansions.
add a comment |Â
up vote
0
down vote
up vote
0
down vote
You are having quoting issues:
Variable expansion:
y will have the string hello hi world
No it won't. But an echo unquoted will print such value:
$ IFS=,
$ x="hello,hi,world"
$ y=$x
$ echo $y
hello hi worldYes, the IFS character (
,
) splits the variable expansion and echo places an space between the arguments, look at this to see it in detail:$ printf '<%s>n' $y
<hello>
<hi>
<world>However, a quoted expansion will not be changed by IFS nor split:
$ echo "$y"
hello,hi,world
$ printf '<%s>n' "$y"
<hello,hi,world>Test line
[ $x = "hello hi world" ]
The same quoting problem happens here, the variable gets expanded and split into words. The line becomes:
[ hello hi world = "hello hi world" ]
The three arguments "hello", "hi" and "world" can not be parsed into a correct test construct.
This, however, does:
$ y=hello,=,world,-o,hello
$ [ $y = "hello" ] && echo yes || echo no
yesbecause what got executed was:
[ hello = world -o hello = "hello" ] && echo yes || echo no
Quoting avoids the splitting:
$ y=hello,hi,world
$ [ "$y" = "hello,hi,world" ] && echo yes || echo no
yesAs using the
[[
construct also avoids splitting:$ y=hello,hi,world
$ [[ $y == "hello,hi,world" ]] && echo yes || echo no
yesYour question:
Am I correct?
No, each time the variable got expanded in the same way.
TL;DR
Quote your expansions.
You are having quoting issues:
Variable expansion:
y will have the string hello hi world
No it won't. But an echo unquoted will print such value:
$ IFS=,
$ x="hello,hi,world"
$ y=$x
$ echo $y
hello hi worldYes, the IFS character (
,
) splits the variable expansion and echo places an space between the arguments, look at this to see it in detail:$ printf '<%s>n' $y
<hello>
<hi>
<world>However, a quoted expansion will not be changed by IFS nor split:
$ echo "$y"
hello,hi,world
$ printf '<%s>n' "$y"
<hello,hi,world>Test line
[ $x = "hello hi world" ]
The same quoting problem happens here, the variable gets expanded and split into words. The line becomes:
[ hello hi world = "hello hi world" ]
The three arguments "hello", "hi" and "world" can not be parsed into a correct test construct.
This, however, does:
$ y=hello,=,world,-o,hello
$ [ $y = "hello" ] && echo yes || echo no
yesbecause what got executed was:
[ hello = world -o hello = "hello" ] && echo yes || echo no
Quoting avoids the splitting:
$ y=hello,hi,world
$ [ "$y" = "hello,hi,world" ] && echo yes || echo no
yesAs using the
[[
construct also avoids splitting:$ y=hello,hi,world
$ [[ $y == "hello,hi,world" ]] && echo yes || echo no
yesYour question:
Am I correct?
No, each time the variable got expanded in the same way.
TL;DR
Quote your expansions.
answered Jan 5 at 1:25
Isaac
6,7911834
6,7911834
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f414846%2fdoes-variable-expansion-work-differently-depending-on-the-context-the-variable-i%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
2
"y will have the string hello hi world" That is not correct.
â Hauke Laging
Jan 4 at 20:38