bash/debian: strange makefile behaviour
Clash 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
make
add a comment |Â
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
make
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
add a comment |Â
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
make
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
make
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
add a comment |Â
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
add a comment |Â
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.
add a comment |Â
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.
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 useprintf
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
add a comment |Â
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.
add a comment |Â
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.
add a comment |Â
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.
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.
edited Jun 6 at 17:01
answered Jun 6 at 16:54
ilkkachu
47.7k668131
47.7k668131
add a comment |Â
add a comment |Â
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.
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 useprintf
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
add a comment |Â
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.
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 useprintf
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
add a comment |Â
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.
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.
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 useprintf
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
add a comment |Â
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 useprintf
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
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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