NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: bin/45430: ash uses argv[0] as $0 for scripts without #!



Thank you for the reply, David.
Please see my reply below.

On 11/05/2011 07:15 PM, David Holland wrote:

  Do they?

  valkyrie% cat test
  echo "$0"
  valkyrie% sh -c './test'
  ./test
  valkyrie% csh -c './test'
  ./test
  valkyrie% ksh -c './test'
  ./test
  valkyrie% bash -c './test'
  ./test
  valkyrie% tcsh -c './test'
  ./test
  valkyrie% zsh -c './test'
  ./test
  valkyrie%

The behavior above suits me perfectly. It seems you misunderstood the issue,
so I still have hope :)


  Anyway, I think what you're doing is almost certainly a mistake.

I'm aware that this is almost a hack. Unfortunately, I have little choice.

I see that your ash version behavior differs from the majority of shells out
there and am simply hoping you would have mercy to do a practical thing that
won't affect anything much, but would help us and maybe some other system
engineers having to deal with Android systems.

In essence the problem is that a non setuid shebang-less script could always
get its own contents (through accessing the file at $0) on dash, busybox,
bash, csh, tcsh and zsh, but not on ksh or NetBSD ash. The only case which
isn't working with these two is when such a script is invoked with just a
filename, using PATH lookup. The most convenient case.

To illustrate:

$ mkdir tmpbin
$ echo 'echo $0' > tmpbin/noshebang
$ chmod 755 tmpbin/noshebang
$ export PATH=$PATH:`pwd`/tmpbin
$ zsh -c noshebang
/home/nick/tmpbin/noshebang
$ csh -c noshebang
/home/nick/tmpbin/noshebang
$ tcsh -c noshebang
/home/nick/tmpbin/noshebang
$ bash -c noshebang
/home/nick/tmpbin/noshebang
$ dash -c noshebang
/home/nick/tmpbin/noshebang
$ busybox sh -c noshebang
/home/nick/tmpbin/noshebang
$ ksh -c noshebang
noshebang
$ sh -c noshebang
noshebang

The last one is supposed to be NetBSD ash and is faked, but this is what
would happen.

Now, the specific problem I'm having (as described at the URL which 
unfortunately
didn't work for you) is the following.

I need to run the same Lua test scripts, without changes, both on a
development board running Android and on Linux host for use with a GPU
simulator.

The standard location for executables on Android is /system/bin. There is no
/usr. Root filesystem is rootfs and as such is not writable. I can't ask the
engineers to reflash root filesystem in case they need to build and run
tests. It would be too intrusive to modify rootfs unconditionally for all
the builds. So there can't be /usr and as such /usr/bin/lua, which would
have matched the Linux system. For the same reason there can't be
/usr/bin/env. There is also no /bin/sh. Yes, I have a lot to say to Android
designers.

So the solution was to use this pseudo-shebang at the beginning of files:

-- 2>/dev/null; exec lua "$0" "$@"

"--" here is the beginning of a Lua comment.

It would work with execlp/execvp/execvpe (libc does that). It wouldn't work
with execl/execle/execv, but these require a full program path specification
and this is what we're trying to avoid here, so it's not a problem.

It would work in a shell using an explicit program file path (as you've
shown above), because in this case shells provide what they get. It would
work if run using just file name on dash, busybox, bash, csh, tcsh and zsh
(because these provide the path found through PATH lookup), but not on ksh
or NetBSD ash, which Android uses (because these provide what they get).

So I'm asking: could you please consider accepting this as a useful and
practical thing to do for the benefit of people having to use Android?


  By convention the value of argv[0] is whatever the invoker supplies, and
  with most shells by (mostly tacit) convention that is the path used to
  invoke the program if a path was given (with at least one slash)

This is perfectly suitable.


  and just the name if the program was found somewhere on $PATH.  In some
  cases the full path will get substituted; and, as David Laight hinted
  at, for

This isn't true. At least on Linux. Most of the shells I've tried supply the
full path. The shebang-less case is demonstrated above. Now for the shebang
case. The interpreter paths might not match a NetBSD system, but still,
continuing the above:

$ touch tmpdir/shebang
$ chmod 755 tmpbin/shebang
$ (echo '#!/usr/bin/zsh';       echo 'echo $0') > tmpbin/shebang; shebang
/home/nick/tmpbin/shebang
$ (echo '#!/bin/csh';           echo 'echo $0') > tmpbin/shebang; shebang
/home/nick/tmpbin/shebang
$ (echo '#!/usr/bin/tcsh';      echo 'echo $0') > tmpbin/shebang; shebang
/home/nick/tmpbin/shebang
$ (echo '#!/bin/bash';          echo 'echo $0') > tmpbin/shebang; shebang
/home/nick/tmpbin/shebang
$ (echo '#!/bin/dash';          echo 'echo $0') > tmpbin/shebang; shebang
/home/nick/tmpbin/shebang
$ (echo '#!/bin/busybox sh';    echo 'echo $0') > tmpbin/shebang; shebang
/home/nick/tmpbin/shebang
$ (echo '#!/usr/bin/ksh';       echo 'echo $0') > tmpbin/shebang; shebang
/home/nick/tmpbin/shebang
$ (echo '#!/bin/sh';            echo 'echo $0') > tmpbin/shebang; shebang
/home/nick/tmpbin/shebang

The last case is faked again, but this is basically what would happen on
Android with NetBSD ash it uses.


  and, as David Laight hinted at, for a setuid script the value won't be
  the file at all but something in /dev/fd. (Not that sh scripts should
  ever be setuid...  but still.)

Yes, setuid's are an exception and is not a portable one at that.


  However, relying on the full path to be substituted (or for that
  matter, even relying on it to be a name for the running script) is a
  bad idea, because it might not be.

  There's probably a better way to do what you're trying to accomplish.

Thanks, but I've searched long without luck. There is another, yet a less
portable way. Using this shebang instead:

-- 2>/dev/null; exec lua "`command -v \"$0\"`" "$@"

This one wouldn't work with csh and tcsh. They just don't have "command".
AFAIK, csh and tcsh are more popular than ksh, thus harder to ignore. And
changing this particular behavior of NetBSD ash has much lower impact than
adding "command" to csh and tcsh.

However, I accept that this is *your* shell and you guard its behavior for
the sake of stability.


 Details, if anyone is curious:
 https://plus.google.com/109969355357893765097/posts/2tmx3gmK3yY

  This gives me a blank page.

I'm sorry. Yet, this is quite unexpected. I've tested it again now and it
works for me even in Lynx.


 If nothing else, could you please confirm that the patch above doesn't
 break anything?

  No such luck...

Well, thanks for answer anyway :)

Please excuse me if there are any flaws in my writing, I'm having a pretty
bad cold here.

Sincerely,
Nick


Home | Main Index | Thread Index | Old Index