Expansion with *.txt in the shell doesn't work if no .txt file existsBash prompt doesn't print until I interact with console againCreating a very simple upstart scriptWhy no shell expansion?Unique sorting: Redirect output to the same fileWindows FINDSTR Ubuntu equivalent to search .csvDo GUI based application execute shell commands in the background?Terminal closes immediately after trying to change shell script back to bashsource syntax errorWhy do I get different output from the same commands? (redirect and piping)txt to pcap file conversion using sed and xxd

“The Fourier transform cannot measure two phases at the same frequency.” Why not?

Tile the chessboard with four-colored triominoes

Could an areostationary satellite help locate asteroids?

Launch capabilities of GSLV Mark III

Why do proponents of guns oppose gun competency tests?

Can I enter a rental property without giving notice if I'm afraid a tenant may be hurt?

Plato and the knowledge of the forms

The meaning of "scale" in "because diversions scale so easily wealth becomes concentrated"

Does the length of a password for Wi-Fi affect speed?

Is there a way to improve my grade after graduation?

What are the function of EM and EN spaces?

Our group keeps dying during the Lost Mine of Phandelver campaign. What are we doing wrong?

Write The Shortest Program to Calculate Height of a Binary Tree

I was contacted by a private bank overseas to get my inheritance

Not been paid even after reminding the Treasurer; what should I do?

Repeated! Factorials!

Why do my fried eggs start browning very fast?

How to call made-up data?

What is the difference between these two share classes of an ETF?

Why did the US Airways Flight 1549 passengers stay on the wings?

Why does putting a dot after the URL remove login information?

Why should I "believe in" weak solutions to PDEs?

Does a 4 bladed prop have almost twice the thrust of a 2 bladed prop?

Do some languages mention the top limit of a range first?



Expansion with *.txt in the shell doesn't work if no .txt file exists


Bash prompt doesn't print until I interact with console againCreating a very simple upstart scriptWhy no shell expansion?Unique sorting: Redirect output to the same fileWindows FINDSTR Ubuntu equivalent to search .csvDo GUI based application execute shell commands in the background?Terminal closes immediately after trying to change shell script back to bashsource syntax errorWhy do I get different output from the same commands? (redirect and piping)txt to pcap file conversion using sed and xxd






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








10















I was playing around with expansion, and I noticed a peculiar behavior. I tried doing:



echo ./*.txt



And I didn't have any .txt file in my current directory. The output I got was:



./*.txt



I'm just curious: Why did I get this? I was expecting to not get any output.



PS: When I did have a .txt file, the expansion was correctly interpreted. In other words, say I had a file, smthn.txt, the echo actually echoed current_directory/smthn.txt.










share|improve this question
































    10















    I was playing around with expansion, and I noticed a peculiar behavior. I tried doing:



    echo ./*.txt



    And I didn't have any .txt file in my current directory. The output I got was:



    ./*.txt



    I'm just curious: Why did I get this? I was expecting to not get any output.



    PS: When I did have a .txt file, the expansion was correctly interpreted. In other words, say I had a file, smthn.txt, the echo actually echoed current_directory/smthn.txt.










    share|improve this question




























      10












      10








      10








      I was playing around with expansion, and I noticed a peculiar behavior. I tried doing:



      echo ./*.txt



      And I didn't have any .txt file in my current directory. The output I got was:



      ./*.txt



      I'm just curious: Why did I get this? I was expecting to not get any output.



      PS: When I did have a .txt file, the expansion was correctly interpreted. In other words, say I had a file, smthn.txt, the echo actually echoed current_directory/smthn.txt.










      share|improve this question
















      I was playing around with expansion, and I noticed a peculiar behavior. I tried doing:



      echo ./*.txt



      And I didn't have any .txt file in my current directory. The output I got was:



      ./*.txt



      I'm just curious: Why did I get this? I was expecting to not get any output.



      PS: When I did have a .txt file, the expansion was correctly interpreted. In other words, say I had a file, smthn.txt, the echo actually echoed current_directory/smthn.txt.







      command-line bash






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jul 27 at 13:20









      Peter Mortensen

      1,0272 gold badges11 silver badges17 bronze badges




      1,0272 gold badges11 silver badges17 bronze badges










      asked Jul 26 at 8:45









      user10796158user10796158

      1775 bronze badges




      1775 bronze badges























          3 Answers
          3






          active

          oldest

          votes


















          15














          Adapting from the bash shell man page,




          bash scans each word for the characters *, ?, and [. If one of
          these characters appears, then the word is regarded as a pattern, and
          replaced with an alphabetically sorted list of filenames matching
          the pattern. If no matching filenames are found, and the shell
          option nullglob is not enabled, the word is left unchanged. If the
          nullglob option is set, and no matches are found, the word is
          removed.




          In this case I presume nullglob is not enabled, so the word is left unchanged - hence the output you see.






          share|improve this answer






















          • 2





            You can change the behaviour as follows: shopt -s nullglob will yield empty strings for unmatched patterns and shopt -u nullglob (standard setting) will yield the pattern itself.

            – PerlDuck
            Jul 26 at 9:03



















          13















          I was expecting to not get any output.




          If nullglob were the default, many commands would behave quite unexpectedly, because it is (perhaps unfortunately) common that commands treat the case of zero filename arguments in a qualitatively different way than the case of one or more filename arguments.



          Suppose you've enabled nullglob (shopt -s nullglob) and you're in a directory where no files match *.txt. Then *.txt will indeed expand to nothing--not an empty field, but no fields at all--as you expected. But that would have these results:




          • ls *.txt would list all the files in the current directory (except hidden files), because that's what ls does when you don't pass it any filename arguments.


          • cat *.txt would read from standard input, because when cat has no filename arguments, it's as if you ran cat -. If running interactively, it sits around waiting for input. Many commands behave this way.


          • cp *.txt dest/ would fail with the error cp: missing destination file operand after 'dest/'. This isn't a disaster, but it's confusing and quite different from the silent success that is probably desired.


          • file *.txt, and various other programs with no special behavior for the case of zero filename arguments, would still fail with an error or usage message when none are passed.

          • Even cases that intuitively feel like they should work often wouldn't. printf 'Got file: "%s"n' *.txt would print Got file: "" instead of nothing.

          • Accidental failure to quote occurrences of *, ?, and [ that aren't intended to be expanded by the shell would more often produce obviously wrong results, but in ways that might be difficult to figure out. For example, if no filenames in the current directory started with gedit, then apt list gedit* (where apt list 'gedit*' was intended) would become just apt list and list all available packages.

          So it's good that you don't get this behavior without requesting it. Probably the most common practical situation that is actually simplified by nullglob is for f in *.txt. See also this question (which Sergiy Kolodyazhnyy's answer linked to).



          The harder question to answer is why failglob--where it's an expansion error to have a glob that doesn't match any files--isn't the default in bash. I believe Sergiy Kolodyazhnyy's answer captures the reason for this even without addressing it directly. Retaining unexpanding globs without producing an expansion error is (perhaps unfortunately) the standardized behavior, and it is also traditional, and thus expected, behavior. Although bash doesn't attempt to be fully POSIX-compliant unless it is invoked with the name sh or passed the --posix option, many of its design choices even when not in POSIX mode follow POSIX directly. They had to pick some behavior, and there are downsides associated with going against users' expectations.




          I think this is the least historically influential aspect of the matter so I've saved it for last... but it is worth mentioning that there's something a bit conceptually odd about nullglob behavior.



          nullglob seems elegant at first because, syntactically, it treats the case of zero matching files no differently from the case of one, two, or any other number. The commands we run, which globs expand into arguments for, don't tend to treat them the same, as detailed above. But syntactically this at least feels right, which I think is the motivation for your question.



          And yet, there is another, more subtle inconsistency that nullglob doesn't address--that it actually amplifies. The case of zero globbing characters ("wildcards") is treated profoundly differently from that of one, or two, or any other number. For example, with shopt -s nullglob, if ab?d?f doesn't match any files, it is removed; if ab?d doesn't match any files, it is removed; but if ab doesn't match any files (i.e., if there is no file whose name is exactly ab) it is still not removed. Of course, it would be a disaster if it were removed, because it might not be intended to refer to an existing file in the current directory at all; it might not even refer to a file. But this still eliminates any hope for total consistency.



          The three behaviors bash provides--the default of treating globs that don't match any files as though they weren't globs and passing them unexpanded, the behavior you expected of treating them (if you'll pardon this odd turn of phrase) as signifying all zero of the files that do match (nullglob), and the safe behavior of considering them errors (failglob)--all represent different approaches to the ambiguity inherent in the shell not being able to know if any particular word is intended to be a filename. The shell performs its expansions without knowledge of how the particular commands you call with it will treat their arguments.



          This is one of many instances of separation of concerns. In systems whose design follows the Unix philosophy, each part is intended to do one thing and do it well. The shell processes text into commands and arguments and invokes those commands, most of which are external to the shell itself. This tends to be a lot nicer and more versatile than systems where the external commands are themselves responsible for performing those transformations (as with the traditional command processors in DOS and Windows). But it has its occasional downsides.






          share|improve this answer



























          • Apparently, bash-4.3.39(2) doesn't have failglob. So it can't the default because it hasn't always been supported.

            – Ruslan
            Jul 28 at 6:48



















          6














          The main reason is because this is standard behavior specified by POSIX - the standard which covers shell command language and among other things pattern matching ( shells such as bash, dash shell - Ubuntu's default /bin/sh, and ksh follow this standard ). From section 2.13.3 Patterns Used for Filename Expansion:




          If the pattern does not match any existing filenames or pathnames, the pattern string shall be left unchanged.




          This of course has a side effect - matching filename that may be literally *.txt. The nullglob option in bash and zsh can help: if that option is enabled via shopt -s nullglob (and it is not enabled by default which applies to this question), then globstar will be expanded to empty string when no matching filenames found. ksh93 has its own advanced pattern matching mechanism which achieves the same effect ~(N)*.txt



          See also Why is nullglob not default?






          share|improve this answer





























            Your Answer








            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "89"
            ;
            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: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            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%2faskubuntu.com%2fquestions%2f1161180%2fexpansion-with-txt-in-the-shell-doesnt-work-if-no-txt-file-exists%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            15














            Adapting from the bash shell man page,




            bash scans each word for the characters *, ?, and [. If one of
            these characters appears, then the word is regarded as a pattern, and
            replaced with an alphabetically sorted list of filenames matching
            the pattern. If no matching filenames are found, and the shell
            option nullglob is not enabled, the word is left unchanged. If the
            nullglob option is set, and no matches are found, the word is
            removed.




            In this case I presume nullglob is not enabled, so the word is left unchanged - hence the output you see.






            share|improve this answer






















            • 2





              You can change the behaviour as follows: shopt -s nullglob will yield empty strings for unmatched patterns and shopt -u nullglob (standard setting) will yield the pattern itself.

              – PerlDuck
              Jul 26 at 9:03
















            15














            Adapting from the bash shell man page,




            bash scans each word for the characters *, ?, and [. If one of
            these characters appears, then the word is regarded as a pattern, and
            replaced with an alphabetically sorted list of filenames matching
            the pattern. If no matching filenames are found, and the shell
            option nullglob is not enabled, the word is left unchanged. If the
            nullglob option is set, and no matches are found, the word is
            removed.




            In this case I presume nullglob is not enabled, so the word is left unchanged - hence the output you see.






            share|improve this answer






















            • 2





              You can change the behaviour as follows: shopt -s nullglob will yield empty strings for unmatched patterns and shopt -u nullglob (standard setting) will yield the pattern itself.

              – PerlDuck
              Jul 26 at 9:03














            15












            15








            15







            Adapting from the bash shell man page,




            bash scans each word for the characters *, ?, and [. If one of
            these characters appears, then the word is regarded as a pattern, and
            replaced with an alphabetically sorted list of filenames matching
            the pattern. If no matching filenames are found, and the shell
            option nullglob is not enabled, the word is left unchanged. If the
            nullglob option is set, and no matches are found, the word is
            removed.




            In this case I presume nullglob is not enabled, so the word is left unchanged - hence the output you see.






            share|improve this answer















            Adapting from the bash shell man page,




            bash scans each word for the characters *, ?, and [. If one of
            these characters appears, then the word is regarded as a pattern, and
            replaced with an alphabetically sorted list of filenames matching
            the pattern. If no matching filenames are found, and the shell
            option nullglob is not enabled, the word is left unchanged. If the
            nullglob option is set, and no matches are found, the word is
            removed.




            In this case I presume nullglob is not enabled, so the word is left unchanged - hence the output you see.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jul 26 at 8:58









            PerlDuck

            9,1931 gold badge18 silver badges44 bronze badges




            9,1931 gold badge18 silver badges44 bronze badges










            answered Jul 26 at 8:57









            ColinBColinB

            3182 silver badges7 bronze badges




            3182 silver badges7 bronze badges










            • 2





              You can change the behaviour as follows: shopt -s nullglob will yield empty strings for unmatched patterns and shopt -u nullglob (standard setting) will yield the pattern itself.

              – PerlDuck
              Jul 26 at 9:03













            • 2





              You can change the behaviour as follows: shopt -s nullglob will yield empty strings for unmatched patterns and shopt -u nullglob (standard setting) will yield the pattern itself.

              – PerlDuck
              Jul 26 at 9:03








            2




            2





            You can change the behaviour as follows: shopt -s nullglob will yield empty strings for unmatched patterns and shopt -u nullglob (standard setting) will yield the pattern itself.

            – PerlDuck
            Jul 26 at 9:03






            You can change the behaviour as follows: shopt -s nullglob will yield empty strings for unmatched patterns and shopt -u nullglob (standard setting) will yield the pattern itself.

            – PerlDuck
            Jul 26 at 9:03














            13















            I was expecting to not get any output.




            If nullglob were the default, many commands would behave quite unexpectedly, because it is (perhaps unfortunately) common that commands treat the case of zero filename arguments in a qualitatively different way than the case of one or more filename arguments.



            Suppose you've enabled nullglob (shopt -s nullglob) and you're in a directory where no files match *.txt. Then *.txt will indeed expand to nothing--not an empty field, but no fields at all--as you expected. But that would have these results:




            • ls *.txt would list all the files in the current directory (except hidden files), because that's what ls does when you don't pass it any filename arguments.


            • cat *.txt would read from standard input, because when cat has no filename arguments, it's as if you ran cat -. If running interactively, it sits around waiting for input. Many commands behave this way.


            • cp *.txt dest/ would fail with the error cp: missing destination file operand after 'dest/'. This isn't a disaster, but it's confusing and quite different from the silent success that is probably desired.


            • file *.txt, and various other programs with no special behavior for the case of zero filename arguments, would still fail with an error or usage message when none are passed.

            • Even cases that intuitively feel like they should work often wouldn't. printf 'Got file: "%s"n' *.txt would print Got file: "" instead of nothing.

            • Accidental failure to quote occurrences of *, ?, and [ that aren't intended to be expanded by the shell would more often produce obviously wrong results, but in ways that might be difficult to figure out. For example, if no filenames in the current directory started with gedit, then apt list gedit* (where apt list 'gedit*' was intended) would become just apt list and list all available packages.

            So it's good that you don't get this behavior without requesting it. Probably the most common practical situation that is actually simplified by nullglob is for f in *.txt. See also this question (which Sergiy Kolodyazhnyy's answer linked to).



            The harder question to answer is why failglob--where it's an expansion error to have a glob that doesn't match any files--isn't the default in bash. I believe Sergiy Kolodyazhnyy's answer captures the reason for this even without addressing it directly. Retaining unexpanding globs without producing an expansion error is (perhaps unfortunately) the standardized behavior, and it is also traditional, and thus expected, behavior. Although bash doesn't attempt to be fully POSIX-compliant unless it is invoked with the name sh or passed the --posix option, many of its design choices even when not in POSIX mode follow POSIX directly. They had to pick some behavior, and there are downsides associated with going against users' expectations.




            I think this is the least historically influential aspect of the matter so I've saved it for last... but it is worth mentioning that there's something a bit conceptually odd about nullglob behavior.



            nullglob seems elegant at first because, syntactically, it treats the case of zero matching files no differently from the case of one, two, or any other number. The commands we run, which globs expand into arguments for, don't tend to treat them the same, as detailed above. But syntactically this at least feels right, which I think is the motivation for your question.



            And yet, there is another, more subtle inconsistency that nullglob doesn't address--that it actually amplifies. The case of zero globbing characters ("wildcards") is treated profoundly differently from that of one, or two, or any other number. For example, with shopt -s nullglob, if ab?d?f doesn't match any files, it is removed; if ab?d doesn't match any files, it is removed; but if ab doesn't match any files (i.e., if there is no file whose name is exactly ab) it is still not removed. Of course, it would be a disaster if it were removed, because it might not be intended to refer to an existing file in the current directory at all; it might not even refer to a file. But this still eliminates any hope for total consistency.



            The three behaviors bash provides--the default of treating globs that don't match any files as though they weren't globs and passing them unexpanded, the behavior you expected of treating them (if you'll pardon this odd turn of phrase) as signifying all zero of the files that do match (nullglob), and the safe behavior of considering them errors (failglob)--all represent different approaches to the ambiguity inherent in the shell not being able to know if any particular word is intended to be a filename. The shell performs its expansions without knowledge of how the particular commands you call with it will treat their arguments.



            This is one of many instances of separation of concerns. In systems whose design follows the Unix philosophy, each part is intended to do one thing and do it well. The shell processes text into commands and arguments and invokes those commands, most of which are external to the shell itself. This tends to be a lot nicer and more versatile than systems where the external commands are themselves responsible for performing those transformations (as with the traditional command processors in DOS and Windows). But it has its occasional downsides.






            share|improve this answer



























            • Apparently, bash-4.3.39(2) doesn't have failglob. So it can't the default because it hasn't always been supported.

              – Ruslan
              Jul 28 at 6:48
















            13















            I was expecting to not get any output.




            If nullglob were the default, many commands would behave quite unexpectedly, because it is (perhaps unfortunately) common that commands treat the case of zero filename arguments in a qualitatively different way than the case of one or more filename arguments.



            Suppose you've enabled nullglob (shopt -s nullglob) and you're in a directory where no files match *.txt. Then *.txt will indeed expand to nothing--not an empty field, but no fields at all--as you expected. But that would have these results:




            • ls *.txt would list all the files in the current directory (except hidden files), because that's what ls does when you don't pass it any filename arguments.


            • cat *.txt would read from standard input, because when cat has no filename arguments, it's as if you ran cat -. If running interactively, it sits around waiting for input. Many commands behave this way.


            • cp *.txt dest/ would fail with the error cp: missing destination file operand after 'dest/'. This isn't a disaster, but it's confusing and quite different from the silent success that is probably desired.


            • file *.txt, and various other programs with no special behavior for the case of zero filename arguments, would still fail with an error or usage message when none are passed.

            • Even cases that intuitively feel like they should work often wouldn't. printf 'Got file: "%s"n' *.txt would print Got file: "" instead of nothing.

            • Accidental failure to quote occurrences of *, ?, and [ that aren't intended to be expanded by the shell would more often produce obviously wrong results, but in ways that might be difficult to figure out. For example, if no filenames in the current directory started with gedit, then apt list gedit* (where apt list 'gedit*' was intended) would become just apt list and list all available packages.

            So it's good that you don't get this behavior without requesting it. Probably the most common practical situation that is actually simplified by nullglob is for f in *.txt. See also this question (which Sergiy Kolodyazhnyy's answer linked to).



            The harder question to answer is why failglob--where it's an expansion error to have a glob that doesn't match any files--isn't the default in bash. I believe Sergiy Kolodyazhnyy's answer captures the reason for this even without addressing it directly. Retaining unexpanding globs without producing an expansion error is (perhaps unfortunately) the standardized behavior, and it is also traditional, and thus expected, behavior. Although bash doesn't attempt to be fully POSIX-compliant unless it is invoked with the name sh or passed the --posix option, many of its design choices even when not in POSIX mode follow POSIX directly. They had to pick some behavior, and there are downsides associated with going against users' expectations.




            I think this is the least historically influential aspect of the matter so I've saved it for last... but it is worth mentioning that there's something a bit conceptually odd about nullglob behavior.



            nullglob seems elegant at first because, syntactically, it treats the case of zero matching files no differently from the case of one, two, or any other number. The commands we run, which globs expand into arguments for, don't tend to treat them the same, as detailed above. But syntactically this at least feels right, which I think is the motivation for your question.



            And yet, there is another, more subtle inconsistency that nullglob doesn't address--that it actually amplifies. The case of zero globbing characters ("wildcards") is treated profoundly differently from that of one, or two, or any other number. For example, with shopt -s nullglob, if ab?d?f doesn't match any files, it is removed; if ab?d doesn't match any files, it is removed; but if ab doesn't match any files (i.e., if there is no file whose name is exactly ab) it is still not removed. Of course, it would be a disaster if it were removed, because it might not be intended to refer to an existing file in the current directory at all; it might not even refer to a file. But this still eliminates any hope for total consistency.



            The three behaviors bash provides--the default of treating globs that don't match any files as though they weren't globs and passing them unexpanded, the behavior you expected of treating them (if you'll pardon this odd turn of phrase) as signifying all zero of the files that do match (nullglob), and the safe behavior of considering them errors (failglob)--all represent different approaches to the ambiguity inherent in the shell not being able to know if any particular word is intended to be a filename. The shell performs its expansions without knowledge of how the particular commands you call with it will treat their arguments.



            This is one of many instances of separation of concerns. In systems whose design follows the Unix philosophy, each part is intended to do one thing and do it well. The shell processes text into commands and arguments and invokes those commands, most of which are external to the shell itself. This tends to be a lot nicer and more versatile than systems where the external commands are themselves responsible for performing those transformations (as with the traditional command processors in DOS and Windows). But it has its occasional downsides.






            share|improve this answer



























            • Apparently, bash-4.3.39(2) doesn't have failglob. So it can't the default because it hasn't always been supported.

              – Ruslan
              Jul 28 at 6:48














            13












            13








            13








            I was expecting to not get any output.




            If nullglob were the default, many commands would behave quite unexpectedly, because it is (perhaps unfortunately) common that commands treat the case of zero filename arguments in a qualitatively different way than the case of one or more filename arguments.



            Suppose you've enabled nullglob (shopt -s nullglob) and you're in a directory where no files match *.txt. Then *.txt will indeed expand to nothing--not an empty field, but no fields at all--as you expected. But that would have these results:




            • ls *.txt would list all the files in the current directory (except hidden files), because that's what ls does when you don't pass it any filename arguments.


            • cat *.txt would read from standard input, because when cat has no filename arguments, it's as if you ran cat -. If running interactively, it sits around waiting for input. Many commands behave this way.


            • cp *.txt dest/ would fail with the error cp: missing destination file operand after 'dest/'. This isn't a disaster, but it's confusing and quite different from the silent success that is probably desired.


            • file *.txt, and various other programs with no special behavior for the case of zero filename arguments, would still fail with an error or usage message when none are passed.

            • Even cases that intuitively feel like they should work often wouldn't. printf 'Got file: "%s"n' *.txt would print Got file: "" instead of nothing.

            • Accidental failure to quote occurrences of *, ?, and [ that aren't intended to be expanded by the shell would more often produce obviously wrong results, but in ways that might be difficult to figure out. For example, if no filenames in the current directory started with gedit, then apt list gedit* (where apt list 'gedit*' was intended) would become just apt list and list all available packages.

            So it's good that you don't get this behavior without requesting it. Probably the most common practical situation that is actually simplified by nullglob is for f in *.txt. See also this question (which Sergiy Kolodyazhnyy's answer linked to).



            The harder question to answer is why failglob--where it's an expansion error to have a glob that doesn't match any files--isn't the default in bash. I believe Sergiy Kolodyazhnyy's answer captures the reason for this even without addressing it directly. Retaining unexpanding globs without producing an expansion error is (perhaps unfortunately) the standardized behavior, and it is also traditional, and thus expected, behavior. Although bash doesn't attempt to be fully POSIX-compliant unless it is invoked with the name sh or passed the --posix option, many of its design choices even when not in POSIX mode follow POSIX directly. They had to pick some behavior, and there are downsides associated with going against users' expectations.




            I think this is the least historically influential aspect of the matter so I've saved it for last... but it is worth mentioning that there's something a bit conceptually odd about nullglob behavior.



            nullglob seems elegant at first because, syntactically, it treats the case of zero matching files no differently from the case of one, two, or any other number. The commands we run, which globs expand into arguments for, don't tend to treat them the same, as detailed above. But syntactically this at least feels right, which I think is the motivation for your question.



            And yet, there is another, more subtle inconsistency that nullglob doesn't address--that it actually amplifies. The case of zero globbing characters ("wildcards") is treated profoundly differently from that of one, or two, or any other number. For example, with shopt -s nullglob, if ab?d?f doesn't match any files, it is removed; if ab?d doesn't match any files, it is removed; but if ab doesn't match any files (i.e., if there is no file whose name is exactly ab) it is still not removed. Of course, it would be a disaster if it were removed, because it might not be intended to refer to an existing file in the current directory at all; it might not even refer to a file. But this still eliminates any hope for total consistency.



            The three behaviors bash provides--the default of treating globs that don't match any files as though they weren't globs and passing them unexpanded, the behavior you expected of treating them (if you'll pardon this odd turn of phrase) as signifying all zero of the files that do match (nullglob), and the safe behavior of considering them errors (failglob)--all represent different approaches to the ambiguity inherent in the shell not being able to know if any particular word is intended to be a filename. The shell performs its expansions without knowledge of how the particular commands you call with it will treat their arguments.



            This is one of many instances of separation of concerns. In systems whose design follows the Unix philosophy, each part is intended to do one thing and do it well. The shell processes text into commands and arguments and invokes those commands, most of which are external to the shell itself. This tends to be a lot nicer and more versatile than systems where the external commands are themselves responsible for performing those transformations (as with the traditional command processors in DOS and Windows). But it has its occasional downsides.






            share|improve this answer
















            I was expecting to not get any output.




            If nullglob were the default, many commands would behave quite unexpectedly, because it is (perhaps unfortunately) common that commands treat the case of zero filename arguments in a qualitatively different way than the case of one or more filename arguments.



            Suppose you've enabled nullglob (shopt -s nullglob) and you're in a directory where no files match *.txt. Then *.txt will indeed expand to nothing--not an empty field, but no fields at all--as you expected. But that would have these results:




            • ls *.txt would list all the files in the current directory (except hidden files), because that's what ls does when you don't pass it any filename arguments.


            • cat *.txt would read from standard input, because when cat has no filename arguments, it's as if you ran cat -. If running interactively, it sits around waiting for input. Many commands behave this way.


            • cp *.txt dest/ would fail with the error cp: missing destination file operand after 'dest/'. This isn't a disaster, but it's confusing and quite different from the silent success that is probably desired.


            • file *.txt, and various other programs with no special behavior for the case of zero filename arguments, would still fail with an error or usage message when none are passed.

            • Even cases that intuitively feel like they should work often wouldn't. printf 'Got file: "%s"n' *.txt would print Got file: "" instead of nothing.

            • Accidental failure to quote occurrences of *, ?, and [ that aren't intended to be expanded by the shell would more often produce obviously wrong results, but in ways that might be difficult to figure out. For example, if no filenames in the current directory started with gedit, then apt list gedit* (where apt list 'gedit*' was intended) would become just apt list and list all available packages.

            So it's good that you don't get this behavior without requesting it. Probably the most common practical situation that is actually simplified by nullglob is for f in *.txt. See also this question (which Sergiy Kolodyazhnyy's answer linked to).



            The harder question to answer is why failglob--where it's an expansion error to have a glob that doesn't match any files--isn't the default in bash. I believe Sergiy Kolodyazhnyy's answer captures the reason for this even without addressing it directly. Retaining unexpanding globs without producing an expansion error is (perhaps unfortunately) the standardized behavior, and it is also traditional, and thus expected, behavior. Although bash doesn't attempt to be fully POSIX-compliant unless it is invoked with the name sh or passed the --posix option, many of its design choices even when not in POSIX mode follow POSIX directly. They had to pick some behavior, and there are downsides associated with going against users' expectations.




            I think this is the least historically influential aspect of the matter so I've saved it for last... but it is worth mentioning that there's something a bit conceptually odd about nullglob behavior.



            nullglob seems elegant at first because, syntactically, it treats the case of zero matching files no differently from the case of one, two, or any other number. The commands we run, which globs expand into arguments for, don't tend to treat them the same, as detailed above. But syntactically this at least feels right, which I think is the motivation for your question.



            And yet, there is another, more subtle inconsistency that nullglob doesn't address--that it actually amplifies. The case of zero globbing characters ("wildcards") is treated profoundly differently from that of one, or two, or any other number. For example, with shopt -s nullglob, if ab?d?f doesn't match any files, it is removed; if ab?d doesn't match any files, it is removed; but if ab doesn't match any files (i.e., if there is no file whose name is exactly ab) it is still not removed. Of course, it would be a disaster if it were removed, because it might not be intended to refer to an existing file in the current directory at all; it might not even refer to a file. But this still eliminates any hope for total consistency.



            The three behaviors bash provides--the default of treating globs that don't match any files as though they weren't globs and passing them unexpanded, the behavior you expected of treating them (if you'll pardon this odd turn of phrase) as signifying all zero of the files that do match (nullglob), and the safe behavior of considering them errors (failglob)--all represent different approaches to the ambiguity inherent in the shell not being able to know if any particular word is intended to be a filename. The shell performs its expansions without knowledge of how the particular commands you call with it will treat their arguments.



            This is one of many instances of separation of concerns. In systems whose design follows the Unix philosophy, each part is intended to do one thing and do it well. The shell processes text into commands and arguments and invokes those commands, most of which are external to the shell itself. This tends to be a lot nicer and more versatile than systems where the external commands are themselves responsible for performing those transformations (as with the traditional command processors in DOS and Windows). But it has its occasional downsides.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jul 27 at 23:45

























            answered Jul 26 at 19:43









            Eliah KaganEliah Kagan

            87.7k22 gold badges243 silver badges386 bronze badges




            87.7k22 gold badges243 silver badges386 bronze badges















            • Apparently, bash-4.3.39(2) doesn't have failglob. So it can't the default because it hasn't always been supported.

              – Ruslan
              Jul 28 at 6:48


















            • Apparently, bash-4.3.39(2) doesn't have failglob. So it can't the default because it hasn't always been supported.

              – Ruslan
              Jul 28 at 6:48

















            Apparently, bash-4.3.39(2) doesn't have failglob. So it can't the default because it hasn't always been supported.

            – Ruslan
            Jul 28 at 6:48






            Apparently, bash-4.3.39(2) doesn't have failglob. So it can't the default because it hasn't always been supported.

            – Ruslan
            Jul 28 at 6:48












            6














            The main reason is because this is standard behavior specified by POSIX - the standard which covers shell command language and among other things pattern matching ( shells such as bash, dash shell - Ubuntu's default /bin/sh, and ksh follow this standard ). From section 2.13.3 Patterns Used for Filename Expansion:




            If the pattern does not match any existing filenames or pathnames, the pattern string shall be left unchanged.




            This of course has a side effect - matching filename that may be literally *.txt. The nullglob option in bash and zsh can help: if that option is enabled via shopt -s nullglob (and it is not enabled by default which applies to this question), then globstar will be expanded to empty string when no matching filenames found. ksh93 has its own advanced pattern matching mechanism which achieves the same effect ~(N)*.txt



            See also Why is nullglob not default?






            share|improve this answer































              6














              The main reason is because this is standard behavior specified by POSIX - the standard which covers shell command language and among other things pattern matching ( shells such as bash, dash shell - Ubuntu's default /bin/sh, and ksh follow this standard ). From section 2.13.3 Patterns Used for Filename Expansion:




              If the pattern does not match any existing filenames or pathnames, the pattern string shall be left unchanged.




              This of course has a side effect - matching filename that may be literally *.txt. The nullglob option in bash and zsh can help: if that option is enabled via shopt -s nullglob (and it is not enabled by default which applies to this question), then globstar will be expanded to empty string when no matching filenames found. ksh93 has its own advanced pattern matching mechanism which achieves the same effect ~(N)*.txt



              See also Why is nullglob not default?






              share|improve this answer





























                6












                6








                6







                The main reason is because this is standard behavior specified by POSIX - the standard which covers shell command language and among other things pattern matching ( shells such as bash, dash shell - Ubuntu's default /bin/sh, and ksh follow this standard ). From section 2.13.3 Patterns Used for Filename Expansion:




                If the pattern does not match any existing filenames or pathnames, the pattern string shall be left unchanged.




                This of course has a side effect - matching filename that may be literally *.txt. The nullglob option in bash and zsh can help: if that option is enabled via shopt -s nullglob (and it is not enabled by default which applies to this question), then globstar will be expanded to empty string when no matching filenames found. ksh93 has its own advanced pattern matching mechanism which achieves the same effect ~(N)*.txt



                See also Why is nullglob not default?






                share|improve this answer















                The main reason is because this is standard behavior specified by POSIX - the standard which covers shell command language and among other things pattern matching ( shells such as bash, dash shell - Ubuntu's default /bin/sh, and ksh follow this standard ). From section 2.13.3 Patterns Used for Filename Expansion:




                If the pattern does not match any existing filenames or pathnames, the pattern string shall be left unchanged.




                This of course has a side effect - matching filename that may be literally *.txt. The nullglob option in bash and zsh can help: if that option is enabled via shopt -s nullglob (and it is not enabled by default which applies to this question), then globstar will be expanded to empty string when no matching filenames found. ksh93 has its own advanced pattern matching mechanism which achieves the same effect ~(N)*.txt



                See also Why is nullglob not default?







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Jul 26 at 18:45

























                answered Jul 26 at 9:04









                Sergiy KolodyazhnyySergiy Kolodyazhnyy

                78.4k11 gold badges168 silver badges346 bronze badges




                78.4k11 gold badges168 silver badges346 bronze badges






























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Ask Ubuntu!


                    • 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%2faskubuntu.com%2fquestions%2f1161180%2fexpansion-with-txt-in-the-shell-doesnt-work-if-no-txt-file-exists%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

                    Grendel Contents Story Scholarship Depictions Notes References Navigation menu10.1093/notesj/gjn112Berserkeree

                    Area configuration aggregation error after install Porto themeMagento 2.1 CE Installed but front/backend not loading/workingCSS not loading on page within Magento 2 pageCannot install module in Magento 2no commands defined in the “setup” namespace. in Magento2Magento 2: Static files are present but shows 404Why do i have to always run the commands to clean cache in Magento 2.1.8?Failure reason: 'Unable to unserialize value.'Error 500 after magento migrationIn production mode the site does not loadMagento 2 : Error 500 after installing

                    Middle Expansion Olielle Resaix Definition: Uttering songs of triumph shouting with joy triumphant exulting Sejunction Journal 붙다 달 고급 품목 외출 The stretch trades the screeching tin. Definition: The act of speaking with a drawl a drawl Cough Sand Definition: An uproar a quarrel a noisy outbreak Shake Iron Publicize Horse House Baby 사과 Resaix Flaggy Jelly Temporary Unequaled Puppet A drop in the bucket Shrew 성격 회원 성질 미팅 The burn frames the tacky quality. Materialistic The smoke reduces the way. Yammoe Nondescript Cheek 얼굴 배 약하다 날리다 타다 The illegal country shows the iron. Help Rule Drearien Smoke Teaching Meaty Wasp Abraham Lincoln Jaws 진심 수리하다 Size Cork Idea Convert Think Lark John Lennon 거울 청소 군 추천하다 아이스크림