Echoing a tail command produces unexpected output? Announcing the arrival of Valued Associate...

What does "fit" mean in this sentence?

Sci-Fi book where patients in a coma ward all live in a subconscious world linked together

Output the ŋarâþ crîþ alphabet song without using (m)any letters

What LEGO pieces have "real-world" functionality?

Error "illegal generic type for instanceof" when using local classes

How does the particle を relate to the verb 行く in the structure「A を + B に行く」?

Can a USB port passively 'listen only'?

2001: A Space Odyssey's use of the song "Daisy Bell" (Bicycle Built for Two); life imitates art or vice-versa?

Why did the IBM 650 use bi-quinary?

Why did the Falcon Heavy center core fall off the ASDS OCISLY barge?

Generate an RGB colour grid

How to deal with a team lead who never gives me credit?

How to find out what spells would be useless to a blind NPC spellcaster?

Can a non-EU citizen traveling with me come with me through the EU passport line?

String `!23` is replaced with `docker` in command line

Withdrew £2800, but only £2000 shows as withdrawn on online banking; what are my obligations?

How does debian/ubuntu knows a package has a updated version

When a candle burns, why does the top of wick glow if bottom of flame is hottest?

List *all* the tuples!

What does the "x" in "x86" represent?

What exactly is a "Meth" in Altered Carbon?

What is Arya's weapon design?

Identify plant with long narrow paired leaves and reddish stems

How can I make names more distinctive without making them longer?



Echoing a tail command produces unexpected output?



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)
2019 Community Moderator Election Results
Why I closed the “Why is Kali so hard” questionWhy does cron silently fail to run sudo stuff in my script?BashScript works from Terminal but not from CronTabHow to run a shell script using cron and atsh script containing perl element does not produce same output via crontab as manual executionHave a command in my $PATH, but it is not being recognized when I use sudoPiping the result of ls to tailWhy does head; tail on a large file sometimes take a long time and sometimes not?Crontab in Mac is not workingtail and bash: different output when same is expectedCronjob output not working





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







7















This command, when run alone, produces the expected result (the last line of the crontab):



tail -n 1 /etc/crontab


However, when I run it as part of an echo command to send the result to a file, it adds a summary of all the files in the working directory, plus the expected result:



sudo bash -c 'echo $(tail -n 1 /etc/crontab) > /path/to/file'


Why did this command produce the extra data?










share|improve this question









New contributor




Davidw is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 2





    See Why does my shell script choke on whitespace or other special characters? and Why is printf better than echo?

    – Stéphane Chazelas
    19 hours ago






  • 3





    What is echo doing for you here? Consider also tail -n 1 /etc/crontab | sudo tee /path/to/file >/dev/null

    – ctrl-alt-delor
    17 hours ago








  • 1





    What is wrong with echo $(stuff)?

    – Kamil Maciorowski
    13 hours ago


















7















This command, when run alone, produces the expected result (the last line of the crontab):



tail -n 1 /etc/crontab


However, when I run it as part of an echo command to send the result to a file, it adds a summary of all the files in the working directory, plus the expected result:



sudo bash -c 'echo $(tail -n 1 /etc/crontab) > /path/to/file'


Why did this command produce the extra data?










share|improve this question









New contributor




Davidw is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 2





    See Why does my shell script choke on whitespace or other special characters? and Why is printf better than echo?

    – Stéphane Chazelas
    19 hours ago






  • 3





    What is echo doing for you here? Consider also tail -n 1 /etc/crontab | sudo tee /path/to/file >/dev/null

    – ctrl-alt-delor
    17 hours ago








  • 1





    What is wrong with echo $(stuff)?

    – Kamil Maciorowski
    13 hours ago














7












7








7


0






This command, when run alone, produces the expected result (the last line of the crontab):



tail -n 1 /etc/crontab


However, when I run it as part of an echo command to send the result to a file, it adds a summary of all the files in the working directory, plus the expected result:



sudo bash -c 'echo $(tail -n 1 /etc/crontab) > /path/to/file'


Why did this command produce the extra data?










share|improve this question









New contributor




Davidw is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












This command, when run alone, produces the expected result (the last line of the crontab):



tail -n 1 /etc/crontab


However, when I run it as part of an echo command to send the result to a file, it adds a summary of all the files in the working directory, plus the expected result:



sudo bash -c 'echo $(tail -n 1 /etc/crontab) > /path/to/file'


Why did this command produce the extra data?







bash sudo cron echo tail






share|improve this question









New contributor




Davidw is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Davidw is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 13 hours ago









Jeff Schaller

45.1k1164147




45.1k1164147






New contributor




Davidw is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 19 hours ago









DavidwDavidw

1416




1416




New contributor




Davidw is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Davidw is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Davidw is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








  • 2





    See Why does my shell script choke on whitespace or other special characters? and Why is printf better than echo?

    – Stéphane Chazelas
    19 hours ago






  • 3





    What is echo doing for you here? Consider also tail -n 1 /etc/crontab | sudo tee /path/to/file >/dev/null

    – ctrl-alt-delor
    17 hours ago








  • 1





    What is wrong with echo $(stuff)?

    – Kamil Maciorowski
    13 hours ago














  • 2





    See Why does my shell script choke on whitespace or other special characters? and Why is printf better than echo?

    – Stéphane Chazelas
    19 hours ago






  • 3





    What is echo doing for you here? Consider also tail -n 1 /etc/crontab | sudo tee /path/to/file >/dev/null

    – ctrl-alt-delor
    17 hours ago








  • 1





    What is wrong with echo $(stuff)?

    – Kamil Maciorowski
    13 hours ago








2




2





See Why does my shell script choke on whitespace or other special characters? and Why is printf better than echo?

– Stéphane Chazelas
19 hours ago





See Why does my shell script choke on whitespace or other special characters? and Why is printf better than echo?

– Stéphane Chazelas
19 hours ago




3




3





What is echo doing for you here? Consider also tail -n 1 /etc/crontab | sudo tee /path/to/file >/dev/null

– ctrl-alt-delor
17 hours ago







What is echo doing for you here? Consider also tail -n 1 /etc/crontab | sudo tee /path/to/file >/dev/null

– ctrl-alt-delor
17 hours ago






1




1





What is wrong with echo $(stuff)?

– Kamil Maciorowski
13 hours ago





What is wrong with echo $(stuff)?

– Kamil Maciorowski
13 hours ago










3 Answers
3






active

oldest

votes


















21














Your crontab line has one or more asterisks * in it, indicating "any time". When that line is substituted in from the command substitution, the result is something like



echo * * * * * cmd > /path/to/file


While most further expansions are not applied to the output of command substitution, pathname expansion is (as is field splitting):




The results of command substitution shall not be processed for further tilde expansion, parameter expansion, command substitution, or arithmetic expansion. If a command substitution occurs inside double-quotes, field splitting and pathname expansion shall not be performed on the results of the substitution.




Pathname expansion is what turns *.txt into a list of matching filenames (globbing), where * matches everything. The end result is that you get every (non-hidden) filename in the working directory listed for every * in your crontab line.





You could fix this by quoting the expansion, if the code you posted was a representative of a more complex command:



sudo bash -c 'echo "$(tail -n 1 /etc/crontab)" > /path/to/file'


but more straightforwardly just lose the echo entirely:



sudo bash -c 'tail -n 1 /etc/crontab > /path/to/file'


This should do what you want and it's simpler as well (the only other material difference is that this version will omit field splitting that would otherwise have occurred, so runs of spaces won't be collapsed).






share|improve this answer





















  • 4





    Since /etc/crontab is almost always world readable, all the "bash -c" trickery is actually unnecessary: tail -n -1 /etc/crontab | sudo tee /path/to/file is the idiom that I've found to be the least error prone when redirecting output into files that require superuser privileges.

    – Bass
    18 hours ago





















5














Let's consider a directory with these files:



$ ls
crontab file1 file2 file3
$ cat crontab
f*


Now, let's run the tail command:



$ tail -n 1 crontab
f*


The above is the last line of crontab and this is what we expect. However:



$ echo $(tail -n 1 crontab)
file1 file2 file3


Double-quotes eliminate this problem:



$ echo "$(tail -n 1 crontab)"
f*


Without the double-quotes, the result of the command substitution is expanded by the shell. One of the expansions is pathname expansion. In the case above, this means that f* is expanded to match every file name that starts with f.



Unless you explicitly want shell expansions, put all you shell variables and/or command substitutions inside double quotes.






share|improve this answer































    4














    globing shell mecanism will expand * to local file.



    crontab line is likely to have a * as placeholder for any.



    e.g. this line in crontab run on 7.47 am on sunday, first star mean any day, second any month.



    47  7 * * 0 /run/on/sunday


    then you tail, and issue



    echo 47  7 * * 0 /run/on/sunday


    that will expand * to local file.






    share|improve this answer
























      Your Answer








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

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

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      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
      });


      }
      });






      Davidw is a new contributor. Be nice, and check out our Code of Conduct.










      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f512702%2fechoing-a-tail-command-produces-unexpected-output%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









      21














      Your crontab line has one or more asterisks * in it, indicating "any time". When that line is substituted in from the command substitution, the result is something like



      echo * * * * * cmd > /path/to/file


      While most further expansions are not applied to the output of command substitution, pathname expansion is (as is field splitting):




      The results of command substitution shall not be processed for further tilde expansion, parameter expansion, command substitution, or arithmetic expansion. If a command substitution occurs inside double-quotes, field splitting and pathname expansion shall not be performed on the results of the substitution.




      Pathname expansion is what turns *.txt into a list of matching filenames (globbing), where * matches everything. The end result is that you get every (non-hidden) filename in the working directory listed for every * in your crontab line.





      You could fix this by quoting the expansion, if the code you posted was a representative of a more complex command:



      sudo bash -c 'echo "$(tail -n 1 /etc/crontab)" > /path/to/file'


      but more straightforwardly just lose the echo entirely:



      sudo bash -c 'tail -n 1 /etc/crontab > /path/to/file'


      This should do what you want and it's simpler as well (the only other material difference is that this version will omit field splitting that would otherwise have occurred, so runs of spaces won't be collapsed).






      share|improve this answer





















      • 4





        Since /etc/crontab is almost always world readable, all the "bash -c" trickery is actually unnecessary: tail -n -1 /etc/crontab | sudo tee /path/to/file is the idiom that I've found to be the least error prone when redirecting output into files that require superuser privileges.

        – Bass
        18 hours ago


















      21














      Your crontab line has one or more asterisks * in it, indicating "any time". When that line is substituted in from the command substitution, the result is something like



      echo * * * * * cmd > /path/to/file


      While most further expansions are not applied to the output of command substitution, pathname expansion is (as is field splitting):




      The results of command substitution shall not be processed for further tilde expansion, parameter expansion, command substitution, or arithmetic expansion. If a command substitution occurs inside double-quotes, field splitting and pathname expansion shall not be performed on the results of the substitution.




      Pathname expansion is what turns *.txt into a list of matching filenames (globbing), where * matches everything. The end result is that you get every (non-hidden) filename in the working directory listed for every * in your crontab line.





      You could fix this by quoting the expansion, if the code you posted was a representative of a more complex command:



      sudo bash -c 'echo "$(tail -n 1 /etc/crontab)" > /path/to/file'


      but more straightforwardly just lose the echo entirely:



      sudo bash -c 'tail -n 1 /etc/crontab > /path/to/file'


      This should do what you want and it's simpler as well (the only other material difference is that this version will omit field splitting that would otherwise have occurred, so runs of spaces won't be collapsed).






      share|improve this answer





















      • 4





        Since /etc/crontab is almost always world readable, all the "bash -c" trickery is actually unnecessary: tail -n -1 /etc/crontab | sudo tee /path/to/file is the idiom that I've found to be the least error prone when redirecting output into files that require superuser privileges.

        – Bass
        18 hours ago
















      21












      21








      21







      Your crontab line has one or more asterisks * in it, indicating "any time". When that line is substituted in from the command substitution, the result is something like



      echo * * * * * cmd > /path/to/file


      While most further expansions are not applied to the output of command substitution, pathname expansion is (as is field splitting):




      The results of command substitution shall not be processed for further tilde expansion, parameter expansion, command substitution, or arithmetic expansion. If a command substitution occurs inside double-quotes, field splitting and pathname expansion shall not be performed on the results of the substitution.




      Pathname expansion is what turns *.txt into a list of matching filenames (globbing), where * matches everything. The end result is that you get every (non-hidden) filename in the working directory listed for every * in your crontab line.





      You could fix this by quoting the expansion, if the code you posted was a representative of a more complex command:



      sudo bash -c 'echo "$(tail -n 1 /etc/crontab)" > /path/to/file'


      but more straightforwardly just lose the echo entirely:



      sudo bash -c 'tail -n 1 /etc/crontab > /path/to/file'


      This should do what you want and it's simpler as well (the only other material difference is that this version will omit field splitting that would otherwise have occurred, so runs of spaces won't be collapsed).






      share|improve this answer















      Your crontab line has one or more asterisks * in it, indicating "any time". When that line is substituted in from the command substitution, the result is something like



      echo * * * * * cmd > /path/to/file


      While most further expansions are not applied to the output of command substitution, pathname expansion is (as is field splitting):




      The results of command substitution shall not be processed for further tilde expansion, parameter expansion, command substitution, or arithmetic expansion. If a command substitution occurs inside double-quotes, field splitting and pathname expansion shall not be performed on the results of the substitution.




      Pathname expansion is what turns *.txt into a list of matching filenames (globbing), where * matches everything. The end result is that you get every (non-hidden) filename in the working directory listed for every * in your crontab line.





      You could fix this by quoting the expansion, if the code you posted was a representative of a more complex command:



      sudo bash -c 'echo "$(tail -n 1 /etc/crontab)" > /path/to/file'


      but more straightforwardly just lose the echo entirely:



      sudo bash -c 'tail -n 1 /etc/crontab > /path/to/file'


      This should do what you want and it's simpler as well (the only other material difference is that this version will omit field splitting that would otherwise have occurred, so runs of spaces won't be collapsed).







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited 19 hours ago

























      answered 19 hours ago









      Michael HomerMichael Homer

      51.2k8142179




      51.2k8142179








      • 4





        Since /etc/crontab is almost always world readable, all the "bash -c" trickery is actually unnecessary: tail -n -1 /etc/crontab | sudo tee /path/to/file is the idiom that I've found to be the least error prone when redirecting output into files that require superuser privileges.

        – Bass
        18 hours ago
















      • 4





        Since /etc/crontab is almost always world readable, all the "bash -c" trickery is actually unnecessary: tail -n -1 /etc/crontab | sudo tee /path/to/file is the idiom that I've found to be the least error prone when redirecting output into files that require superuser privileges.

        – Bass
        18 hours ago










      4




      4





      Since /etc/crontab is almost always world readable, all the "bash -c" trickery is actually unnecessary: tail -n -1 /etc/crontab | sudo tee /path/to/file is the idiom that I've found to be the least error prone when redirecting output into files that require superuser privileges.

      – Bass
      18 hours ago







      Since /etc/crontab is almost always world readable, all the "bash -c" trickery is actually unnecessary: tail -n -1 /etc/crontab | sudo tee /path/to/file is the idiom that I've found to be the least error prone when redirecting output into files that require superuser privileges.

      – Bass
      18 hours ago















      5














      Let's consider a directory with these files:



      $ ls
      crontab file1 file2 file3
      $ cat crontab
      f*


      Now, let's run the tail command:



      $ tail -n 1 crontab
      f*


      The above is the last line of crontab and this is what we expect. However:



      $ echo $(tail -n 1 crontab)
      file1 file2 file3


      Double-quotes eliminate this problem:



      $ echo "$(tail -n 1 crontab)"
      f*


      Without the double-quotes, the result of the command substitution is expanded by the shell. One of the expansions is pathname expansion. In the case above, this means that f* is expanded to match every file name that starts with f.



      Unless you explicitly want shell expansions, put all you shell variables and/or command substitutions inside double quotes.






      share|improve this answer




























        5














        Let's consider a directory with these files:



        $ ls
        crontab file1 file2 file3
        $ cat crontab
        f*


        Now, let's run the tail command:



        $ tail -n 1 crontab
        f*


        The above is the last line of crontab and this is what we expect. However:



        $ echo $(tail -n 1 crontab)
        file1 file2 file3


        Double-quotes eliminate this problem:



        $ echo "$(tail -n 1 crontab)"
        f*


        Without the double-quotes, the result of the command substitution is expanded by the shell. One of the expansions is pathname expansion. In the case above, this means that f* is expanded to match every file name that starts with f.



        Unless you explicitly want shell expansions, put all you shell variables and/or command substitutions inside double quotes.






        share|improve this answer


























          5












          5








          5







          Let's consider a directory with these files:



          $ ls
          crontab file1 file2 file3
          $ cat crontab
          f*


          Now, let's run the tail command:



          $ tail -n 1 crontab
          f*


          The above is the last line of crontab and this is what we expect. However:



          $ echo $(tail -n 1 crontab)
          file1 file2 file3


          Double-quotes eliminate this problem:



          $ echo "$(tail -n 1 crontab)"
          f*


          Without the double-quotes, the result of the command substitution is expanded by the shell. One of the expansions is pathname expansion. In the case above, this means that f* is expanded to match every file name that starts with f.



          Unless you explicitly want shell expansions, put all you shell variables and/or command substitutions inside double quotes.






          share|improve this answer













          Let's consider a directory with these files:



          $ ls
          crontab file1 file2 file3
          $ cat crontab
          f*


          Now, let's run the tail command:



          $ tail -n 1 crontab
          f*


          The above is the last line of crontab and this is what we expect. However:



          $ echo $(tail -n 1 crontab)
          file1 file2 file3


          Double-quotes eliminate this problem:



          $ echo "$(tail -n 1 crontab)"
          f*


          Without the double-quotes, the result of the command substitution is expanded by the shell. One of the expansions is pathname expansion. In the case above, this means that f* is expanded to match every file name that starts with f.



          Unless you explicitly want shell expansions, put all you shell variables and/or command substitutions inside double quotes.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 19 hours ago









          John1024John1024

          48.8k5114129




          48.8k5114129























              4














              globing shell mecanism will expand * to local file.



              crontab line is likely to have a * as placeholder for any.



              e.g. this line in crontab run on 7.47 am on sunday, first star mean any day, second any month.



              47  7 * * 0 /run/on/sunday


              then you tail, and issue



              echo 47  7 * * 0 /run/on/sunday


              that will expand * to local file.






              share|improve this answer




























                4














                globing shell mecanism will expand * to local file.



                crontab line is likely to have a * as placeholder for any.



                e.g. this line in crontab run on 7.47 am on sunday, first star mean any day, second any month.



                47  7 * * 0 /run/on/sunday


                then you tail, and issue



                echo 47  7 * * 0 /run/on/sunday


                that will expand * to local file.






                share|improve this answer


























                  4












                  4








                  4







                  globing shell mecanism will expand * to local file.



                  crontab line is likely to have a * as placeholder for any.



                  e.g. this line in crontab run on 7.47 am on sunday, first star mean any day, second any month.



                  47  7 * * 0 /run/on/sunday


                  then you tail, and issue



                  echo 47  7 * * 0 /run/on/sunday


                  that will expand * to local file.






                  share|improve this answer













                  globing shell mecanism will expand * to local file.



                  crontab line is likely to have a * as placeholder for any.



                  e.g. this line in crontab run on 7.47 am on sunday, first star mean any day, second any month.



                  47  7 * * 0 /run/on/sunday


                  then you tail, and issue



                  echo 47  7 * * 0 /run/on/sunday


                  that will expand * to local file.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered 19 hours ago









                  ArchemarArchemar

                  20.6k93973




                  20.6k93973






















                      Davidw is a new contributor. Be nice, and check out our Code of Conduct.










                      draft saved

                      draft discarded


















                      Davidw is a new contributor. Be nice, and check out our Code of Conduct.













                      Davidw is a new contributor. Be nice, and check out our Code of Conduct.












                      Davidw is a new contributor. Be nice, and check out our Code of Conduct.
















                      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%2f512702%2fechoing-a-tail-command-produces-unexpected-output%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

                      Why not use the yoke to control yaw, as well as pitch and roll? Announcing the arrival of...

                      Couldn't open a raw socket. Error: Permission denied (13) (nmap)Is it possible to run networking commands...

                      VNC viewer RFB protocol error: bad desktop size 0x0I Cannot Type the Key 'd' (lowercase) in VNC Viewer...