Forum: Ruby proper usr/bin/env ruby shebang

Df5e7adb20adae6c120b04e7cafb15a0?d=identicon&s=25 Rob Sanheim (rsanheim)
on 2007-01-31 17:45
(Received via mailing list)
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...

This works fine from the command line:

rsanheim@seekingalpha06a [/sa/bin]$ /usr/bin/env ruby -w
FOO = "hi"
FOO = "bye"
-:2: warning: already initialized constant FOO

Any ideas?  Forgive me if I'm missing something obvious here...This is
red hat 4, I believe...

thanks,
Rob
Bb6ecee0238ef2461bef3416722b35c5?d=identicon&s=25 pat eyler (Guest)
on 2007-01-31 17:56
(Received via mailing list)
On 1/31/07, Rob Sanheim <rsanheim@gmail.com> wrote:
> If I remove the -w, it runs and works fine.   But of course, I want
> red hat 4, I believe...
Either you're dating yourself, or you mean RHEL 4 ...  (I still have
manuals from both RHL 3 and 4 (and maybe install media if I look
hard enough))
Df5e7adb20adae6c120b04e7cafb15a0?d=identicon&s=25 Rob Sanheim (rsanheim)
on 2007-01-31 17:59
(Received via mailing list)
On 1/31/07, pat eyler <pat.eyler@gmail.com> wrote:
> >
> > Any ideas?  Forgive me if I'm missing something obvious here...This is
> > red hat 4, I believe...
>
> Either you're dating yourself, or you mean RHEL 4 ...  (I still have
> manuals from both RHL 3 and 4 (and maybe install media if I look
> hard enough))
>

You're right, I meant RHEL4.
- rob
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2007-01-31 18:10
(Received via mailing list)
On Thu, 1 Feb 2007, Rob Sanheim wrote:

> If I remove the -w, it runs and works fine.   But of course, I want
> red hat 4, I believe...
>
> thanks,
> Rob

   harp:~ > cat a.rb
   #!/usr/bin/env ruby -w
   p $VERBOSE
   FOO = 42 and FOO = 42

   harp:~ > ruby a.rb
   true
   a.rb:3: warning: already initialized constant FOO

   harp:~ > ruby -v
   ruby 1.8.4 (2005-12-01) [i686-linux]

   harp:~ > uname -srm
   Linux 2.4.21-47.0.1.EL i686

   harp:~ > cat /etc/redhat-release
   Red Hat Enterprise Linux WS release 3 (Taroon Update 8)


what happens for you?

-a
F1d6cc2b735bfd82c8773172da2aeab9?d=identicon&s=25 Nobuyoshi Nakada (Guest)
on 2007-01-31 18:13
(Received via mailing list)
Hi,

At Thu, 1 Feb 2007 01:45:15 +0900,
Rob Sanheim wrote in [ruby-talk:237036]:
> 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

Do not rely on /usr/bin/env, it may not exist.

  #!/bin/sh
  exec ruby -x "$0" "$@"
  #!ruby -w
Df5e7adb20adae6c120b04e7cafb15a0?d=identicon&s=25 Rob Sanheim (rsanheim)
on 2007-01-31 18:18
(Received via mailing list)
On 1/31/07, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:
>    ruby 1.8.4 (2005-12-01) [i686-linux]
> -a
> --

Hmm, so that works -- the issue is where I run it as an executable
(see the end of the log)

sa  [~]$ ruby a.rb
true
a.rb:3: warning: already initialized constant FOO

sa  [~]$ ruby -v
ruby 1.8.5 (2006-12-25 patchlevel 12) [i386-linux]

sa  [~]$ uname -srm
Linux 2.6.9-42.0.3.ELsmp i686

sa  [~]$ cat /etc/redhat-release
Red Hat Enterprise Linux ES release 4 (Nahant Update 4)

sa  [~]$ chmod +x a.rb

sa  [~]$ ./a.rb
/usr/bin/env: ruby -w: Permission denied

- Rob
Df5e7adb20adae6c120b04e7cafb15a0?d=identicon&s=25 Rob Sanheim (rsanheim)
on 2007-01-31 18:21
(Received via mailing list)
On 1/31/07, Nobuyoshi Nakada <nobu@ruby-lang.org> wrote:
> > results in this error:
> >
> > /usr/bin/env: ruby -w: No such file or directory
>
> Do not rely on /usr/bin/env, it may not exist.
>
>   #!/bin/sh
>   exec ruby -x "$0" "$@"
>   #!ruby -w
>

Ugh, so I need that at the top of all these scripts?  I thought
/usr/bin/env was the 'better' way to go?
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2007-01-31 18:26
(Received via mailing list)
On Thu, 1 Feb 2007, Rob Sanheim wrote:

>> >
>
> Ugh, so I need that at the top of all these scripts?  I thought
> /usr/bin/env was the 'better' way to go?
>

you can use

   #! /usr/bin/env ruby
   $VERBOSE=true

-a
D032dc2ce8e6e785161fb4e3ebb64ba3?d=identicon&s=25 Kalman Noel (Guest)
on 2007-01-31 18:45
(Received via mailing list)
ara.t.howard:
>    harp:~ > cat a.rb
>    #!/usr/bin/env ruby -w
>    p $VERBOSE
>    FOO = 42 and FOO = 42
>
>    harp:~ > ruby a.rb
>    true
>    a.rb:3: warning: already initialized constant FOO

There's no shell or anything here interpreting the shebang.

Kalman
Df5e7adb20adae6c120b04e7cafb15a0?d=identicon&s=25 Rob Sanheim (rsanheim)
on 2007-01-31 18:50
(Received via mailing list)
On 1/31/07, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:
> >> >
> >>   #!ruby -w
> >>
> >
> > Ugh, so I need that at the top of all these scripts?  I thought
> > /usr/bin/env was the 'better' way to go?
> >
>
> you can use
>
>    #! /usr/bin/env ruby
>    $VERBOSE=true

That will work - thanks.
Df5e7adb20adae6c120b04e7cafb15a0?d=identicon&s=25 Rob Sanheim (rsanheim)
on 2007-01-31 20:06
(Received via mailing list)
On 1/31/07, Rob Sanheim <rsanheim@gmail.com> wrote:
> > >> > this:
> > >>   exec ruby -x "$0" "$@"
> >    $VERBOSE=true
>
> That will work - thanks.

My hosting provider provided this very helpful post on this whole mess:

http://elliotth.blogspot.com/2006/04/lesson-about-...

Which explains why passing in -w wasn't working, and why just setting
$VERBOSE to true isn't the same thing.  Seems like it shouldn't be
this hard to get a cross platform script working, with warnings.

- Rob
58479f76374a3ba3c69b9804163f39f4?d=identicon&s=25 Eric Hodel (Guest)
on 2007-01-31 20:09
(Received via mailing list)
On Jan 31, 2007, at 08:45, Rob Sanheim wrote:
> 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.
Fe6a008c1e3065327d1f1b007d8f1362?d=identicon&s=25 Paul Brannan (cout)
on 2007-01-31 20:55
(Received via mailing list)
On Thu, Feb 01, 2007 at 02:20:38AM +0900, Rob Sanheim wrote:
> Ugh, so I need that at the top of all these scripts?  I thought
> /usr/bin/env was the 'better' way to go?

This issue has come up before (see [ruby-talk:27508]).  However, Austin
Ziegler pointed out in [ruby-talk:56340] that the sh/exec solution won't
work on non-Unix environments.  See also 'perldoc perlrun' for more
discussion on the issue (ruby takes much of its behavior from perl in
this case).

Paul
B74f9ac58c7a0b80d877470198e1a472?d=identicon&s=25 gga (Guest)
on 2007-02-01 00:35
(Received via mailing list)
On 31 ene, 16:53, Paul Brannan <pbran...@atdesk.com> wrote:
> Paul
All solutions posted so far are broken in one way or another.

What will work across platforms and OSes is this:

#! /usr/bin/env ruby

And add:

export RUBYOPT="-w $RUBYOPT"

to your environment (.bashrc) or:

setenv RUBYOPT "-w $RUBYOPT"

for cshrc, tcsh (.cshrc, .tcshrc, etc).   For windows, do:

set RUBYOPT="-w %RUBYOPT%"

in a bat file (or in your environment variables for the user or the
machine).
The additional benefit of this is that you will not only get your
little script compiled with warnings on, but every piece of ruby code
you run, too.
Also, if you need performance, you can easily turn off the -w flag,
without having to modify a single file.
E31a49b77b1987ec5fd28dbfcec33185?d=identicon&s=25 Mike Kasick (Guest)
on 2007-02-01 06:03
(Received via mailing list)
On Thu, Feb 01, 2007 at 01:45:15AM +0900, Rob Sanheim wrote:

> Any ideas?

I tend to do:

#!/usr/bin/env ruby
BEGIN {$VERBOSE = true}

as I think that's the best you can do within a single script.  If the
link referenced in another reply is correct, then warnings won't be
emitted as the script initially loads.  However, doing a manual "ruby -w
foo_script.rb" once to test the code should catch any of these warnings.
Fe6a008c1e3065327d1f1b007d8f1362?d=identicon&s=25 Paul Brannan (cout)
on 2007-02-01 16:22
(Received via mailing list)
On Thu, Feb 01, 2007 at 08:35:08AM +0900, gga wrote:
> What will work across platforms and OSes is this:
>
> #! /usr/bin/env ruby

This will not work for platforms that put env in /bin or don't have /usr
mounted.

Paul
C5be24289f1471f3da84864a6677af12?d=identicon&s=25 Garance A Drosehn (Guest)
on 2007-02-01 23:24
(Received via mailing list)
On 1/31/07, Eric Hodel <drbrain@segment7.net> wrote:
> >
> > 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.
4d36f6edbdcdf94ed95d38eb57cac30f?d=identicon&s=25 Will Parsons (Guest)
on 2007-02-01 23:25
(Received via mailing list)
Paul Brannan wrote:
> On Thu, Feb 01, 2007 at 08:35:08AM +0900, gga wrote:
>> What will work across platforms and OSes is this:
>>
>> #! /usr/bin/env ruby
>
> This will not work for platforms that put env in /bin or don't have /usr
> mounted.
>
Some platforms don't even have an env.  I regularly work on one.

- Will
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2007-02-01 23:27
(Received via mailing list)
On Fri, 2 Feb 2007, Garance A Drosehn wrote:

> for fname in /usr/local/bin /opt/csw/bin /opt/local/bin /usr/bin ; do
> #! This #!-line starts the real script, due to the marker: ruby
> 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.

thanks garance!  i'm filing this under 'definitive' in my mail ;-)

-a
C5be24289f1471f3da84864a6677af12?d=identicon&s=25 Garance A Drosehn (Guest)
on 2007-02-01 23:52
(Received via mailing list)
On 2/1/07, Paul Brannan <pbrannan@atdesk.com> wrote:
> On Thu, Feb 01, 2007 at 08:35:08AM +0900, gga wrote:
> > What will work across platforms and OSes is this:
> >
> > #! /usr/bin/env ruby
>
> This will not work for platforms that put env in /bin or don't have /usr
> mounted.

Well, on many of my systems, if /usr is not mounted, then 'ruby' itself
is also not available!  :-)

I have a bigger concern with using /usr/bin/env for this. The
/usr/bin/env trick will only work if ruby *IS* in the PATH of the
person who is running the ruby script, and if that version of ruby is
the version expected by the script.  On many systems that is a safe
assumption, but it isn't always true.

Consider something like MacOS 10, for instance, where Apple
ships one version of ruby in /usr/bin, but many people will install a
newer version in /opt/local/bin.  I've had some scripts fail because
the user running them didn't have /opt/local/bin in their PATH.

(ie, I helped them install ruby into /opt/local/bin using macports,
but they didn't update their settings for PATH)
B74f9ac58c7a0b80d877470198e1a472?d=identicon&s=25 gga (Guest)
on 2007-02-02 05:10
(Received via mailing list)
On 1 feb, 19:51, "Garance A Drosehn" <dros...@gmail.com> wrote:
> Well, on many of my systems, if /usr is not mounted, then 'ruby' itself
> is also not available!  :-)
>
> I have a bigger concern with using /usr/bin/env for this. The
> /usr/bin/env trick will only work if ruby *IS* in the PATH of the
> person who is running the ruby script, and if that version of ruby is
> the version expected by the script.  On many systems that is a safe
> assumption, but it isn't always true.

It should be.

>
> Consider something like MacOS 10, for instance, where Apple
> ships one version of ruby in /usr/bin, but many people will install a
> newer version in /opt/local/bin.  I've had some scripts fail because
> the user running them didn't have /opt/local/bin in their PATH.
>

More the reason to use /usr/bin/env.  That way, you are not hard-
coding the script to a specific version of ruby.
If you had done the opposite and had used #! /usr/bin/ruby (or
whatever location macs put ruby by default ), your users would have
never been able to use a different version of ruby without having to
manually change the path to ruby in all scripts or type "ruby" itself.
If your users have path issues, your likely problem is not /usr/bin/
env but a bad system-wide .bashrc or .tcshrc configuration file that
is not adding the path automatically (a sysadmin issue) or some lack
of knowledge on the user's part who probably overrode what the
sysadmin did by setting path improperly.  If it is a sysadmin issue,
talk to your sysadmin (and probably, start shopping for a new
sysadmin :).  If it is a user issue, as it is more likely, teach him
how to change variables without overriding system-wide configurations
(ie. PATH=stuff:$PATH instead of just PATH=stuff).
Another way this happens is when a user wants to use an unpopular (or
an incompatible) shell within the company (say, zsh in a place where
tcsh is the default) and as such he does not inherit the settings the
sysadmin sets up for him.  A good way around this (I have found over
the years) is to eventually handle all environment path changes with a
custom script (usually written in perl or ruby) rather than by using
the shell's built-in commands (setenv/export/etc).  The ruby script is
the one in charge of detecting the shell the user is using and spits
out the correct setenv commands for it (this output is evaled thru an
alias).
See for example (this only handle output for a single shell, thou):
http://seriss.com/people/erco/unixtools/ (epath)
or if you want ruby code:
http://www.highend3d.com/downloads/tools/os_utils/...
http://rubyforge.org/projects/ggenv/ ( a simpler library )
B74f9ac58c7a0b80d877470198e1a472?d=identicon&s=25 gga (Guest)
on 2007-02-02 05:20
(Received via mailing list)
On 1 feb, 19:22, Will Parsons <oud...@nodomain.invalid> wrote:
>
> - Will

env in bin is definitively non-standard unix, so that platform is
likely to end with a sudo ln -s /bin/env /usr/bin almost immediately.
I was not aware of any unix platform without env.  What platform are
you on btw?  Obviously windows does not have env, but you solve issues
there with file associations or by using some unix environment (like
cygwin, etc).
E0526a6bf302e77598ef142d91bdd31c?d=identicon&s=25 Daniel DeLorme (Guest)
on 2007-02-03 04:25
(Received via mailing list)
Nobuyoshi Nakada wrote:
> Do not rely on /usr/bin/env, it may not exist.

Also, /usr/bin/env relies on the $PATH env variable,
so if you try to run this as a cron job it will fail
because $PATH is not set.

Daniel
B74f9ac58c7a0b80d877470198e1a472?d=identicon&s=25 gga (Guest)
on 2007-02-03 08:46
(Received via mailing list)
On Feb 3, 12:25 am, Daniel DeLorme <dan...@dan42.com> wrote:
> Nobuyoshi Nakada wrote:
> > Do not rely on /usr/bin/env, it may not exist.
>
> Also, /usr/bin/env relies on the $PATH env variable,
> so if you try to run this as a cron job it will fail
> because $PATH is not set.
>
> Daniel

Again, that's probably bad sysadmin or user error in setting up cron.

> grep PATH /etc/crontab
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

If you run your own cron jobs as a normal user, you should create your
own similar crontab file.  You can do so with:

> crontab /etc/crontab
> crontab -e  # to edit it

(Depending on your linux flavor, your user cron file will be stored
in /var/spool/cron/crontabs/<user> (Unix/Slackware/*BSD),
/var/spool/cron/<user> (RedHat) or /var/cron/tabs/<user> (SuSE).
C5be24289f1471f3da84864a6677af12?d=identicon&s=25 Garance A Drosehn (Guest)
on 2007-03-12 23:00
(Received via mailing list)
On 2/1/07, Garance A Drosehn <drosihn@gmail.com> wrote:
>
>
> 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.


Some people have mentioned that my sample-code was reformatted into
something close to useless by their email (or web-ized mail) clients.
So
here is a very simple "Hello World" script which includes my
ruby-finding
strategy, along with some comments about how it works:

http://people.freebsd.org/~gad/tools/safe_ruby_script

(that is the actual script, and not a web page which displays the
script, so
your web browser might simply download it as a file to your desktop)

I realize that it isn't a truly 100% perfect solution for every possible
situation,
but it has worked well over the past few years for me, writing scripts
which
had to work reliably on several different platforms.
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.