bugmake - Bugs: bug #27495, echo behaves different in pipe for...

 
 

bug #27495: echo behaves different in pipe for /bin/sh symlinked to dash

Submitted by:  None
Submitted on:  Tue 22 Sep 2009 08:24:14 AM UTC  
 
Severity:  3 - Normal Item Group:  Bug
Status:  Not A Bug Privacy:  Public
Assigned to:  None Open/Closed:  Closed
Component Version:  3.81 Operating System:  POSIX-Based
Fixed Release:  None Triage Status:  None

Add a New Comment(Rich Markup)
   

You are not logged in

Please log in, so followups can be emailed to you.

 

Wed 23 Sep 2009 12:34:38 PM UTC, comment #3:

Because if you change the value of SHELL to a command that make doesn't recognize as a POSIX sh implementation, it disables the fast path altogether. There's nothing saying you can't use a completely different program, like Perl or Python or Ruby or something, as SHELL, in which case all make's parsing, etc. would be wrong. So, if SHELL is not a known POSIX sh then make never uses the fast path.

Make does not recognize /bin/dash as a POSIX sh, by default, so if you set SHELL to /bin/bash it will ALWAYS invoke the shell and never use the fast path, so you ALWAYS get the builtin echo behavior.

Paul D. Smith <psmith>
Project Administrator
Wed 23 Sep 2009 11:19:37 AM UTC, comment #2:

Thank you for your very helpful explanation.

One thing I don't understand yet is:
Why is /bin/echo used for SHELL unset and SHELL=/bin/sh,
whereas for SHELL=/bin/dash the builtin echo of dash is used.

Anonymous
Tue 22 Sep 2009 01:03:30 PM UTC, comment #1:

Basically what you're seeing is that dash has a builtin echo command, which behaves differently than the separate echo program in /bin or /usr/bin; this is not a make issue:

The reason you're seeing this here is that in the simple case (without redirection or pipeline) make uses a fast path and avoids the shell invocation; for performance reasons it simply directly forks/execs the command. In the second case, with redirection, make sees that it can't use the fast path and so it actually starts a shell and sends the command line to that shell. Since the shell has a builtin "echo" which behaves differently than the separate program "echo", whether make starts a shell or invokes echo directly leads to different behavior.

There's really nothing make can do about this. According to the POSIX standard, the "echo" command has implementation-defined results if any operand contains a backslash, so technically neither the shell's builtin echo nor the one in /bin are wrong. Also make cannot assume "echo" is a built-in.

If you want to avoid this, you should do one of the following: (a) stop using echo if the strings to be printed may contain backslashes or the first one could be "-n"; instead switch to printf(1); or (b) in your makefile, always use "/bin/echo" instead of "echo"; at least this will be consistent on a given system (but note that other operating systems may have a /bin/echo that behaves differently in this context.

Paul D. Smith <psmith>
Project Administrator
Tue 22 Sep 2009 08:24:14 AM UTC, original submission:

Hi,

'\nfoo' is interpreted differently by echo:

| foo@bar % cat Makefile
| default:
| echo '\nfoo'
| echo '\nfoo' > bar
| foo@bar % make
| echo '\nfoo'
| \nfoo
| echo '\nfoo' > bar
| foo@bar % cat bar
|
| foo
| foo@bar % ls -l /bin/sh
| lrwxrwxrwx 1 root root 4 11. Aug 11:51 /bin/sh -> dash

If SHELL is set to '/bin/dash' this changes:
| foo@bar % cat Makefile
| SHELL=/bin/dash
| default:
| echo '\nfoo'
| echo '\nfoo' > bar
| foo@bar % make
| echo '\nfoo'
|
| foo
| echo '\nfoo' > bar
| foo@bar % cat bar
|
| foo

When SHELL is set to '/bin/sh' the strange behavior arises again:
| foo@bar % cat Makefile
| SHELL=/bin/sh
| default:
| echo '\nfoo'
| echo '\nfoo' > bar
| foo@bar % make
| echo '\nfoo'
| \nfoo
| echo '\nfoo' > bar
| foo@bar % cat bar
|
| foo

HTH

| foo@bar % make --version
| GNU Make 3.81
| Copyright (C) 2006 Free Software Foundation, Inc.
| This is free software; see the source for copying conditions.
| There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
| PARTICULAR PURPOSE.
|
| This program built for i486-pc-linux-gnu
| foo@bar % cat /etc/debian_version
| squeeze/sid
| foo@bar % apt-cache policy make
| make:
| Installed: 3.81-6
| Candidate: 3.81-6
| Version table:
| *** 3.81-6 0
| 500 http://ftp.de.debian.org testing/main Packages
| 100 /var/lib/dpkg/status

Anonymous

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by psmith (Posted a comment)
  •  

    Do you think this task is very important?
    If so, you can add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.

     

     

     

    Follow 2 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2009-09-22 psmith StatusNone => Not A Bug
        Open/ClosedOpen => Closed

    Back to the top


    Powered by Savane 3.4