On 1/31/07, Eric Hodel <drbrain / segment7.net> wrote: > On Jan 31, 2007, at 08:45, Rob Sanheim wrote: > > I'm trying to convert some bash scripts to use /usr/bin/env ruby > > instead of hardcoded shebang lines, and running into an issue. Using > > this: > > > > #!/usr/bin/env ruby -w > > > > results in this error: > > > > /usr/bin/env: ruby -w: No such file or directory > > > > If I remove the -w, it runs and works fine. But of course, I want > > the warnings check in there... > > Linux's env/shebang is broken, so you can't use the shebang this > way. It decides "ruby -w" is the name of the thing you want to > lookup, and of course env can't find that because there isn't one. This is not the fault of Linux. It's an unavoidable consequence of the way the shebang-line is defined in various standards. In fact, I'm the guy who fixed FreeBSD to comply with those standards, and thus I deliberately changed the way FreeBSD handled shebang lines from "convenient" to "broken". For reasons which might not be intuitively obvious, the broken behavior is required. Since FreeBSD *used* to process the shebang line in a more convenient way, I also came up with some changes to /usr/bin/env which can be used to recreate the more convenient problem. However, those new options are only available on FreeBSD (afaik). I also have to write ruby or perl scripts which have to work on a variety of unix-based operating systems. What I have come up with is the following. I'm sure that it will not work on some operating system, but it works on the dozen operating systems that I have to care about, in all situations that I have cared about. #!/bin/sh # -------+---------+---------+-------- + --------+---------+---------+---------+ # / This section is a safe way to find the interpretter for ruby, \ # | without caring about the user's setting of PATH. This reduces | # | the problems from ruby being installed in different places on | # | various operating systems. A much better solution would be to | # | use `/usr/bin/env -S-P' , but right now `-S-P' is available | # \ only on FreeBSD 5, 6 & 7. Garance/2005 / OSRUBYBIN= for fname in /usr/local/bin /opt/csw/bin /opt/local/bin /usr/bin ; do if [ -x "$fname/ruby" ] ; then OSRUBYBIN="$fname/ruby" ; break; fi done if [ -z "$OSRUBYBIN" ] ; then echo "Unable to find a 'ruby' interpretter!" >&2 exit 1 fi eval 'exec "$OSRUBYBIN" -x -S $0 ${1+"$@"}' echo "The 'exec \"$OSRUBYBIN\" -x -S ...' failed!" >&2 exit 1 #! This #!-line starts the real script, due to the marker: ruby ....[ and then the first line of the real ruby script]... Obviously you could add the '-w' after '-x' on the eval/exec line, if you also wanted that option. And if you do something weird like install 'ruby' in /bin (so that you can find out when /usr is not mounted), then you'd need to add that to the list of directories which are searched. In some cases, I also set a new value for PATH= in the /bin/sh portion of the script, to avoid ruby's warning about an "Insecure world writable dir". That warning message can also be avoided by setting $VERBOSE in the ruby script, but in some cases it's just easier for me to change the value for PATH. I suspect that all this is too esoteric for most people to other with! :-) It really is rather absurdly complicated to get 100% right in 100% of the situations that every ruby script might be run in. -- Garance Alistair Drosehn = drosihn / gmail.com Senior Systems Programmer Rensselaer Polytechnic Institute; Troy, NY; USA