bash/debian: strange makefile behaviour

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











up vote
5
down vote

favorite












I use a very simple makefile with TeX:



test-makefile:
echo 'newcommandseanceseance1' > seances/seance.tex


I run it:



$ make test-makefile 
echo 'newcommandseanceseance1' > seances/seance.tex


My problem is that the file created in the folder named "seances" does not contain the two first characters it should contain:



 
ewcommandseanceseance1


The first line of it being empty.



Of course I can protect the first antislash: echo '\newcommandseanceseance1, etc. But in the real world it does not work: my real makefiles (I have posted an ECM) don't work.



What happens? How can bash/debian misunderstand the beginning of the command?





By the way:



$ bash --version
GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)
 
$ cat /etc/debian_version
buster/sid
 
$ uname -a
Linux giljourdan 4.16.0-1-amd64 #1 SMP Debian 4.16.5-1 (2018-04-29) x86_64 GNU/Linux






share|improve this question





















  • Thank you for your replies. Do you think this makefile would work flawlessly with zsh? This because it comes from a zsh user.
    – Pathe
    Jun 6 at 17:20










  • Since zsh is less compatible to a standard shell, you would introduce a higher portential for failures. If you configure your Makefile tu use zsh and you try to run it in a system where zsh is not installed, it will fail completely.
    – schily
    Jun 6 at 17:52










  • n means "new line"
    – JacobIRR
    Jun 6 at 23:12














up vote
5
down vote

favorite












I use a very simple makefile with TeX:



test-makefile:
echo 'newcommandseanceseance1' > seances/seance.tex


I run it:



$ make test-makefile 
echo 'newcommandseanceseance1' > seances/seance.tex


My problem is that the file created in the folder named "seances" does not contain the two first characters it should contain:



 
ewcommandseanceseance1


The first line of it being empty.



Of course I can protect the first antislash: echo '\newcommandseanceseance1, etc. But in the real world it does not work: my real makefiles (I have posted an ECM) don't work.



What happens? How can bash/debian misunderstand the beginning of the command?





By the way:



$ bash --version
GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)
 
$ cat /etc/debian_version
buster/sid
 
$ uname -a
Linux giljourdan 4.16.0-1-amd64 #1 SMP Debian 4.16.5-1 (2018-04-29) x86_64 GNU/Linux






share|improve this question





















  • Thank you for your replies. Do you think this makefile would work flawlessly with zsh? This because it comes from a zsh user.
    – Pathe
    Jun 6 at 17:20










  • Since zsh is less compatible to a standard shell, you would introduce a higher portential for failures. If you configure your Makefile tu use zsh and you try to run it in a system where zsh is not installed, it will fail completely.
    – schily
    Jun 6 at 17:52










  • n means "new line"
    – JacobIRR
    Jun 6 at 23:12












up vote
5
down vote

favorite









up vote
5
down vote

favorite











I use a very simple makefile with TeX:



test-makefile:
echo 'newcommandseanceseance1' > seances/seance.tex


I run it:



$ make test-makefile 
echo 'newcommandseanceseance1' > seances/seance.tex


My problem is that the file created in the folder named "seances" does not contain the two first characters it should contain:



 
ewcommandseanceseance1


The first line of it being empty.



Of course I can protect the first antislash: echo '\newcommandseanceseance1, etc. But in the real world it does not work: my real makefiles (I have posted an ECM) don't work.



What happens? How can bash/debian misunderstand the beginning of the command?





By the way:



$ bash --version
GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)
 
$ cat /etc/debian_version
buster/sid
 
$ uname -a
Linux giljourdan 4.16.0-1-amd64 #1 SMP Debian 4.16.5-1 (2018-04-29) x86_64 GNU/Linux






share|improve this question













I use a very simple makefile with TeX:



test-makefile:
echo 'newcommandseanceseance1' > seances/seance.tex


I run it:



$ make test-makefile 
echo 'newcommandseanceseance1' > seances/seance.tex


My problem is that the file created in the folder named "seances" does not contain the two first characters it should contain:



 
ewcommandseanceseance1


The first line of it being empty.



Of course I can protect the first antislash: echo '\newcommandseanceseance1, etc. But in the real world it does not work: my real makefiles (I have posted an ECM) don't work.



What happens? How can bash/debian misunderstand the beginning of the command?





By the way:



$ bash --version
GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)
 
$ cat /etc/debian_version
buster/sid
 
$ uname -a
Linux giljourdan 4.16.0-1-amd64 #1 SMP Debian 4.16.5-1 (2018-04-29) x86_64 GNU/Linux








share|improve this question












share|improve this question




share|improve this question








edited Jun 6 at 16:46
























asked Jun 6 at 16:38









Pathe

263




263











  • Thank you for your replies. Do you think this makefile would work flawlessly with zsh? This because it comes from a zsh user.
    – Pathe
    Jun 6 at 17:20










  • Since zsh is less compatible to a standard shell, you would introduce a higher portential for failures. If you configure your Makefile tu use zsh and you try to run it in a system where zsh is not installed, it will fail completely.
    – schily
    Jun 6 at 17:52










  • n means "new line"
    – JacobIRR
    Jun 6 at 23:12
















  • Thank you for your replies. Do you think this makefile would work flawlessly with zsh? This because it comes from a zsh user.
    – Pathe
    Jun 6 at 17:20










  • Since zsh is less compatible to a standard shell, you would introduce a higher portential for failures. If you configure your Makefile tu use zsh and you try to run it in a system where zsh is not installed, it will fail completely.
    – schily
    Jun 6 at 17:52










  • n means "new line"
    – JacobIRR
    Jun 6 at 23:12















Thank you for your replies. Do you think this makefile would work flawlessly with zsh? This because it comes from a zsh user.
– Pathe
Jun 6 at 17:20




Thank you for your replies. Do you think this makefile would work flawlessly with zsh? This because it comes from a zsh user.
– Pathe
Jun 6 at 17:20












Since zsh is less compatible to a standard shell, you would introduce a higher portential for failures. If you configure your Makefile tu use zsh and you try to run it in a system where zsh is not installed, it will fail completely.
– schily
Jun 6 at 17:52




Since zsh is less compatible to a standard shell, you would introduce a higher portential for failures. If you configure your Makefile tu use zsh and you try to run it in a system where zsh is not installed, it will fail completely.
– schily
Jun 6 at 17:52












n means "new line"
– JacobIRR
Jun 6 at 23:12




n means "new line"
– JacobIRR
Jun 6 at 23:12










2 Answers
2






active

oldest

votes

















up vote
12
down vote













Your echo is one of those that interprets backslash-escapes. A n means a newline, so you get exactly that. The latter backslash comes as-is, since s isn't a valid escape code.



Make runs the commands through a shell, using /bin/sh by default, and on Debian that's dash. Dash's builtin echo does process backslashes. Bash's doesn't. (And neither does the external /bin/echo on Debian, not that it matters unless you explicitly run /bin/echo).



Your best bet is to use printf explicitly, it's at least safe in that it always processes backslash-escapes. The below should always do the same thing, the \n at the start produces a real backslash and an n, the n later produces a newline to end the line.



foo:
printf '\newcommandn' > foo


(or, if you want to avoid processing backslashes, then use printf "%s" 'newcommand')



See the question Why is printf better than echo? for more details about echo gotchas.






share|improve this answer






























    up vote
    -5
    down vote













    Your echo is POSIX compliant and expands C backslash escapes. This is most likely because /bin/sh is dash instead of bash.



    There is a simple fix: add another backslash to quote the backslash:



     test-makefile:
    echo '\newcommand\seanceseance1' > seances/seance.tex


    Note that the POSIX standard marks the C backslash escapes for echo an XSI extension but the author of the POSIX compliance test suite claims that it is required to be XSI compliant in order to be POSIX compliant except when you like to certify only a small system for embedded use.



    Since it does not seem that the original question has been asked for a small embedded system, that system would need to implement XSI extensions in order to be compliant.



    Note that bash on POSIX certified platforms like Solaris and Mac OS is compiled in a way that it comes with a compliant echo by default. So the problem that bash is nor POSIX XSI compliant by default is Linux specific.






    share|improve this answer























    • Actually, that would be XSI conformant. POSIX conformance makes the behaviour when there are backslashes present anywhere implementation-defined. Stéphane Chazelas wrote a lengthy explanation of the behaviours here, hyperlinked to in another answer, referencing a further explanation by Sven Mascheck that goes into the details of XSI conformance. And on the topic of POSIX conformance, a simple fix following the POSIX standard would use printf instead, as it recommends new scripts do.
      – JdeBP
      Jun 6 at 23:43










    • Stéphane Chazelas explanation is mostly correct. It just misses the fact that XSI extensions are required for most platforms.
      – schily
      Jun 7 at 7:21










    Your Answer







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

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

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    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%2f448244%2fbash-debian-strange-makefile-behaviour%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    12
    down vote













    Your echo is one of those that interprets backslash-escapes. A n means a newline, so you get exactly that. The latter backslash comes as-is, since s isn't a valid escape code.



    Make runs the commands through a shell, using /bin/sh by default, and on Debian that's dash. Dash's builtin echo does process backslashes. Bash's doesn't. (And neither does the external /bin/echo on Debian, not that it matters unless you explicitly run /bin/echo).



    Your best bet is to use printf explicitly, it's at least safe in that it always processes backslash-escapes. The below should always do the same thing, the \n at the start produces a real backslash and an n, the n later produces a newline to end the line.



    foo:
    printf '\newcommandn' > foo


    (or, if you want to avoid processing backslashes, then use printf "%s" 'newcommand')



    See the question Why is printf better than echo? for more details about echo gotchas.






    share|improve this answer



























      up vote
      12
      down vote













      Your echo is one of those that interprets backslash-escapes. A n means a newline, so you get exactly that. The latter backslash comes as-is, since s isn't a valid escape code.



      Make runs the commands through a shell, using /bin/sh by default, and on Debian that's dash. Dash's builtin echo does process backslashes. Bash's doesn't. (And neither does the external /bin/echo on Debian, not that it matters unless you explicitly run /bin/echo).



      Your best bet is to use printf explicitly, it's at least safe in that it always processes backslash-escapes. The below should always do the same thing, the \n at the start produces a real backslash and an n, the n later produces a newline to end the line.



      foo:
      printf '\newcommandn' > foo


      (or, if you want to avoid processing backslashes, then use printf "%s" 'newcommand')



      See the question Why is printf better than echo? for more details about echo gotchas.






      share|improve this answer

























        up vote
        12
        down vote










        up vote
        12
        down vote









        Your echo is one of those that interprets backslash-escapes. A n means a newline, so you get exactly that. The latter backslash comes as-is, since s isn't a valid escape code.



        Make runs the commands through a shell, using /bin/sh by default, and on Debian that's dash. Dash's builtin echo does process backslashes. Bash's doesn't. (And neither does the external /bin/echo on Debian, not that it matters unless you explicitly run /bin/echo).



        Your best bet is to use printf explicitly, it's at least safe in that it always processes backslash-escapes. The below should always do the same thing, the \n at the start produces a real backslash and an n, the n later produces a newline to end the line.



        foo:
        printf '\newcommandn' > foo


        (or, if you want to avoid processing backslashes, then use printf "%s" 'newcommand')



        See the question Why is printf better than echo? for more details about echo gotchas.






        share|improve this answer















        Your echo is one of those that interprets backslash-escapes. A n means a newline, so you get exactly that. The latter backslash comes as-is, since s isn't a valid escape code.



        Make runs the commands through a shell, using /bin/sh by default, and on Debian that's dash. Dash's builtin echo does process backslashes. Bash's doesn't. (And neither does the external /bin/echo on Debian, not that it matters unless you explicitly run /bin/echo).



        Your best bet is to use printf explicitly, it's at least safe in that it always processes backslash-escapes. The below should always do the same thing, the \n at the start produces a real backslash and an n, the n later produces a newline to end the line.



        foo:
        printf '\newcommandn' > foo


        (or, if you want to avoid processing backslashes, then use printf "%s" 'newcommand')



        See the question Why is printf better than echo? for more details about echo gotchas.







        share|improve this answer















        share|improve this answer



        share|improve this answer








        edited Jun 6 at 17:01


























        answered Jun 6 at 16:54









        ilkkachu

        47.7k668131




        47.7k668131






















            up vote
            -5
            down vote













            Your echo is POSIX compliant and expands C backslash escapes. This is most likely because /bin/sh is dash instead of bash.



            There is a simple fix: add another backslash to quote the backslash:



             test-makefile:
            echo '\newcommand\seanceseance1' > seances/seance.tex


            Note that the POSIX standard marks the C backslash escapes for echo an XSI extension but the author of the POSIX compliance test suite claims that it is required to be XSI compliant in order to be POSIX compliant except when you like to certify only a small system for embedded use.



            Since it does not seem that the original question has been asked for a small embedded system, that system would need to implement XSI extensions in order to be compliant.



            Note that bash on POSIX certified platforms like Solaris and Mac OS is compiled in a way that it comes with a compliant echo by default. So the problem that bash is nor POSIX XSI compliant by default is Linux specific.






            share|improve this answer























            • Actually, that would be XSI conformant. POSIX conformance makes the behaviour when there are backslashes present anywhere implementation-defined. Stéphane Chazelas wrote a lengthy explanation of the behaviours here, hyperlinked to in another answer, referencing a further explanation by Sven Mascheck that goes into the details of XSI conformance. And on the topic of POSIX conformance, a simple fix following the POSIX standard would use printf instead, as it recommends new scripts do.
              – JdeBP
              Jun 6 at 23:43










            • Stéphane Chazelas explanation is mostly correct. It just misses the fact that XSI extensions are required for most platforms.
              – schily
              Jun 7 at 7:21














            up vote
            -5
            down vote













            Your echo is POSIX compliant and expands C backslash escapes. This is most likely because /bin/sh is dash instead of bash.



            There is a simple fix: add another backslash to quote the backslash:



             test-makefile:
            echo '\newcommand\seanceseance1' > seances/seance.tex


            Note that the POSIX standard marks the C backslash escapes for echo an XSI extension but the author of the POSIX compliance test suite claims that it is required to be XSI compliant in order to be POSIX compliant except when you like to certify only a small system for embedded use.



            Since it does not seem that the original question has been asked for a small embedded system, that system would need to implement XSI extensions in order to be compliant.



            Note that bash on POSIX certified platforms like Solaris and Mac OS is compiled in a way that it comes with a compliant echo by default. So the problem that bash is nor POSIX XSI compliant by default is Linux specific.






            share|improve this answer























            • Actually, that would be XSI conformant. POSIX conformance makes the behaviour when there are backslashes present anywhere implementation-defined. Stéphane Chazelas wrote a lengthy explanation of the behaviours here, hyperlinked to in another answer, referencing a further explanation by Sven Mascheck that goes into the details of XSI conformance. And on the topic of POSIX conformance, a simple fix following the POSIX standard would use printf instead, as it recommends new scripts do.
              – JdeBP
              Jun 6 at 23:43










            • Stéphane Chazelas explanation is mostly correct. It just misses the fact that XSI extensions are required for most platforms.
              – schily
              Jun 7 at 7:21












            up vote
            -5
            down vote










            up vote
            -5
            down vote









            Your echo is POSIX compliant and expands C backslash escapes. This is most likely because /bin/sh is dash instead of bash.



            There is a simple fix: add another backslash to quote the backslash:



             test-makefile:
            echo '\newcommand\seanceseance1' > seances/seance.tex


            Note that the POSIX standard marks the C backslash escapes for echo an XSI extension but the author of the POSIX compliance test suite claims that it is required to be XSI compliant in order to be POSIX compliant except when you like to certify only a small system for embedded use.



            Since it does not seem that the original question has been asked for a small embedded system, that system would need to implement XSI extensions in order to be compliant.



            Note that bash on POSIX certified platforms like Solaris and Mac OS is compiled in a way that it comes with a compliant echo by default. So the problem that bash is nor POSIX XSI compliant by default is Linux specific.






            share|improve this answer















            Your echo is POSIX compliant and expands C backslash escapes. This is most likely because /bin/sh is dash instead of bash.



            There is a simple fix: add another backslash to quote the backslash:



             test-makefile:
            echo '\newcommand\seanceseance1' > seances/seance.tex


            Note that the POSIX standard marks the C backslash escapes for echo an XSI extension but the author of the POSIX compliance test suite claims that it is required to be XSI compliant in order to be POSIX compliant except when you like to certify only a small system for embedded use.



            Since it does not seem that the original question has been asked for a small embedded system, that system would need to implement XSI extensions in order to be compliant.



            Note that bash on POSIX certified platforms like Solaris and Mac OS is compiled in a way that it comes with a compliant echo by default. So the problem that bash is nor POSIX XSI compliant by default is Linux specific.







            share|improve this answer















            share|improve this answer



            share|improve this answer








            edited Jun 7 at 7:18


























            answered Jun 6 at 17:07









            schily

            8,63821435




            8,63821435











            • Actually, that would be XSI conformant. POSIX conformance makes the behaviour when there are backslashes present anywhere implementation-defined. Stéphane Chazelas wrote a lengthy explanation of the behaviours here, hyperlinked to in another answer, referencing a further explanation by Sven Mascheck that goes into the details of XSI conformance. And on the topic of POSIX conformance, a simple fix following the POSIX standard would use printf instead, as it recommends new scripts do.
              – JdeBP
              Jun 6 at 23:43










            • Stéphane Chazelas explanation is mostly correct. It just misses the fact that XSI extensions are required for most platforms.
              – schily
              Jun 7 at 7:21
















            • Actually, that would be XSI conformant. POSIX conformance makes the behaviour when there are backslashes present anywhere implementation-defined. Stéphane Chazelas wrote a lengthy explanation of the behaviours here, hyperlinked to in another answer, referencing a further explanation by Sven Mascheck that goes into the details of XSI conformance. And on the topic of POSIX conformance, a simple fix following the POSIX standard would use printf instead, as it recommends new scripts do.
              – JdeBP
              Jun 6 at 23:43










            • Stéphane Chazelas explanation is mostly correct. It just misses the fact that XSI extensions are required for most platforms.
              – schily
              Jun 7 at 7:21















            Actually, that would be XSI conformant. POSIX conformance makes the behaviour when there are backslashes present anywhere implementation-defined. Stéphane Chazelas wrote a lengthy explanation of the behaviours here, hyperlinked to in another answer, referencing a further explanation by Sven Mascheck that goes into the details of XSI conformance. And on the topic of POSIX conformance, a simple fix following the POSIX standard would use printf instead, as it recommends new scripts do.
            – JdeBP
            Jun 6 at 23:43




            Actually, that would be XSI conformant. POSIX conformance makes the behaviour when there are backslashes present anywhere implementation-defined. Stéphane Chazelas wrote a lengthy explanation of the behaviours here, hyperlinked to in another answer, referencing a further explanation by Sven Mascheck that goes into the details of XSI conformance. And on the topic of POSIX conformance, a simple fix following the POSIX standard would use printf instead, as it recommends new scripts do.
            – JdeBP
            Jun 6 at 23:43












            Stéphane Chazelas explanation is mostly correct. It just misses the fact that XSI extensions are required for most platforms.
            – schily
            Jun 7 at 7:21




            Stéphane Chazelas explanation is mostly correct. It just misses the fact that XSI extensions are required for most platforms.
            – schily
            Jun 7 at 7:21












             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f448244%2fbash-debian-strange-makefile-behaviour%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Bahrain

            Postfix configuration issue with fips on centos 7; mailgun relay