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

 
 

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

Submitter:  None
Submitted:  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
* Mandatory Fields

Add a New Comment Rich Markup
   

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>
Group 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:

$ /bin/dash -c "/bin/echo '\nhi'"
\nhi

$ /bin/dash -c "echo '\nhi'"

hi


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>
Group 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)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    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.13-02a9.
    Corresponding source code