This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: cygwin-bash compat/regression bug... startup line prob


On 04/30/2014 11:57 PM, Linda Walsh wrote:
> Eric Blake wrote:
>> On 04/28/2014 02:43 PM, Linda Walsh wrote:
>>
>> >> cat bin/t.sh
>> > #!/bin/bash -u 
> Um... it doesn't work with 1 argument either.

Your context quoting is hard to follow. Here, you are complaining about
a she-bang with only one argument,...

>>
>> This is an invalid shebang line.  Historically, you are allowed at most
>> ONE argument to the program that you will be executing.
> ?!? Historically?.. since when?  Never encountered that problem on linux
> nor on cygwin.  This isn't a case of 2 args, just the "-u" by itself
> doesn't work.

...but here, you are quoting my reply to your original example that
included two arguments, although you managed to snip that original text
[for reference, my comment was about _this_ portion of your mail:

| > cat bin/t.sh
| #!/bin/bash -u -x

which is indeed invalid usage].  I made no comment confirming or denying
whether your use of '-u' by itself works (as I was not on cygwin when I
wrote my first reply, and so had no easy way to confirm or refute if
one-argument -u "works" on cygwin); but was merely pointing out that in
your further investigation of the issue, you were creating an
unsupported 2-argument she-bang line, and thus not testing what you
thought you were testing.

As for history of shebang,
https://en.wikipedia.org/wiki/Shebang_%28Unix%29 states that whether
subsequent arguments are split (Solaris) or provided as one argument
(Linux) has been a long time issue, quoting at least this article from
2008
http://mail-index.netbsd.org/netbsd-users/2008/11/09/msg002388.html,
although I'm sure you could trace it back at least to the 1980s.  The
Linux man pages for execve state:

       A maximum line length of 127 characters is allowed for the  first
 line
       in a #! executable shell script.

       The  semantics  of  the  optional-arg argument of an interpreter
script
       vary across implementations.  On Linux, the entire string
following the
       interpreter name is passed as a single argument to the
interpreter, and
       this string can include white space.  However, behavior differs
on some
       other  systems.   Some  systems  use the first white space to
terminate
       optional-arg.  On some systems, an interpreter script can have
multiple
       arguments,  and  white  spaces  in optional-arg are used to
delimit the
       arguments.

Since cygwin emulates Linux, it makes sense that Cygwin likewise accepts
exactly one argument on the shebang line.

> 
>> > Also weird -- the interp line says "/bin/bash" not "/usr/bin/bash"
>> > as the shell, so why does the error come from /usr/bin/bash?
>>
>> the answer to this question.
> ---
> ???
> This isn't clear to me.  If I am running /bin/bash, why did the error
> message
> say /usr/bin/bash?
> 

Because you weren't running /bin/bash at that point in time, but
/usr/bin/bash.  Again, you snipped the relevant portion of your original
mail:

| > bash t.sh

but that says to run 't.sh' using the 'bash' interpreter found first in
your PATH (which presumably had /usr/bin before /bin), and not as a
standalone executable.  A shebang line is ignored when you run a script
directly as an argument to 'bash' - the only time a shebang line is
honored is when it appears as argv[0] of the execve() family of
functions (your command line had it as argv[1]).  To use the shebang,
you have to execute 't.sh', not 'bash t.sh'.  Remember, when bash
executes a script, the #! line is a comment that does not further impact
how bash behaves.

(If you look at the bash source code, it does have fallback code to
emulate shebang magic on platforms where execve() fails due to lacking
shebang support.  But there are two things to note - this fallback does
NOT kick in on cygwin, since cygwin's execve() DOES have shebang
support; and even with that fallback code in bash, it is still only
triggered in instances where you try to execute a script as argv[0] of
the child process, and NOT when you pass the script name as argv[1] of
the bash process.)

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]