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

Clash 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.
bash brace-expansion tilde
add a comment |
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.
bash brace-expansion tilde
add a comment |
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.
bash brace-expansion tilde
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
bash brace-expansion tilde
asked Dec 4 at 18:52
De Novo
1156
1156
add a comment |
add a comment |
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:
- The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later processing.
- 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:
- 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.
@DeNovo Assignments are different, seeman bashon 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
add a comment |
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.
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
add a comment |
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
);
);
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
Required, but never shown
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:
- The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later processing.
- 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:
- 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.
@DeNovo Assignments are different, seeman bashon 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
add a comment |
up vote
4
down vote
In your test, a..c isn’t expanded because it’s part of a variable assignment, and handled separately:
- The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later processing.
- 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:
- 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.
@DeNovo Assignments are different, seeman bashon 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
add a comment |
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:
- The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later processing.
- 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:
- 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.
In your test, a..c isn’t expanded because it’s part of a variable assignment, and handled separately:
- The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later processing.
- 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:
- 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.
edited Dec 4 at 19:07
answered Dec 4 at 19:05
Stephen Kitt
161k24358433
161k24358433
@DeNovo Assignments are different, seeman bashon 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
add a comment |
@DeNovo Assignments are different, seeman bashon 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
add a comment |
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.
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
add a comment |
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.
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
add a comment |
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.
@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.
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
add a comment |
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
add a comment |
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.
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
Required, but never shown
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
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
Required, but never shown
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
Required, but never shown
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
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