Does variable expansion work differently depending on the context the variable is in?

The name of the pictureThe name of the pictureThe name of the pictureClash 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?







share|improve this question
















  • 2




    "y will have the string hello hi world" That is not correct.
    – Hauke Laging
    Jan 4 at 20:38














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?







share|improve this question
















  • 2




    "y will have the string hello hi world" That is not correct.
    – Hauke Laging
    Jan 4 at 20:38












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?







share|improve this question












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?









share|improve this question











share|improve this question




share|improve this question










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












  • 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










4 Answers
4






active

oldest

votes

















up vote
4
down vote














y will have the string hello 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 by if [ 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.






share|improve this answer



























    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".






    share|improve this answer



























      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.






      share|improve this answer



























        up vote
        0
        down vote













        You are having quoting issues:




        1. 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 world


          Yes, 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>



        2. 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
          yes


          because 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
          yes


          As using the [[ construct also avoids splitting:



          $ y=hello,hi,world
          $ [[ $y == "hello,hi,world" ]] && echo yes || echo no
          yes



        3. Your question:




          Am I correct?




          No, each time the variable got expanded in the same way.



        TL;DR



        Quote your expansions.






        share|improve this answer




















          Your Answer







          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "106"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          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






























          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 string hello 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 by if [ 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.






          share|improve this answer
























            up vote
            4
            down vote














            y will have the string hello 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 by if [ 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.






            share|improve this answer






















              up vote
              4
              down vote










              up vote
              4
              down vote










              y will have the string hello 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 by if [ 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.






              share|improve this answer













              y will have the string hello 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 by if [ 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.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Jan 4 at 20:58









              ilkkachu

              49.9k674137




              49.9k674137






















                  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".






                  share|improve this answer
























                    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".






                    share|improve this answer






















                      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".






                      share|improve this answer












                      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".







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Jan 4 at 21:00









                      Hauke Laging

                      53.5k1282130




                      53.5k1282130




















                          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.






                          share|improve this answer
























                            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.






                            share|improve this answer






















                              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.






                              share|improve this answer












                              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.







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Jan 4 at 21:11









                              m0dular

                              63115




                              63115




















                                  up vote
                                  0
                                  down vote













                                  You are having quoting issues:




                                  1. 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 world


                                    Yes, 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>



                                  2. 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
                                    yes


                                    because 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
                                    yes


                                    As using the [[ construct also avoids splitting:



                                    $ y=hello,hi,world
                                    $ [[ $y == "hello,hi,world" ]] && echo yes || echo no
                                    yes



                                  3. Your question:




                                    Am I correct?




                                    No, each time the variable got expanded in the same way.



                                  TL;DR



                                  Quote your expansions.






                                  share|improve this answer
























                                    up vote
                                    0
                                    down vote













                                    You are having quoting issues:




                                    1. 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 world


                                      Yes, 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>



                                    2. 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
                                      yes


                                      because 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
                                      yes


                                      As using the [[ construct also avoids splitting:



                                      $ y=hello,hi,world
                                      $ [[ $y == "hello,hi,world" ]] && echo yes || echo no
                                      yes



                                    3. Your question:




                                      Am I correct?




                                      No, each time the variable got expanded in the same way.



                                    TL;DR



                                    Quote your expansions.






                                    share|improve this answer






















                                      up vote
                                      0
                                      down vote










                                      up vote
                                      0
                                      down vote









                                      You are having quoting issues:




                                      1. 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 world


                                        Yes, 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>



                                      2. 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
                                        yes


                                        because 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
                                        yes


                                        As using the [[ construct also avoids splitting:



                                        $ y=hello,hi,world
                                        $ [[ $y == "hello,hi,world" ]] && echo yes || echo no
                                        yes



                                      3. Your question:




                                        Am I correct?




                                        No, each time the variable got expanded in the same way.



                                      TL;DR



                                      Quote your expansions.






                                      share|improve this answer












                                      You are having quoting issues:




                                      1. 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 world


                                        Yes, 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>



                                      2. 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
                                        yes


                                        because 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
                                        yes


                                        As using the [[ construct also avoids splitting:



                                        $ y=hello,hi,world
                                        $ [[ $y == "hello,hi,world" ]] && echo yes || echo no
                                        yes



                                      3. Your question:




                                        Am I correct?




                                        No, each time the variable got expanded in the same way.



                                      TL;DR



                                      Quote your expansions.







                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Jan 5 at 1:25









                                      Isaac

                                      6,7911834




                                      6,7911834






















                                           

                                          draft saved


                                          draft discarded


























                                           


                                          draft saved


                                          draft discarded














                                          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













































































                                          Popular posts from this blog

                                          How to check contact read email or not when send email to Individual?

                                          Displaying single band from multi-band raster using QGIS

                                          How many registers does an x86_64 CPU actually have?