Bug 219409 - multi-line commands don't work when SHELL is set
Summary: multi-line commands don't work when SHELL is set
Status: CLOSED RAWHIDE
Alias: None
Product: Fedora
Classification: Fedora
Component: make
Version: 6
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Petr Machata
QA Contact: Brian Brock
URL:
Whiteboard:
Keywords:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2006-12-12 22:37 UTC by Ian Collier
Modified: 2015-05-05 01:32 UTC (History)
1 user (show)

(edit)
Clone Of:
(edit)
Last Closed: 2007-02-22 17:58:59 UTC


Attachments (Terms of Use)
a Makefile showing the problem (72 bytes, text/plain)
2006-12-12 22:37 UTC, Ian Collier
no flags Details

Description Ian Collier 2006-12-12 22:37:22 UTC
Description of problem:
make 3.81 differs in how it treats multi-line statements depending on whether or
not the SHELL is specified.  It didn't do this in 3.80.

Version-Release number of selected component (if applicable):
make-3.81-1.1

How reproducible:
Always

Steps to Reproduce:
1. Use the attached Makefile
2. make
3. Un-comment the first line
4. make
  
Actual results:
First run:
for i in one two three; do \
                echo $i; \
        done
one
two
three

Second run:
for i in one two three; do \
                echo $i; \
        done
/bin/sh: -c: line 1: syntax error: unexpected end of file
/bin/sh: line 1:        echo $i; \: command not found
/bin/sh: -c: line 2: syntax error near unexpected token `done'
/bin/sh: -c: line 2: `done'
make: *** [all] Error 2

Expected results:
Same both times, no syntax error

Additional info:
Since the docs say that when SHELL is not set, /bin/sh is used, I wouldn't
expect a difference.  Indeed, the docs say that every Makefile should set the
SHELL to /bin/sh (section 14.1, "General Conventions for Makefiles").  However,
tracing shows that when SHELL is set, make invokes an extra shell like this:

/bin/sh -c "\"/bin/sh\" -c for\\ i\\ in\\ one\\ two\\ three\\;\\ do\\ \\\\\n..."

That part hasn't changed since 3.80, though.  What has changed is the treatment
of line-ends.  The newlines are passed without quoting them, so they are
interpreted by the outer shell instead of the inner shell.  The inner shell only
ever gets the first line of the command; the outer shell gets the rest of the
lines as quoted strings and thus usually can't execute them.

Eliminating the double shell would fix this in the case that SHELL=/bin/sh. 
However, single-quoting the newlines might also fix it:

/bin/sh -c "\"/bin/sh\" -c for\\ i\\ in\\ one\\ two\\ three\\;\\ do\\ \\\\'\n'..."

The Makefile mentioned above, which I'll also try to attach, is as follows:

#SHELL="/bin/sh"
all:
        for i in one two three; do \
                echo $$i; \
        done

Comment 1 Ian Collier 2006-12-12 22:37:22 UTC
Created attachment 143470 [details]
a Makefile showing the problem

Comment 2 Petr Machata 2007-02-21 16:59:25 UTC
Confirmed.  Didn't find anything relevant in documentation.  Didn't find related
bug upstream, only several bugs with backshlash-eol handling.  The problem
arises when shell program, or any of its arguments, contain non-path characters.
 In that case, another shell is invoked, and whole command is passed through
that. This includes e.g. cases when SHELL contents is quoted or back-ticked. 
White space is handled just fine, make will consider them argument separators.

This works:

SHELL:=/usr/bin/env python
all:; @print 6,\
	 5

This fails:

SHELL:=/usr/bin/env ""python
all:; @print 6,\
	 5

Comment 3 Petr Machata 2007-02-22 17:58:59 UTC
Fixed in rawhide.


Note You need to log in before you can comment on or make changes to this bug.