Why 1,2 printed by a command in $() is not interpolated?What is the difference between `a[bc]d` (brackets) and `ab,cd` (braces)?nesting brace expansion and command substitutionWhy are these values not appending correctly when appended to the pipeline?Save list of echo outputs to .txtusing sed to modify all files in a directory and name the outputs accordinglyEntering a folder with whitespaces and escape characters using bashBash pattern to match directories whose names begin with a dot (period), by being “explicit”, instead of using “shopt -s dotglob”?Use asterisk in variablesBash filename completion explanationshopt -s extdebug in .bashrc not working in script filesbash script to find files thinks the file name should be an integerRunning multiple command against files matching a brace+glob pattern without repeating it

Require advice on power conservation for backpacking trip

Find the diameter of a word graph

Would it be a copyright violation if I made a character’s full name refer to a song?

How to create a Tetrix/Sierpinski Tetrahedron fractal radiating from 0,0,0 ? Python or nodes

Unusual mail headers, evidence of an attempted attack. Have I been pwned?

Why aren't cotton tents more popular?

expiry or manufactured date?

What is the better way to use Optional in conditions?

Sci fi short story, robot city that nags people about health

Is my Rep in Stack-Exchange Form?

Long term BTC investing

Does Marvel have an equivalent of the Green Lantern?

Apply brace expansion in "reverse order"

How does a blind passenger not die, if driver becomes unconscious

How are the Zhentarim and Black Fist related?

Why is the voltage measurement of this circuit different when the switch is on?

STM Microcontroller burns every time

How to make clear to people I don't want to answer their "Where are you from?" question?

I am completely new to Tales from the Floating Vagabond, how do I get started?

How do I turn off a repeating trade?

Why did pressing the joystick button spit out keypresses?

How does metta sutra develop loving kindness

A STL-like vector implementation in C++

Why do some games show lights shine thorugh walls?



Why 1,2 printed by a command in $() is not interpolated?


What is the difference between `a[bc]d` (brackets) and `ab,cd` (braces)?nesting brace expansion and command substitutionWhy are these values not appending correctly when appended to the pipeline?Save list of echo outputs to .txtusing sed to modify all files in a directory and name the outputs accordinglyEntering a folder with whitespaces and escape characters using bashBash pattern to match directories whose names begin with a dot (period), by being “explicit”, instead of using “shopt -s dotglob”?Use asterisk in variablesBash filename completion explanationshopt -s extdebug in .bashrc not working in script filesbash script to find files thinks the file name should be an integerRunning multiple command against files matching a brace+glob pattern without repeating it






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








8















I am in a directory in which I have two text files:



$ touch test1.txt
$ touch test2.txt


When I try to list the files (with Bash) using some pattern it works:



$ ls test?.txt
test1.txt test2.txt
$ ls test1,2.txt
test1.txt test2.txt


However, when a pattern is produced by a command enclosed in $(), only one of patterns work:



$ ls $(echo 'test?.txt')
test1.txt test2.txt
$ ls $(echo 'test1,2.txt')
ls: cannot access test1,2.txt: No such file or directory


What's going on here? Why the pattern 1,2 does not work?










share|improve this question

















  • 4





    Brace expansion isn't performed within single or double quotes

    – Sergiy Kolodyazhnyy
    Jun 6 at 6:47






  • 3





    @SergiyKolodyazhnyy The point of the question is that the ? is also quoted, and gets expanded after $(...) substitutes it, but the brace expansion doesn't.

    – Michael Homer
    Jun 6 at 6:48






  • 1





    @muru No, that's not the same issue. Here the order of expansions doesn't matter, what matters is which expansion takes place in which context. I wouldn't be surprised if this question was a duplicate, but I couldn't find it.

    – Gilles
    Jun 6 at 7:00






  • 1





    @mosvy Ksh and bash do expansions in the same order, but ksh does brace expansion in a case where bash doesn't do it at all. Zsh-with-globsubst does the same expansions as bash, but in a different order.

    – Gilles
    Jun 6 at 20:59






  • 1





    @Gilles no they don't. As documented and easily demonstrated, ksh (and zsh) will perform the brace expansion just before globbing. zsh-with-globsubst won't perform any brace expansion at all on the results of $-expansions: zsh -o globsubst -c 'a=/e*; b=/b*,/v*; echo $a; echo $b'.

    – mosvy
    Jun 6 at 22:14


















8















I am in a directory in which I have two text files:



$ touch test1.txt
$ touch test2.txt


When I try to list the files (with Bash) using some pattern it works:



$ ls test?.txt
test1.txt test2.txt
$ ls test1,2.txt
test1.txt test2.txt


However, when a pattern is produced by a command enclosed in $(), only one of patterns work:



$ ls $(echo 'test?.txt')
test1.txt test2.txt
$ ls $(echo 'test1,2.txt')
ls: cannot access test1,2.txt: No such file or directory


What's going on here? Why the pattern 1,2 does not work?










share|improve this question

















  • 4





    Brace expansion isn't performed within single or double quotes

    – Sergiy Kolodyazhnyy
    Jun 6 at 6:47






  • 3





    @SergiyKolodyazhnyy The point of the question is that the ? is also quoted, and gets expanded after $(...) substitutes it, but the brace expansion doesn't.

    – Michael Homer
    Jun 6 at 6:48






  • 1





    @muru No, that's not the same issue. Here the order of expansions doesn't matter, what matters is which expansion takes place in which context. I wouldn't be surprised if this question was a duplicate, but I couldn't find it.

    – Gilles
    Jun 6 at 7:00






  • 1





    @mosvy Ksh and bash do expansions in the same order, but ksh does brace expansion in a case where bash doesn't do it at all. Zsh-with-globsubst does the same expansions as bash, but in a different order.

    – Gilles
    Jun 6 at 20:59






  • 1





    @Gilles no they don't. As documented and easily demonstrated, ksh (and zsh) will perform the brace expansion just before globbing. zsh-with-globsubst won't perform any brace expansion at all on the results of $-expansions: zsh -o globsubst -c 'a=/e*; b=/b*,/v*; echo $a; echo $b'.

    – mosvy
    Jun 6 at 22:14














8












8








8


1






I am in a directory in which I have two text files:



$ touch test1.txt
$ touch test2.txt


When I try to list the files (with Bash) using some pattern it works:



$ ls test?.txt
test1.txt test2.txt
$ ls test1,2.txt
test1.txt test2.txt


However, when a pattern is produced by a command enclosed in $(), only one of patterns work:



$ ls $(echo 'test?.txt')
test1.txt test2.txt
$ ls $(echo 'test1,2.txt')
ls: cannot access test1,2.txt: No such file or directory


What's going on here? Why the pattern 1,2 does not work?










share|improve this question














I am in a directory in which I have two text files:



$ touch test1.txt
$ touch test2.txt


When I try to list the files (with Bash) using some pattern it works:



$ ls test?.txt
test1.txt test2.txt
$ ls test1,2.txt
test1.txt test2.txt


However, when a pattern is produced by a command enclosed in $(), only one of patterns work:



$ ls $(echo 'test?.txt')
test1.txt test2.txt
$ ls $(echo 'test1,2.txt')
ls: cannot access test1,2.txt: No such file or directory


What's going on here? Why the pattern 1,2 does not work?







bash bash-expansion






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jun 6 at 6:36









Herosław MiraszewskiHerosław Miraszewski

464 bronze badges




464 bronze badges







  • 4





    Brace expansion isn't performed within single or double quotes

    – Sergiy Kolodyazhnyy
    Jun 6 at 6:47






  • 3





    @SergiyKolodyazhnyy The point of the question is that the ? is also quoted, and gets expanded after $(...) substitutes it, but the brace expansion doesn't.

    – Michael Homer
    Jun 6 at 6:48






  • 1





    @muru No, that's not the same issue. Here the order of expansions doesn't matter, what matters is which expansion takes place in which context. I wouldn't be surprised if this question was a duplicate, but I couldn't find it.

    – Gilles
    Jun 6 at 7:00






  • 1





    @mosvy Ksh and bash do expansions in the same order, but ksh does brace expansion in a case where bash doesn't do it at all. Zsh-with-globsubst does the same expansions as bash, but in a different order.

    – Gilles
    Jun 6 at 20:59






  • 1





    @Gilles no they don't. As documented and easily demonstrated, ksh (and zsh) will perform the brace expansion just before globbing. zsh-with-globsubst won't perform any brace expansion at all on the results of $-expansions: zsh -o globsubst -c 'a=/e*; b=/b*,/v*; echo $a; echo $b'.

    – mosvy
    Jun 6 at 22:14













  • 4





    Brace expansion isn't performed within single or double quotes

    – Sergiy Kolodyazhnyy
    Jun 6 at 6:47






  • 3





    @SergiyKolodyazhnyy The point of the question is that the ? is also quoted, and gets expanded after $(...) substitutes it, but the brace expansion doesn't.

    – Michael Homer
    Jun 6 at 6:48






  • 1





    @muru No, that's not the same issue. Here the order of expansions doesn't matter, what matters is which expansion takes place in which context. I wouldn't be surprised if this question was a duplicate, but I couldn't find it.

    – Gilles
    Jun 6 at 7:00






  • 1





    @mosvy Ksh and bash do expansions in the same order, but ksh does brace expansion in a case where bash doesn't do it at all. Zsh-with-globsubst does the same expansions as bash, but in a different order.

    – Gilles
    Jun 6 at 20:59






  • 1





    @Gilles no they don't. As documented and easily demonstrated, ksh (and zsh) will perform the brace expansion just before globbing. zsh-with-globsubst won't perform any brace expansion at all on the results of $-expansions: zsh -o globsubst -c 'a=/e*; b=/b*,/v*; echo $a; echo $b'.

    – mosvy
    Jun 6 at 22:14








4




4





Brace expansion isn't performed within single or double quotes

– Sergiy Kolodyazhnyy
Jun 6 at 6:47





Brace expansion isn't performed within single or double quotes

– Sergiy Kolodyazhnyy
Jun 6 at 6:47




3




3





@SergiyKolodyazhnyy The point of the question is that the ? is also quoted, and gets expanded after $(...) substitutes it, but the brace expansion doesn't.

– Michael Homer
Jun 6 at 6:48





@SergiyKolodyazhnyy The point of the question is that the ? is also quoted, and gets expanded after $(...) substitutes it, but the brace expansion doesn't.

– Michael Homer
Jun 6 at 6:48




1




1





@muru No, that's not the same issue. Here the order of expansions doesn't matter, what matters is which expansion takes place in which context. I wouldn't be surprised if this question was a duplicate, but I couldn't find it.

– Gilles
Jun 6 at 7:00





@muru No, that's not the same issue. Here the order of expansions doesn't matter, what matters is which expansion takes place in which context. I wouldn't be surprised if this question was a duplicate, but I couldn't find it.

– Gilles
Jun 6 at 7:00




1




1





@mosvy Ksh and bash do expansions in the same order, but ksh does brace expansion in a case where bash doesn't do it at all. Zsh-with-globsubst does the same expansions as bash, but in a different order.

– Gilles
Jun 6 at 20:59





@mosvy Ksh and bash do expansions in the same order, but ksh does brace expansion in a case where bash doesn't do it at all. Zsh-with-globsubst does the same expansions as bash, but in a different order.

– Gilles
Jun 6 at 20:59




1




1





@Gilles no they don't. As documented and easily demonstrated, ksh (and zsh) will perform the brace expansion just before globbing. zsh-with-globsubst won't perform any brace expansion at all on the results of $-expansions: zsh -o globsubst -c 'a=/e*; b=/b*,/v*; echo $a; echo $b'.

– mosvy
Jun 6 at 22:14






@Gilles no they don't. As documented and easily demonstrated, ksh (and zsh) will perform the brace expansion just before globbing. zsh-with-globsubst won't perform any brace expansion at all on the results of $-expansions: zsh -o globsubst -c 'a=/e*; b=/b*,/v*; echo $a; echo $b'.

– mosvy
Jun 6 at 22:14











5 Answers
5






active

oldest

votes


















17














It's a combination of two things. First, brace expansion is not a pattern that matches file names: it's a purely textual substitution — see What is the difference between `a[bc]d` (brackets) and `ab,cd` (braces)? . Second, when you use the result of a command substitution outside double quotes (ls $(…)), what happens is only pattern matching (and word splitting: the “split+glob” operator), not a complete re-parsing.



With ls $(echo 'test?.txt'), the command echo 'test?.txt' outputs the string test?.txt (with a final newline). The command substitution results in the string test?.txt (without a final newline, because command substitution strips trailing newlines). This unquoted substitution undergoes word splitting, yielding a list consisting of the single string test?.txt since there are no whitespace characters (more precisely, no characters in $IFS) in it. Each element of this one-element list then undergoes conditional wildcard expansion, and since there is a wildcard character ? in the string the wildcard expansion does happen. Since the pattern test?.txt matches at least one file name, the list element test?.txt is replace by the list of file names that match the patterns, yielding the two-element list containing test1.txt and test2.txt. Finally ls is called with two arguments test1 and test2.



With ls $(echo 'test1,2'), the command echo 'test1,2' outputs the string test1,2 (with a final newline). The command substitution results in the string test1,2. This unquoted substitution undergoes word splitting, yielding a list consisting of the single string test1,2. Each element of this one-element list then undergoes conditional wildcard expansion, which does nothing (the element is left as is) since there is no wildcard character in the string. Thus ls is called with the single argument test1,2.



For comparison, here's what happens with ls $(echo test1,2). The command echo test1,2 outputs the string test1 test2 (with a final newline). The command substitution results in the string test1 test2 (without a final newline). This unquoted substitution undergoes word splitting, yielding two strings test1 and test2. Then, since neither of the strings contains a wildcard character, they're left alone, so ls is called with two arguments test1 and test2.






share|improve this answer




















  • 3





    Note that pdksh and ksh93 do perform brace expansion upon expansions (before globbing; not with noglob, but in the case of ksh93, still when braceexpand is turned off!)

    – Stéphane Chazelas
    Jun 6 at 7:10











  • You seem to forgot .txt in second explanation.

    – val
    Jun 7 at 16:21


















10















The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and filename expansion.




Brace expansion won't happen after command substitution. You can use eval to force another round of expansion:



eval echo $(echo '1,2lala')


It's result is:



1lala 2lala





share|improve this answer






























    6














    That problem is very specific to bash, and it's because they decided in bash to separate the brace expansion from filename expansion (globbing), and to perform it first, before all the other expansions.



    From the bash manpage:




    The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and pathname expansion.




    In your example, bash will only see your braces after it had performed the command substitution (the $(echo ...)), when it's just too late.



    This is different from all the other shells, which perform the brace expansion just before (and some even as a part of) pathname expansion (globbing). That includes but is not limited to csh where brace-expansions were first invented.



    $ csh -c 'ls `echo "test1,2.txt"`'
    test1.txt test2.txt
    $ ksh -c 'ls $(echo "test1,2.txt")'
    test1.txt test2.txt

    $ var=nope var1=one var2=two bash -c 'echo $var1,2'
    one two
    $ var=nope var1=one var2=two csh -c 'echo $var1,2'
    nope1 nope2


    The latter example is the same in csh, zsh, ksh93, mksh or fish.



    Also, notice that brace expansion as part of globbing is also available via the glob(3) library function (at least on Linux and all the BSDs), and in other independent implementations (eg. in perl: perl -le 'print join " ", <test1,2.txt>').



    Why that was done differently in bash has probably a story behind it, but FWIW I wasn't able to find any logical explanation, and I find all the post-hoc rationalizations unconvincing.






    share|improve this answer




















    • 3





      Note that perl used to invoke csh to expand globs, so it's not surprising that it still recognises the same globbing operators as csh

      – Stéphane Chazelas
      Jun 6 at 20:29


















    1














    Please try:::



    ls $(echo test1,2.txt)



    With a BackSlash. It works now. Also remove the like the earlier poster said, the quotes.
    The Dot is not for matching pattern, but to be taken literally as Period here.






    share|improve this answer























    • (1) The question asks “What’s going on here?  Why [does] the pattern 1,2” behave the way it does?  The question does not ask “How can I get a command using 1,2 to behave the way the command with ? works?”  You are answering the wrong question.   (2) The backslash has nothing to do with it.  Your command works the way it does because you have removed the quotes that were in the command in the question.

      – G-Man
      Jun 8 at 20:34


















    0














    It works if you remove the quotes



    $ ls $(echo test1,2)
    test1 test2





    share|improve this answer


















    • 9





      The expansion is now happening before the command substitution, which I don't think is what the question is asking for (compare what's happening with ?).

      – Michael Homer
      Jun 6 at 6:48













    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',
    autoActivateHeartbeat: false,
    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%2f523209%2fwhy-1-2-printed-by-a-command-in-is-not-interpolated%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    5 Answers
    5






    active

    oldest

    votes








    5 Answers
    5






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    17














    It's a combination of two things. First, brace expansion is not a pattern that matches file names: it's a purely textual substitution — see What is the difference between `a[bc]d` (brackets) and `ab,cd` (braces)? . Second, when you use the result of a command substitution outside double quotes (ls $(…)), what happens is only pattern matching (and word splitting: the “split+glob” operator), not a complete re-parsing.



    With ls $(echo 'test?.txt'), the command echo 'test?.txt' outputs the string test?.txt (with a final newline). The command substitution results in the string test?.txt (without a final newline, because command substitution strips trailing newlines). This unquoted substitution undergoes word splitting, yielding a list consisting of the single string test?.txt since there are no whitespace characters (more precisely, no characters in $IFS) in it. Each element of this one-element list then undergoes conditional wildcard expansion, and since there is a wildcard character ? in the string the wildcard expansion does happen. Since the pattern test?.txt matches at least one file name, the list element test?.txt is replace by the list of file names that match the patterns, yielding the two-element list containing test1.txt and test2.txt. Finally ls is called with two arguments test1 and test2.



    With ls $(echo 'test1,2'), the command echo 'test1,2' outputs the string test1,2 (with a final newline). The command substitution results in the string test1,2. This unquoted substitution undergoes word splitting, yielding a list consisting of the single string test1,2. Each element of this one-element list then undergoes conditional wildcard expansion, which does nothing (the element is left as is) since there is no wildcard character in the string. Thus ls is called with the single argument test1,2.



    For comparison, here's what happens with ls $(echo test1,2). The command echo test1,2 outputs the string test1 test2 (with a final newline). The command substitution results in the string test1 test2 (without a final newline). This unquoted substitution undergoes word splitting, yielding two strings test1 and test2. Then, since neither of the strings contains a wildcard character, they're left alone, so ls is called with two arguments test1 and test2.






    share|improve this answer




















    • 3





      Note that pdksh and ksh93 do perform brace expansion upon expansions (before globbing; not with noglob, but in the case of ksh93, still when braceexpand is turned off!)

      – Stéphane Chazelas
      Jun 6 at 7:10











    • You seem to forgot .txt in second explanation.

      – val
      Jun 7 at 16:21















    17














    It's a combination of two things. First, brace expansion is not a pattern that matches file names: it's a purely textual substitution — see What is the difference between `a[bc]d` (brackets) and `ab,cd` (braces)? . Second, when you use the result of a command substitution outside double quotes (ls $(…)), what happens is only pattern matching (and word splitting: the “split+glob” operator), not a complete re-parsing.



    With ls $(echo 'test?.txt'), the command echo 'test?.txt' outputs the string test?.txt (with a final newline). The command substitution results in the string test?.txt (without a final newline, because command substitution strips trailing newlines). This unquoted substitution undergoes word splitting, yielding a list consisting of the single string test?.txt since there are no whitespace characters (more precisely, no characters in $IFS) in it. Each element of this one-element list then undergoes conditional wildcard expansion, and since there is a wildcard character ? in the string the wildcard expansion does happen. Since the pattern test?.txt matches at least one file name, the list element test?.txt is replace by the list of file names that match the patterns, yielding the two-element list containing test1.txt and test2.txt. Finally ls is called with two arguments test1 and test2.



    With ls $(echo 'test1,2'), the command echo 'test1,2' outputs the string test1,2 (with a final newline). The command substitution results in the string test1,2. This unquoted substitution undergoes word splitting, yielding a list consisting of the single string test1,2. Each element of this one-element list then undergoes conditional wildcard expansion, which does nothing (the element is left as is) since there is no wildcard character in the string. Thus ls is called with the single argument test1,2.



    For comparison, here's what happens with ls $(echo test1,2). The command echo test1,2 outputs the string test1 test2 (with a final newline). The command substitution results in the string test1 test2 (without a final newline). This unquoted substitution undergoes word splitting, yielding two strings test1 and test2. Then, since neither of the strings contains a wildcard character, they're left alone, so ls is called with two arguments test1 and test2.






    share|improve this answer




















    • 3





      Note that pdksh and ksh93 do perform brace expansion upon expansions (before globbing; not with noglob, but in the case of ksh93, still when braceexpand is turned off!)

      – Stéphane Chazelas
      Jun 6 at 7:10











    • You seem to forgot .txt in second explanation.

      – val
      Jun 7 at 16:21













    17












    17








    17







    It's a combination of two things. First, brace expansion is not a pattern that matches file names: it's a purely textual substitution — see What is the difference between `a[bc]d` (brackets) and `ab,cd` (braces)? . Second, when you use the result of a command substitution outside double quotes (ls $(…)), what happens is only pattern matching (and word splitting: the “split+glob” operator), not a complete re-parsing.



    With ls $(echo 'test?.txt'), the command echo 'test?.txt' outputs the string test?.txt (with a final newline). The command substitution results in the string test?.txt (without a final newline, because command substitution strips trailing newlines). This unquoted substitution undergoes word splitting, yielding a list consisting of the single string test?.txt since there are no whitespace characters (more precisely, no characters in $IFS) in it. Each element of this one-element list then undergoes conditional wildcard expansion, and since there is a wildcard character ? in the string the wildcard expansion does happen. Since the pattern test?.txt matches at least one file name, the list element test?.txt is replace by the list of file names that match the patterns, yielding the two-element list containing test1.txt and test2.txt. Finally ls is called with two arguments test1 and test2.



    With ls $(echo 'test1,2'), the command echo 'test1,2' outputs the string test1,2 (with a final newline). The command substitution results in the string test1,2. This unquoted substitution undergoes word splitting, yielding a list consisting of the single string test1,2. Each element of this one-element list then undergoes conditional wildcard expansion, which does nothing (the element is left as is) since there is no wildcard character in the string. Thus ls is called with the single argument test1,2.



    For comparison, here's what happens with ls $(echo test1,2). The command echo test1,2 outputs the string test1 test2 (with a final newline). The command substitution results in the string test1 test2 (without a final newline). This unquoted substitution undergoes word splitting, yielding two strings test1 and test2. Then, since neither of the strings contains a wildcard character, they're left alone, so ls is called with two arguments test1 and test2.






    share|improve this answer















    It's a combination of two things. First, brace expansion is not a pattern that matches file names: it's a purely textual substitution — see What is the difference between `a[bc]d` (brackets) and `ab,cd` (braces)? . Second, when you use the result of a command substitution outside double quotes (ls $(…)), what happens is only pattern matching (and word splitting: the “split+glob” operator), not a complete re-parsing.



    With ls $(echo 'test?.txt'), the command echo 'test?.txt' outputs the string test?.txt (with a final newline). The command substitution results in the string test?.txt (without a final newline, because command substitution strips trailing newlines). This unquoted substitution undergoes word splitting, yielding a list consisting of the single string test?.txt since there are no whitespace characters (more precisely, no characters in $IFS) in it. Each element of this one-element list then undergoes conditional wildcard expansion, and since there is a wildcard character ? in the string the wildcard expansion does happen. Since the pattern test?.txt matches at least one file name, the list element test?.txt is replace by the list of file names that match the patterns, yielding the two-element list containing test1.txt and test2.txt. Finally ls is called with two arguments test1 and test2.



    With ls $(echo 'test1,2'), the command echo 'test1,2' outputs the string test1,2 (with a final newline). The command substitution results in the string test1,2. This unquoted substitution undergoes word splitting, yielding a list consisting of the single string test1,2. Each element of this one-element list then undergoes conditional wildcard expansion, which does nothing (the element is left as is) since there is no wildcard character in the string. Thus ls is called with the single argument test1,2.



    For comparison, here's what happens with ls $(echo test1,2). The command echo test1,2 outputs the string test1 test2 (with a final newline). The command substitution results in the string test1 test2 (without a final newline). This unquoted substitution undergoes word splitting, yielding two strings test1 and test2. Then, since neither of the strings contains a wildcard character, they're left alone, so ls is called with two arguments test1 and test2.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jun 7 at 8:44









    fra-san

    2,2901 gold badge8 silver badges24 bronze badges




    2,2901 gold badge8 silver badges24 bronze badges










    answered Jun 6 at 6:59









    GillesGilles

    560k134 gold badges1153 silver badges1659 bronze badges




    560k134 gold badges1153 silver badges1659 bronze badges







    • 3





      Note that pdksh and ksh93 do perform brace expansion upon expansions (before globbing; not with noglob, but in the case of ksh93, still when braceexpand is turned off!)

      – Stéphane Chazelas
      Jun 6 at 7:10











    • You seem to forgot .txt in second explanation.

      – val
      Jun 7 at 16:21












    • 3





      Note that pdksh and ksh93 do perform brace expansion upon expansions (before globbing; not with noglob, but in the case of ksh93, still when braceexpand is turned off!)

      – Stéphane Chazelas
      Jun 6 at 7:10











    • You seem to forgot .txt in second explanation.

      – val
      Jun 7 at 16:21







    3




    3





    Note that pdksh and ksh93 do perform brace expansion upon expansions (before globbing; not with noglob, but in the case of ksh93, still when braceexpand is turned off!)

    – Stéphane Chazelas
    Jun 6 at 7:10





    Note that pdksh and ksh93 do perform brace expansion upon expansions (before globbing; not with noglob, but in the case of ksh93, still when braceexpand is turned off!)

    – Stéphane Chazelas
    Jun 6 at 7:10













    You seem to forgot .txt in second explanation.

    – val
    Jun 7 at 16:21





    You seem to forgot .txt in second explanation.

    – val
    Jun 7 at 16:21













    10















    The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and filename expansion.




    Brace expansion won't happen after command substitution. You can use eval to force another round of expansion:



    eval echo $(echo '1,2lala')


    It's result is:



    1lala 2lala





    share|improve this answer



























      10















      The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and filename expansion.




      Brace expansion won't happen after command substitution. You can use eval to force another round of expansion:



      eval echo $(echo '1,2lala')


      It's result is:



      1lala 2lala





      share|improve this answer

























        10












        10








        10








        The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and filename expansion.




        Brace expansion won't happen after command substitution. You can use eval to force another round of expansion:



        eval echo $(echo '1,2lala')


        It's result is:



        1lala 2lala





        share|improve this answer














        The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and filename expansion.




        Brace expansion won't happen after command substitution. You can use eval to force another round of expansion:



        eval echo $(echo '1,2lala')


        It's result is:



        1lala 2lala






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jun 6 at 6:51









        dedowsdidedowsdi

        8282 silver badges8 bronze badges




        8282 silver badges8 bronze badges





















            6














            That problem is very specific to bash, and it's because they decided in bash to separate the brace expansion from filename expansion (globbing), and to perform it first, before all the other expansions.



            From the bash manpage:




            The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and pathname expansion.




            In your example, bash will only see your braces after it had performed the command substitution (the $(echo ...)), when it's just too late.



            This is different from all the other shells, which perform the brace expansion just before (and some even as a part of) pathname expansion (globbing). That includes but is not limited to csh where brace-expansions were first invented.



            $ csh -c 'ls `echo "test1,2.txt"`'
            test1.txt test2.txt
            $ ksh -c 'ls $(echo "test1,2.txt")'
            test1.txt test2.txt

            $ var=nope var1=one var2=two bash -c 'echo $var1,2'
            one two
            $ var=nope var1=one var2=two csh -c 'echo $var1,2'
            nope1 nope2


            The latter example is the same in csh, zsh, ksh93, mksh or fish.



            Also, notice that brace expansion as part of globbing is also available via the glob(3) library function (at least on Linux and all the BSDs), and in other independent implementations (eg. in perl: perl -le 'print join " ", <test1,2.txt>').



            Why that was done differently in bash has probably a story behind it, but FWIW I wasn't able to find any logical explanation, and I find all the post-hoc rationalizations unconvincing.






            share|improve this answer




















            • 3





              Note that perl used to invoke csh to expand globs, so it's not surprising that it still recognises the same globbing operators as csh

              – Stéphane Chazelas
              Jun 6 at 20:29















            6














            That problem is very specific to bash, and it's because they decided in bash to separate the brace expansion from filename expansion (globbing), and to perform it first, before all the other expansions.



            From the bash manpage:




            The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and pathname expansion.




            In your example, bash will only see your braces after it had performed the command substitution (the $(echo ...)), when it's just too late.



            This is different from all the other shells, which perform the brace expansion just before (and some even as a part of) pathname expansion (globbing). That includes but is not limited to csh where brace-expansions were first invented.



            $ csh -c 'ls `echo "test1,2.txt"`'
            test1.txt test2.txt
            $ ksh -c 'ls $(echo "test1,2.txt")'
            test1.txt test2.txt

            $ var=nope var1=one var2=two bash -c 'echo $var1,2'
            one two
            $ var=nope var1=one var2=two csh -c 'echo $var1,2'
            nope1 nope2


            The latter example is the same in csh, zsh, ksh93, mksh or fish.



            Also, notice that brace expansion as part of globbing is also available via the glob(3) library function (at least on Linux and all the BSDs), and in other independent implementations (eg. in perl: perl -le 'print join " ", <test1,2.txt>').



            Why that was done differently in bash has probably a story behind it, but FWIW I wasn't able to find any logical explanation, and I find all the post-hoc rationalizations unconvincing.






            share|improve this answer




















            • 3





              Note that perl used to invoke csh to expand globs, so it's not surprising that it still recognises the same globbing operators as csh

              – Stéphane Chazelas
              Jun 6 at 20:29













            6












            6








            6







            That problem is very specific to bash, and it's because they decided in bash to separate the brace expansion from filename expansion (globbing), and to perform it first, before all the other expansions.



            From the bash manpage:




            The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and pathname expansion.




            In your example, bash will only see your braces after it had performed the command substitution (the $(echo ...)), when it's just too late.



            This is different from all the other shells, which perform the brace expansion just before (and some even as a part of) pathname expansion (globbing). That includes but is not limited to csh where brace-expansions were first invented.



            $ csh -c 'ls `echo "test1,2.txt"`'
            test1.txt test2.txt
            $ ksh -c 'ls $(echo "test1,2.txt")'
            test1.txt test2.txt

            $ var=nope var1=one var2=two bash -c 'echo $var1,2'
            one two
            $ var=nope var1=one var2=two csh -c 'echo $var1,2'
            nope1 nope2


            The latter example is the same in csh, zsh, ksh93, mksh or fish.



            Also, notice that brace expansion as part of globbing is also available via the glob(3) library function (at least on Linux and all the BSDs), and in other independent implementations (eg. in perl: perl -le 'print join " ", <test1,2.txt>').



            Why that was done differently in bash has probably a story behind it, but FWIW I wasn't able to find any logical explanation, and I find all the post-hoc rationalizations unconvincing.






            share|improve this answer















            That problem is very specific to bash, and it's because they decided in bash to separate the brace expansion from filename expansion (globbing), and to perform it first, before all the other expansions.



            From the bash manpage:




            The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and pathname expansion.




            In your example, bash will only see your braces after it had performed the command substitution (the $(echo ...)), when it's just too late.



            This is different from all the other shells, which perform the brace expansion just before (and some even as a part of) pathname expansion (globbing). That includes but is not limited to csh where brace-expansions were first invented.



            $ csh -c 'ls `echo "test1,2.txt"`'
            test1.txt test2.txt
            $ ksh -c 'ls $(echo "test1,2.txt")'
            test1.txt test2.txt

            $ var=nope var1=one var2=two bash -c 'echo $var1,2'
            one two
            $ var=nope var1=one var2=two csh -c 'echo $var1,2'
            nope1 nope2


            The latter example is the same in csh, zsh, ksh93, mksh or fish.



            Also, notice that brace expansion as part of globbing is also available via the glob(3) library function (at least on Linux and all the BSDs), and in other independent implementations (eg. in perl: perl -le 'print join " ", <test1,2.txt>').



            Why that was done differently in bash has probably a story behind it, but FWIW I wasn't able to find any logical explanation, and I find all the post-hoc rationalizations unconvincing.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jun 6 at 20:06









            Stéphane Chazelas

            322k57 gold badges622 silver badges989 bronze badges




            322k57 gold badges622 silver badges989 bronze badges










            answered Jun 6 at 16:00









            mosvymosvy

            14.1k2 gold badges15 silver badges47 bronze badges




            14.1k2 gold badges15 silver badges47 bronze badges







            • 3





              Note that perl used to invoke csh to expand globs, so it's not surprising that it still recognises the same globbing operators as csh

              – Stéphane Chazelas
              Jun 6 at 20:29












            • 3





              Note that perl used to invoke csh to expand globs, so it's not surprising that it still recognises the same globbing operators as csh

              – Stéphane Chazelas
              Jun 6 at 20:29







            3




            3





            Note that perl used to invoke csh to expand globs, so it's not surprising that it still recognises the same globbing operators as csh

            – Stéphane Chazelas
            Jun 6 at 20:29





            Note that perl used to invoke csh to expand globs, so it's not surprising that it still recognises the same globbing operators as csh

            – Stéphane Chazelas
            Jun 6 at 20:29











            1














            Please try:::



            ls $(echo test1,2.txt)



            With a BackSlash. It works now. Also remove the like the earlier poster said, the quotes.
            The Dot is not for matching pattern, but to be taken literally as Period here.






            share|improve this answer























            • (1) The question asks “What’s going on here?  Why [does] the pattern 1,2” behave the way it does?  The question does not ask “How can I get a command using 1,2 to behave the way the command with ? works?”  You are answering the wrong question.   (2) The backslash has nothing to do with it.  Your command works the way it does because you have removed the quotes that were in the command in the question.

              – G-Man
              Jun 8 at 20:34















            1














            Please try:::



            ls $(echo test1,2.txt)



            With a BackSlash. It works now. Also remove the like the earlier poster said, the quotes.
            The Dot is not for matching pattern, but to be taken literally as Period here.






            share|improve this answer























            • (1) The question asks “What’s going on here?  Why [does] the pattern 1,2” behave the way it does?  The question does not ask “How can I get a command using 1,2 to behave the way the command with ? works?”  You are answering the wrong question.   (2) The backslash has nothing to do with it.  Your command works the way it does because you have removed the quotes that were in the command in the question.

              – G-Man
              Jun 8 at 20:34













            1












            1








            1







            Please try:::



            ls $(echo test1,2.txt)



            With a BackSlash. It works now. Also remove the like the earlier poster said, the quotes.
            The Dot is not for matching pattern, but to be taken literally as Period here.






            share|improve this answer













            Please try:::



            ls $(echo test1,2.txt)



            With a BackSlash. It works now. Also remove the like the earlier poster said, the quotes.
            The Dot is not for matching pattern, but to be taken literally as Period here.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jun 8 at 12:56









            mkziamkzia

            392 bronze badges




            392 bronze badges












            • (1) The question asks “What’s going on here?  Why [does] the pattern 1,2” behave the way it does?  The question does not ask “How can I get a command using 1,2 to behave the way the command with ? works?”  You are answering the wrong question.   (2) The backslash has nothing to do with it.  Your command works the way it does because you have removed the quotes that were in the command in the question.

              – G-Man
              Jun 8 at 20:34

















            • (1) The question asks “What’s going on here?  Why [does] the pattern 1,2” behave the way it does?  The question does not ask “How can I get a command using 1,2 to behave the way the command with ? works?”  You are answering the wrong question.   (2) The backslash has nothing to do with it.  Your command works the way it does because you have removed the quotes that were in the command in the question.

              – G-Man
              Jun 8 at 20:34
















            (1) The question asks “What’s going on here?  Why [does] the pattern 1,2” behave the way it does?  The question does not ask “How can I get a command using 1,2 to behave the way the command with ? works?”  You are answering the wrong question.   (2) The backslash has nothing to do with it.  Your command works the way it does because you have removed the quotes that were in the command in the question.

            – G-Man
            Jun 8 at 20:34





            (1) The question asks “What’s going on here?  Why [does] the pattern 1,2” behave the way it does?  The question does not ask “How can I get a command using 1,2 to behave the way the command with ? works?”  You are answering the wrong question.   (2) The backslash has nothing to do with it.  Your command works the way it does because you have removed the quotes that were in the command in the question.

            – G-Man
            Jun 8 at 20:34











            0














            It works if you remove the quotes



            $ ls $(echo test1,2)
            test1 test2





            share|improve this answer


















            • 9





              The expansion is now happening before the command substitution, which I don't think is what the question is asking for (compare what's happening with ?).

              – Michael Homer
              Jun 6 at 6:48















            0














            It works if you remove the quotes



            $ ls $(echo test1,2)
            test1 test2





            share|improve this answer


















            • 9





              The expansion is now happening before the command substitution, which I don't think is what the question is asking for (compare what's happening with ?).

              – Michael Homer
              Jun 6 at 6:48













            0












            0








            0







            It works if you remove the quotes



            $ ls $(echo test1,2)
            test1 test2





            share|improve this answer













            It works if you remove the quotes



            $ ls $(echo test1,2)
            test1 test2






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jun 6 at 6:43









            darxmurfdarxmurf

            61711 bronze badges




            61711 bronze badges







            • 9





              The expansion is now happening before the command substitution, which I don't think is what the question is asking for (compare what's happening with ?).

              – Michael Homer
              Jun 6 at 6:48












            • 9





              The expansion is now happening before the command substitution, which I don't think is what the question is asking for (compare what's happening with ?).

              – Michael Homer
              Jun 6 at 6:48







            9




            9





            The expansion is now happening before the command substitution, which I don't think is what the question is asking for (compare what's happening with ?).

            – Michael Homer
            Jun 6 at 6:48





            The expansion is now happening before the command substitution, which I don't think is what the question is asking for (compare what's happening with ?).

            – Michael Homer
            Jun 6 at 6:48

















            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.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f523209%2fwhy-1-2-printed-by-a-command-in-is-not-interpolated%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

            How to write a 12-bar blues melodyI-IV-V blues progressionHow to play the bridges in a standard blues progressionHow does Gdim7 fit in C# minor?question on a certain chord progressionMusicology of Melody12 bar blues, spread rhythm: alternative to 6th chord to avoid finger stretchChord progressions/ Root key/ MelodiesHow to put chords (POP-EDM) under a given lead vocal melody (starting from a good knowledge in music theory)Are there “rules” for improvising with the minor pentatonic scale over 12-bar shuffle?Confusion about blues scale and chords

            What if the end-user didn't have the required library?What is setup.py?What is a clean, pythonic way to have multiple constructors in Python?What does Ruby have that Python doesn't, and vice versa?What is the reason for having '//' in Python?How do I create a namespace package in Python?How to package shared objects that python modules depend on?setuptools vs. distutils: why is distutils still a thing?Navigation in Windows 10 vs code not going to virtualenv library when the same library is installed at user levelPython create package for local usePackaging a project that uses multiple python versionsWhy is permission denied on pip install except for when “--user” is included at end of command?

            Esgonzo ibérico Índice Descrición Distribución Hábitat Ameazas Notas Véxase tamén "Acerca dos nomes dos anfibios e réptiles galegos""Chalcides bedriagai"Chalcides bedriagai en Carrascal, L. M. Salvador, A. (Eds). Enciclopedia virtual de los vertebrados españoles. Museo Nacional de Ciencias Naturales, Madrid. España.Fotos