Why do tilde prefixes expand prior to assignment, but braces don't

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
0
down vote

favorite












tl;dir



In bash, brace expansion occurs before tilde expansion. However, tilde prefixes seem to expand prior to variable assignment and brace expansion doesn't. Why?



Details and examples



Brace expansion in bash is documented as occurring prior to tilde expansion:




Brace expansion is performed before any other expansions




As I understand it, tilde expansion occurs prior to variable assignment, demonstrated by the following example:



# UNQUOTED TILDE PREFIX, TILDE EXPANSION EXPECTED
tilde=~
echo "$tilde"
# /Users/DeNovo
[[ $tilde == "$HOME" ]] && echo "literal match"
# literal match

# QUOTED TILDE PREFIX, TILDE EXPANSION DOES NOT OCCUR
lit_tilde='~'
echo "$lit_tilde"
# ~
# UNQUOTED TILDE PREFIX PRODUCED AND EVALUATED, TILDE EXPANSION OCCURS
# AS EXPECTED
eval echo "$lit_tilde"
# /Users/DeNovo
[[ $lit_tilde == "~" ]] && echo "literal match"
# literal match


These examples would seem to suggest that the right operand of left=right undergoes tilde expansion before being bound as the value to the left operand.



Brace expansion, however, does NOT occur before variable assignment, with similar behavior to binding a literal tilde to a variable (vs. a special character/prefix that is expanded)



# UNQUOTED BRACE, BUT NO EXPANSION. BRACE LITERAL IS PRESERVED
brace=a..c
echo "$brace"
# a..c
[[ $brace = "a b c" ]] || echo "doesn't match"
# doesn't match
[[ $brace = "a..c" ]] && echo "literal match"
# literal match

# SIMILAR TO THE LITERAL TILDE, EVALUATING THE VARIABLE VALUE
# RESULTS IN BRACE EXPANSION
eval echo "$brace"
# a b c


Combining the two expansions into one example, you can see tilde expansion occurs and brace expansion does not:



combined=~/dir_a..c
echo "$combined"
# /Users/DeNovo/dir_a..c


And braces prevent internal tilde's from expanding during assignment



internal_tilde=~,~+/new_dir
echo "$internal_tilde"
# ~,~+/new_dir

# vs the same output, not in a variable
echo ~,~+/new_dir
/Users/DeNovo/new_dir /Your/Working/Directory/new_dir


Just to clarify, I'm not asking how to get a variable to contain the result of brace expansion, but why, despite occurring before tilde expansion, brace expansion doesn't occur before variable assignment. There are several ways to get the desired behavior. Here is one:



# PROCESS SUBSTITUTION GIVES THE DESIRED BEHAVIOR
brace_exp="$(echo a..c)"
echo "$brace_exp"
a b c
[[ $brace_exp = "a b c" ]] && echo "literal match"
# literal match


So again, why does tilde expansion occur before variable assignment, but brace expansion (which is supposed to occur before tilde expansion) doesn't occur before variable assignment. Presumably assignment is special in some way that I'm not aware of.










share|improve this question

























    up vote
    0
    down vote

    favorite












    tl;dir



    In bash, brace expansion occurs before tilde expansion. However, tilde prefixes seem to expand prior to variable assignment and brace expansion doesn't. Why?



    Details and examples



    Brace expansion in bash is documented as occurring prior to tilde expansion:




    Brace expansion is performed before any other expansions




    As I understand it, tilde expansion occurs prior to variable assignment, demonstrated by the following example:



    # UNQUOTED TILDE PREFIX, TILDE EXPANSION EXPECTED
    tilde=~
    echo "$tilde"
    # /Users/DeNovo
    [[ $tilde == "$HOME" ]] && echo "literal match"
    # literal match

    # QUOTED TILDE PREFIX, TILDE EXPANSION DOES NOT OCCUR
    lit_tilde='~'
    echo "$lit_tilde"
    # ~
    # UNQUOTED TILDE PREFIX PRODUCED AND EVALUATED, TILDE EXPANSION OCCURS
    # AS EXPECTED
    eval echo "$lit_tilde"
    # /Users/DeNovo
    [[ $lit_tilde == "~" ]] && echo "literal match"
    # literal match


    These examples would seem to suggest that the right operand of left=right undergoes tilde expansion before being bound as the value to the left operand.



    Brace expansion, however, does NOT occur before variable assignment, with similar behavior to binding a literal tilde to a variable (vs. a special character/prefix that is expanded)



    # UNQUOTED BRACE, BUT NO EXPANSION. BRACE LITERAL IS PRESERVED
    brace=a..c
    echo "$brace"
    # a..c
    [[ $brace = "a b c" ]] || echo "doesn't match"
    # doesn't match
    [[ $brace = "a..c" ]] && echo "literal match"
    # literal match

    # SIMILAR TO THE LITERAL TILDE, EVALUATING THE VARIABLE VALUE
    # RESULTS IN BRACE EXPANSION
    eval echo "$brace"
    # a b c


    Combining the two expansions into one example, you can see tilde expansion occurs and brace expansion does not:



    combined=~/dir_a..c
    echo "$combined"
    # /Users/DeNovo/dir_a..c


    And braces prevent internal tilde's from expanding during assignment



    internal_tilde=~,~+/new_dir
    echo "$internal_tilde"
    # ~,~+/new_dir

    # vs the same output, not in a variable
    echo ~,~+/new_dir
    /Users/DeNovo/new_dir /Your/Working/Directory/new_dir


    Just to clarify, I'm not asking how to get a variable to contain the result of brace expansion, but why, despite occurring before tilde expansion, brace expansion doesn't occur before variable assignment. There are several ways to get the desired behavior. Here is one:



    # PROCESS SUBSTITUTION GIVES THE DESIRED BEHAVIOR
    brace_exp="$(echo a..c)"
    echo "$brace_exp"
    a b c
    [[ $brace_exp = "a b c" ]] && echo "literal match"
    # literal match


    So again, why does tilde expansion occur before variable assignment, but brace expansion (which is supposed to occur before tilde expansion) doesn't occur before variable assignment. Presumably assignment is special in some way that I'm not aware of.










    share|improve this question























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      tl;dir



      In bash, brace expansion occurs before tilde expansion. However, tilde prefixes seem to expand prior to variable assignment and brace expansion doesn't. Why?



      Details and examples



      Brace expansion in bash is documented as occurring prior to tilde expansion:




      Brace expansion is performed before any other expansions




      As I understand it, tilde expansion occurs prior to variable assignment, demonstrated by the following example:



      # UNQUOTED TILDE PREFIX, TILDE EXPANSION EXPECTED
      tilde=~
      echo "$tilde"
      # /Users/DeNovo
      [[ $tilde == "$HOME" ]] && echo "literal match"
      # literal match

      # QUOTED TILDE PREFIX, TILDE EXPANSION DOES NOT OCCUR
      lit_tilde='~'
      echo "$lit_tilde"
      # ~
      # UNQUOTED TILDE PREFIX PRODUCED AND EVALUATED, TILDE EXPANSION OCCURS
      # AS EXPECTED
      eval echo "$lit_tilde"
      # /Users/DeNovo
      [[ $lit_tilde == "~" ]] && echo "literal match"
      # literal match


      These examples would seem to suggest that the right operand of left=right undergoes tilde expansion before being bound as the value to the left operand.



      Brace expansion, however, does NOT occur before variable assignment, with similar behavior to binding a literal tilde to a variable (vs. a special character/prefix that is expanded)



      # UNQUOTED BRACE, BUT NO EXPANSION. BRACE LITERAL IS PRESERVED
      brace=a..c
      echo "$brace"
      # a..c
      [[ $brace = "a b c" ]] || echo "doesn't match"
      # doesn't match
      [[ $brace = "a..c" ]] && echo "literal match"
      # literal match

      # SIMILAR TO THE LITERAL TILDE, EVALUATING THE VARIABLE VALUE
      # RESULTS IN BRACE EXPANSION
      eval echo "$brace"
      # a b c


      Combining the two expansions into one example, you can see tilde expansion occurs and brace expansion does not:



      combined=~/dir_a..c
      echo "$combined"
      # /Users/DeNovo/dir_a..c


      And braces prevent internal tilde's from expanding during assignment



      internal_tilde=~,~+/new_dir
      echo "$internal_tilde"
      # ~,~+/new_dir

      # vs the same output, not in a variable
      echo ~,~+/new_dir
      /Users/DeNovo/new_dir /Your/Working/Directory/new_dir


      Just to clarify, I'm not asking how to get a variable to contain the result of brace expansion, but why, despite occurring before tilde expansion, brace expansion doesn't occur before variable assignment. There are several ways to get the desired behavior. Here is one:



      # PROCESS SUBSTITUTION GIVES THE DESIRED BEHAVIOR
      brace_exp="$(echo a..c)"
      echo "$brace_exp"
      a b c
      [[ $brace_exp = "a b c" ]] && echo "literal match"
      # literal match


      So again, why does tilde expansion occur before variable assignment, but brace expansion (which is supposed to occur before tilde expansion) doesn't occur before variable assignment. Presumably assignment is special in some way that I'm not aware of.










      share|improve this question













      tl;dir



      In bash, brace expansion occurs before tilde expansion. However, tilde prefixes seem to expand prior to variable assignment and brace expansion doesn't. Why?



      Details and examples



      Brace expansion in bash is documented as occurring prior to tilde expansion:




      Brace expansion is performed before any other expansions




      As I understand it, tilde expansion occurs prior to variable assignment, demonstrated by the following example:



      # UNQUOTED TILDE PREFIX, TILDE EXPANSION EXPECTED
      tilde=~
      echo "$tilde"
      # /Users/DeNovo
      [[ $tilde == "$HOME" ]] && echo "literal match"
      # literal match

      # QUOTED TILDE PREFIX, TILDE EXPANSION DOES NOT OCCUR
      lit_tilde='~'
      echo "$lit_tilde"
      # ~
      # UNQUOTED TILDE PREFIX PRODUCED AND EVALUATED, TILDE EXPANSION OCCURS
      # AS EXPECTED
      eval echo "$lit_tilde"
      # /Users/DeNovo
      [[ $lit_tilde == "~" ]] && echo "literal match"
      # literal match


      These examples would seem to suggest that the right operand of left=right undergoes tilde expansion before being bound as the value to the left operand.



      Brace expansion, however, does NOT occur before variable assignment, with similar behavior to binding a literal tilde to a variable (vs. a special character/prefix that is expanded)



      # UNQUOTED BRACE, BUT NO EXPANSION. BRACE LITERAL IS PRESERVED
      brace=a..c
      echo "$brace"
      # a..c
      [[ $brace = "a b c" ]] || echo "doesn't match"
      # doesn't match
      [[ $brace = "a..c" ]] && echo "literal match"
      # literal match

      # SIMILAR TO THE LITERAL TILDE, EVALUATING THE VARIABLE VALUE
      # RESULTS IN BRACE EXPANSION
      eval echo "$brace"
      # a b c


      Combining the two expansions into one example, you can see tilde expansion occurs and brace expansion does not:



      combined=~/dir_a..c
      echo "$combined"
      # /Users/DeNovo/dir_a..c


      And braces prevent internal tilde's from expanding during assignment



      internal_tilde=~,~+/new_dir
      echo "$internal_tilde"
      # ~,~+/new_dir

      # vs the same output, not in a variable
      echo ~,~+/new_dir
      /Users/DeNovo/new_dir /Your/Working/Directory/new_dir


      Just to clarify, I'm not asking how to get a variable to contain the result of brace expansion, but why, despite occurring before tilde expansion, brace expansion doesn't occur before variable assignment. There are several ways to get the desired behavior. Here is one:



      # PROCESS SUBSTITUTION GIVES THE DESIRED BEHAVIOR
      brace_exp="$(echo a..c)"
      echo "$brace_exp"
      a b c
      [[ $brace_exp = "a b c" ]] && echo "literal match"
      # literal match


      So again, why does tilde expansion occur before variable assignment, but brace expansion (which is supposed to occur before tilde expansion) doesn't occur before variable assignment. Presumably assignment is special in some way that I'm not aware of.







      bash brace-expansion tilde






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Dec 4 at 18:52









      De Novo

      1156




      1156




















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          4
          down vote













          In your test, a..c isn’t expanded because it’s part of a variable assignment, and handled separately:




          1. The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later processing.

          2. The words that are not variable assignments or redirections are expanded (see Shell Expansions). If any words remain after expansion, the first word is taken to be the name of the command and the remaining words are the arguments.



          Assigned values don’t undergo brace expansion:




          1. The text after the ‘=’ in each variable assignment undergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal before being assigned to the variable.






          share|improve this answer






















          • @DeNovo Assignments are different, see man bash on assignments: "All values undergo tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal". No brace expansion will be done during assignments.
            – nohillside
            Dec 4 at 19:08










          • Thank you for pointing me to the relevant section of the documentation (+1). I should have been looking in the general information about command expansion, rather than specifically at tilde and brace expansion. I think I've come up with the "why" (beyond "that's how it's documented"). See my self answer
            – De Novo
            Dec 4 at 23:40

















          up vote
          0
          down vote



          accepted










          @StephenKitt's answer points to the relevant documentation (+1), indicating that the behavior is expected (why do tilde prefixes expand prior to assignment but braces don't? Because that's how they are defined).



          Re: A possible reason brace expansion is special, let's look at what doesn't happen on variable assignment:



          • brace expansion

          • word splitting (the parser splits the line, but doesn't split the result of expansion within that word)

          • filename expansion

          These are exactly the operations that can change the number of words of the expansion:



          Shell Expansion:




          Only brace expansion, word splitting, and filename expansion can change the number of words of the expansion




          In the example cases, the variable is a string rather than an array, and should contain only one word.



          Brace expansion does occur when assigning an array, as in brace=(a..c). To use the more complicated example:



          internal_tilde=(~,~+/new_dir)
          echo "$internal_tilde[@]"
          # /Users/DeNovo/new_dir /Your/Working/Directory/new_dir


          So, I would propose this design makes sense (rather than being a historical oddity). Tilde expansion doesn't change the number of words. Brace expansion does. If you want your variable to contain more than one word, use a data structure that is designed for that.






          share|improve this answer




















          • As an additional twist, brace expansion is applied after a redirection operator. Bash reports an error if any expansion results in more than one word after a redirection operator. If changing the number of words was a design consideration, it wasn’t applied consistently :-(.
            – Stephen Kitt
            Dec 5 at 7:57










          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: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          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%2f485970%2fwhy-do-tilde-prefixes-expand-prior-to-assignment-but-braces-dont%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          4
          down vote













          In your test, a..c isn’t expanded because it’s part of a variable assignment, and handled separately:




          1. The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later processing.

          2. The words that are not variable assignments or redirections are expanded (see Shell Expansions). If any words remain after expansion, the first word is taken to be the name of the command and the remaining words are the arguments.



          Assigned values don’t undergo brace expansion:




          1. The text after the ‘=’ in each variable assignment undergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal before being assigned to the variable.






          share|improve this answer






















          • @DeNovo Assignments are different, see man bash on assignments: "All values undergo tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal". No brace expansion will be done during assignments.
            – nohillside
            Dec 4 at 19:08










          • Thank you for pointing me to the relevant section of the documentation (+1). I should have been looking in the general information about command expansion, rather than specifically at tilde and brace expansion. I think I've come up with the "why" (beyond "that's how it's documented"). See my self answer
            – De Novo
            Dec 4 at 23:40














          up vote
          4
          down vote













          In your test, a..c isn’t expanded because it’s part of a variable assignment, and handled separately:




          1. The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later processing.

          2. The words that are not variable assignments or redirections are expanded (see Shell Expansions). If any words remain after expansion, the first word is taken to be the name of the command and the remaining words are the arguments.



          Assigned values don’t undergo brace expansion:




          1. The text after the ‘=’ in each variable assignment undergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal before being assigned to the variable.






          share|improve this answer






















          • @DeNovo Assignments are different, see man bash on assignments: "All values undergo tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal". No brace expansion will be done during assignments.
            – nohillside
            Dec 4 at 19:08










          • Thank you for pointing me to the relevant section of the documentation (+1). I should have been looking in the general information about command expansion, rather than specifically at tilde and brace expansion. I think I've come up with the "why" (beyond "that's how it's documented"). See my self answer
            – De Novo
            Dec 4 at 23:40












          up vote
          4
          down vote










          up vote
          4
          down vote









          In your test, a..c isn’t expanded because it’s part of a variable assignment, and handled separately:




          1. The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later processing.

          2. The words that are not variable assignments or redirections are expanded (see Shell Expansions). If any words remain after expansion, the first word is taken to be the name of the command and the remaining words are the arguments.



          Assigned values don’t undergo brace expansion:




          1. The text after the ‘=’ in each variable assignment undergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal before being assigned to the variable.






          share|improve this answer














          In your test, a..c isn’t expanded because it’s part of a variable assignment, and handled separately:




          1. The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later processing.

          2. The words that are not variable assignments or redirections are expanded (see Shell Expansions). If any words remain after expansion, the first word is taken to be the name of the command and the remaining words are the arguments.



          Assigned values don’t undergo brace expansion:




          1. The text after the ‘=’ in each variable assignment undergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal before being assigned to the variable.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Dec 4 at 19:07

























          answered Dec 4 at 19:05









          Stephen Kitt

          161k24358433




          161k24358433











          • @DeNovo Assignments are different, see man bash on assignments: "All values undergo tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal". No brace expansion will be done during assignments.
            – nohillside
            Dec 4 at 19:08










          • Thank you for pointing me to the relevant section of the documentation (+1). I should have been looking in the general information about command expansion, rather than specifically at tilde and brace expansion. I think I've come up with the "why" (beyond "that's how it's documented"). See my self answer
            – De Novo
            Dec 4 at 23:40
















          • @DeNovo Assignments are different, see man bash on assignments: "All values undergo tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal". No brace expansion will be done during assignments.
            – nohillside
            Dec 4 at 19:08










          • Thank you for pointing me to the relevant section of the documentation (+1). I should have been looking in the general information about command expansion, rather than specifically at tilde and brace expansion. I think I've come up with the "why" (beyond "that's how it's documented"). See my self answer
            – De Novo
            Dec 4 at 23:40















          @DeNovo Assignments are different, see man bash on assignments: "All values undergo tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal". No brace expansion will be done during assignments.
          – nohillside
          Dec 4 at 19:08




          @DeNovo Assignments are different, see man bash on assignments: "All values undergo tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal". No brace expansion will be done during assignments.
          – nohillside
          Dec 4 at 19:08












          Thank you for pointing me to the relevant section of the documentation (+1). I should have been looking in the general information about command expansion, rather than specifically at tilde and brace expansion. I think I've come up with the "why" (beyond "that's how it's documented"). See my self answer
          – De Novo
          Dec 4 at 23:40




          Thank you for pointing me to the relevant section of the documentation (+1). I should have been looking in the general information about command expansion, rather than specifically at tilde and brace expansion. I think I've come up with the "why" (beyond "that's how it's documented"). See my self answer
          – De Novo
          Dec 4 at 23:40












          up vote
          0
          down vote



          accepted










          @StephenKitt's answer points to the relevant documentation (+1), indicating that the behavior is expected (why do tilde prefixes expand prior to assignment but braces don't? Because that's how they are defined).



          Re: A possible reason brace expansion is special, let's look at what doesn't happen on variable assignment:



          • brace expansion

          • word splitting (the parser splits the line, but doesn't split the result of expansion within that word)

          • filename expansion

          These are exactly the operations that can change the number of words of the expansion:



          Shell Expansion:




          Only brace expansion, word splitting, and filename expansion can change the number of words of the expansion




          In the example cases, the variable is a string rather than an array, and should contain only one word.



          Brace expansion does occur when assigning an array, as in brace=(a..c). To use the more complicated example:



          internal_tilde=(~,~+/new_dir)
          echo "$internal_tilde[@]"
          # /Users/DeNovo/new_dir /Your/Working/Directory/new_dir


          So, I would propose this design makes sense (rather than being a historical oddity). Tilde expansion doesn't change the number of words. Brace expansion does. If you want your variable to contain more than one word, use a data structure that is designed for that.






          share|improve this answer




















          • As an additional twist, brace expansion is applied after a redirection operator. Bash reports an error if any expansion results in more than one word after a redirection operator. If changing the number of words was a design consideration, it wasn’t applied consistently :-(.
            – Stephen Kitt
            Dec 5 at 7:57














          up vote
          0
          down vote



          accepted










          @StephenKitt's answer points to the relevant documentation (+1), indicating that the behavior is expected (why do tilde prefixes expand prior to assignment but braces don't? Because that's how they are defined).



          Re: A possible reason brace expansion is special, let's look at what doesn't happen on variable assignment:



          • brace expansion

          • word splitting (the parser splits the line, but doesn't split the result of expansion within that word)

          • filename expansion

          These are exactly the operations that can change the number of words of the expansion:



          Shell Expansion:




          Only brace expansion, word splitting, and filename expansion can change the number of words of the expansion




          In the example cases, the variable is a string rather than an array, and should contain only one word.



          Brace expansion does occur when assigning an array, as in brace=(a..c). To use the more complicated example:



          internal_tilde=(~,~+/new_dir)
          echo "$internal_tilde[@]"
          # /Users/DeNovo/new_dir /Your/Working/Directory/new_dir


          So, I would propose this design makes sense (rather than being a historical oddity). Tilde expansion doesn't change the number of words. Brace expansion does. If you want your variable to contain more than one word, use a data structure that is designed for that.






          share|improve this answer




















          • As an additional twist, brace expansion is applied after a redirection operator. Bash reports an error if any expansion results in more than one word after a redirection operator. If changing the number of words was a design consideration, it wasn’t applied consistently :-(.
            – Stephen Kitt
            Dec 5 at 7:57












          up vote
          0
          down vote



          accepted







          up vote
          0
          down vote



          accepted






          @StephenKitt's answer points to the relevant documentation (+1), indicating that the behavior is expected (why do tilde prefixes expand prior to assignment but braces don't? Because that's how they are defined).



          Re: A possible reason brace expansion is special, let's look at what doesn't happen on variable assignment:



          • brace expansion

          • word splitting (the parser splits the line, but doesn't split the result of expansion within that word)

          • filename expansion

          These are exactly the operations that can change the number of words of the expansion:



          Shell Expansion:




          Only brace expansion, word splitting, and filename expansion can change the number of words of the expansion




          In the example cases, the variable is a string rather than an array, and should contain only one word.



          Brace expansion does occur when assigning an array, as in brace=(a..c). To use the more complicated example:



          internal_tilde=(~,~+/new_dir)
          echo "$internal_tilde[@]"
          # /Users/DeNovo/new_dir /Your/Working/Directory/new_dir


          So, I would propose this design makes sense (rather than being a historical oddity). Tilde expansion doesn't change the number of words. Brace expansion does. If you want your variable to contain more than one word, use a data structure that is designed for that.






          share|improve this answer












          @StephenKitt's answer points to the relevant documentation (+1), indicating that the behavior is expected (why do tilde prefixes expand prior to assignment but braces don't? Because that's how they are defined).



          Re: A possible reason brace expansion is special, let's look at what doesn't happen on variable assignment:



          • brace expansion

          • word splitting (the parser splits the line, but doesn't split the result of expansion within that word)

          • filename expansion

          These are exactly the operations that can change the number of words of the expansion:



          Shell Expansion:




          Only brace expansion, word splitting, and filename expansion can change the number of words of the expansion




          In the example cases, the variable is a string rather than an array, and should contain only one word.



          Brace expansion does occur when assigning an array, as in brace=(a..c). To use the more complicated example:



          internal_tilde=(~,~+/new_dir)
          echo "$internal_tilde[@]"
          # /Users/DeNovo/new_dir /Your/Working/Directory/new_dir


          So, I would propose this design makes sense (rather than being a historical oddity). Tilde expansion doesn't change the number of words. Brace expansion does. If you want your variable to contain more than one word, use a data structure that is designed for that.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Dec 4 at 23:32









          De Novo

          1156




          1156











          • As an additional twist, brace expansion is applied after a redirection operator. Bash reports an error if any expansion results in more than one word after a redirection operator. If changing the number of words was a design consideration, it wasn’t applied consistently :-(.
            – Stephen Kitt
            Dec 5 at 7:57
















          • As an additional twist, brace expansion is applied after a redirection operator. Bash reports an error if any expansion results in more than one word after a redirection operator. If changing the number of words was a design consideration, it wasn’t applied consistently :-(.
            – Stephen Kitt
            Dec 5 at 7:57















          As an additional twist, brace expansion is applied after a redirection operator. Bash reports an error if any expansion results in more than one word after a redirection operator. If changing the number of words was a design consideration, it wasn’t applied consistently :-(.
          – Stephen Kitt
          Dec 5 at 7:57




          As an additional twist, brace expansion is applied after a redirection operator. Bash reports an error if any expansion results in more than one word after a redirection operator. If changing the number of words was a design consideration, it wasn’t applied consistently :-(.
          – Stephen Kitt
          Dec 5 at 7:57

















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Unix & Linux Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f485970%2fwhy-do-tilde-prefixes-expand-prior-to-assignment-but-braces-dont%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown






          Popular posts from this blog

          Peggy Mitchell

          Palaiologos

          The Forum (Inglewood, California)