Proper usr/bin/env ruby shebang

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

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...

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))

···

On 1/31/07, Rob Sanheim <rsanheim@gmail.com> wrote:

thanks,
Rob

--
thanks,
-pate
-------------------------

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

···

On Thu, 1 Feb 2007, 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...

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

--
we can deny everything, except that we have the possibility of being better.
simply reflect on that.
- the dalai lama

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

···

--
Nobu Nakada

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.

···

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...

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.

···

On Thu, Feb 01, 2007 at 01:45:15AM +0900, Rob Sanheim wrote:

Any ideas?

You're right, I meant RHEL4.
- rob

···

On 1/31/07, pat eyler <pat.eyler@gmail.com> wrote:

On 1/31/07, Rob Sanheim <rsanheim@gmail.com> 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...
>
> 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...

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))

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

···

On 1/31/07, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:

   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
--

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

···

On 1/31/07, Nobuyoshi Nakada <nobu@ruby-lang.org> wrote:

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

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

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! :slight_smile:
It really is rather absurdly complicated to get 100% right in 100% of
the situations that every ruby script might be run in.

···

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.

--
Garance Alistair Drosehn = drosihn@gmail.com
Senior Systems Programmer
Rensselaer Polytechnic Institute; Troy, NY; USA

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

you can use

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

-a

···

On Thu, 1 Feb 2007, Rob Sanheim wrote:

On 1/31/07, Nobuyoshi Nakada <nobu@ruby-lang.org> wrote:

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

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

--
we can deny everything, except that we have the possibility of being better.
simply reflect on that.
- the dalai lama

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

···

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?

thanks garance! i'm filing this under 'definitive' in my mail :wink:

-a

···

On Fri, 2 Feb 2007, Garance A Drosehn wrote:

#!/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! :slight_smile:
It really is rather absurdly complicated to get 100% right in 100% of
the situations that every ruby script might be run in.

--
we can deny everything, except that we have the possibility of being better.
simply reflect on that.
- the dalai lama

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).

···

On Feb 3, 12:25 am, Daniel DeLorme <dan...@dan42.com> wrote:

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.

···

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.

--
Garance Alistair Drosehn = drosihn@gmail.com
Senior Systems Programmer
Rensselaer Polytechnic Institute; Troy, NY; USA

That will work - thanks.

···

On 1/31/07, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:

On Thu, 1 Feb 2007, Rob Sanheim wrote:

> On 1/31/07, Nobuyoshi Nakada <nobu@ruby-lang.org> wrote:
>> 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
>>
>
> 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

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.

···

On 31 ene, 16:53, Paul Brannan <pbran...@atdesk.com> wrote:

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

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

http://elliotth.blogspot.com/2006/04/lesson-about-using-env1-in-script.html

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

···

On 1/31/07, Rob Sanheim <rsanheim@gmail.com> wrote:

On 1/31/07, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:
> On Thu, 1 Feb 2007, Rob Sanheim wrote:
>
> > On 1/31/07, Nobuyoshi Nakada <nobu@ruby-lang.org> wrote:
> >> 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
> >>
> >
> > 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.