Changing the shebang of ruby files best way?

I've a lot of ruby files (grabed from net) having a wrong shebang for my
setup.

actual shebang is :
#!/usr/bin/ruby -w

and i need to change it to :
#! /usr/bin/env ruby -w

that way i'll get the ruby in my PATH and not a fixed ruby.

what i plan to do :

detect if the shebang isn't correct and if true :
move the file to a temp directory
create a new with "good" shebang having path/name of the previous

remove the tmp dir

but i wonder, because i know i have to change the first line only, if i
could change the uncorrect file "in place" even if my shebang line is
longer (4 chars) than the preceeding one ???

···

--
Une Bévue

for file in *.rb; do
  cp $file $file.tmp
  sed -e "s/#!\/usr\/bin\/ruby\ -w$/#!\/usr\/bin\/env\ ruby\ -w/g"
$file.tmp >$file
  rm $file.tmp
done

···

On Fri, Jun 27, 2008 at 3:22 PM, Une Bévue <unbewusst.sein@weltanschauung.com.invalid> wrote:

I've a lot of ruby files (grabed from net) having a wrong shebang for my
setup.

actual shebang is :
#!/usr/bin/ruby -w

and i need to change it to :
#! /usr/bin/env ruby -w

--
Greg Donald
http://destiney.com/

In article <1ij7ltk.jdqdo9zynmjxN%unbewusst.sein@weltanschauung.com.invalid>, unbewusst.sein@weltanschauung.com.invalid (=?ISO-8859-1?Q?Une_B=E9v?=
=?ISO-8859-1?Q?ue?=) wrote:

I've a lot of ruby files (grabed from net) having a wrong shebang for my
setup.

actual shebang is :
#!/usr/bin/ruby -w

and i need to change it to :
#! /usr/bin/env ruby -w

that way i'll get the ruby in my PATH and not a fixed ruby.

what i plan to do :

detect if the shebang isn't correct and if true :
move the file to a temp directory
create a new with "good" shebang having path/name of the previous

remove the tmp dir

but i wonder, because i know i have to change the first line only, if i
could change the uncorrect file "in place" even if my shebang line is
longer (4 chars) than the preceeding one ???

Just create a symbolic link to /usr/bin and leave the shebang

the problem is that /usr/bin/env absolutely sucks on linux. -w is not only NOT passed as an argument to "ruby", it is considered part of ruby (eg "ruby -w") and horks the exec.

If you're tweaking shebang lines JUST FOR YOU, this is fine... but I get a bunch of tickets filed against my software that it doesn't work for them (mitigated by installing via rubygems). I try to tell them to file a bug against their linux distro, but they don't seem to agree with me most of the time. :slight_smile:

···

On Jun 27, 2008, at 13:22 , Une Bévue wrote:

I've a lot of ruby files (grabed from net) having a wrong shebang for my
setup.

actual shebang is :
#!/usr/bin/ruby -w

and i need to change it to :
#! /usr/bin/env ruby -w

fine, thanks, i'll switch from ruby to zsh :wink:

···

Greg Donald <gdonald@gmail.com> wrote:

for file in *.rb; do
  cp $file $file.tmp
  sed -e "s/#!\/usr\/bin\/ruby\ -w$/#!\/usr\/bin\/env\ ruby\ -w/g"
$file.tmp >$file
  rm $file.tmp
done

--
Une Bévue

Greg Donald wrote:

for file in *.rb; do
  cp $file $file.tmp
  sed -e "s/#!\/usr\/bin\/ruby\ -w$/#!\/usr\/bin\/env\ ruby\ -w/g"
$file.tmp >$file
  rm $file.tmp
done
  

Or as sh and Ruby:

for file in *.rb; do
    ruby -p -i.bak -e '$_.sub!(%r{(#!)(/usr/bin/ruby)( -w)?}, "\\1/usr/bin/env ruby -w")' "$file"
done

Or using find and Ruby to recurse the entire tree:

find . -type f -name '*.rb' -exec ruby -p -i.bak -e '$_.sub!(%r{(#!)(/usr/bin/ruby)( -w)?}, "\\1/usr/bin/env ruby -w")' {} \;

The "-i.bak" tells Ruby to do in-place replacements and backup originals to that file extension.

-igal

there is another ruby there...
the default ruby (Apple installed) is under /usr, the used ruby is under
/opt, i'm using the latest...

···

e <efriedNOspam@yahoo.com> wrote:

Just create a symbolic link to /usr/bin and leave the shebang

--
Une Bévue

You can set $VERBOSE, $-w, or $-v to true to get the same effect as ruby -w.

···

On Sat, Jun 28, 2008 at 2:41 PM, Ryan Davis <ryand-ruby@zenspider.com> wrote:

the problem is that /usr/bin/env absolutely sucks on linux. -w is not only
NOT passed as an argument to "ruby", it is considered part of ruby (eg "ruby
-w") and horks the exec.

--
Greg Donald
http://destiney.com/

FWIW, the problem here is not 'env', it's the way that '#!' lines are
parsed. The 'env' will do the correct thing if it is given separate
parameters, but the kernel-level exec processor does not parse out all the
individual fields in a '#!'-line. It parses "the executable" and
"everything else", and then passes "everything else" as a single parameter
to "the executable". And at this point, it would be much too incompatible a
change to have the exec processor parse it in any other way. There's even
some logic to the way that parsing is done, although I don't remember it at
the moment.

The 'env' command in FreeBSD provides a way around this, by adding some more
options to 'env' so it can parse out the individual options, but I don't
know if any other OS's will notice that and pick up the options. (note:
I'm the guy who added those options to 'env' in FreeBSD...)

···

On Sat, Jun 28, 2008 at 3:41 PM, Ryan Davis <ryand-ruby@zenspider.com> wrote:

On Jun 27, 2008, at 13:22 , Une Bévue wrote:

actual shebang is :

#!/usr/bin/ruby -w

and i need to change it to :
#! /usr/bin/env ruby -w

the problem is that /usr/bin/env absolutely sucks on linux. -w is not only
NOT passed as an argument to "ruby", it is considered part of ruby (eg "ruby
-w") and horks the exec.

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

what about -s? or a myriad of other options...

···

On Jun 29, 2008, at 10:09 , Greg Donald wrote:

On Sat, Jun 28, 2008 at 2:41 PM, Ryan Davis <ryand- > ruby@zenspider.com> wrote:

the problem is that /usr/bin/env absolutely sucks on linux. -w is not only
NOT passed as an argument to "ruby", it is considered part of ruby (eg "ruby
-w") and horks the exec.

You can set $VERBOSE, $-w, or $-v to true to get the same effect as ruby -w.

I've been told that FreeBSD is going to start acting like linux in this regard... is that true?

···

On Jun 29, 2008, at 20:59 , Garance A Drosehn wrote:

The 'env' command in FreeBSD provides a way around this, by adding some more
options to 'env' so it can parse out the individual options, but I don't
know if any other OS's will notice that and pick up the options. (note:
I'm the guy who added those options to 'env' in FreeBSD...)

Actually relying on env in itself as absolute path is pretty weird.
After all, env is supposed to do away with the problems imposed by the
FHS.

I wonder whether the first shebang line could not just simply be "env"
instead (or the binary in question, without absolute path) and then
there would be a simple file where one could tell env which path should
be used.

···

--
Posted via http://www.ruby-forum.com/.

I'm not sure what you mean. The last I checked, freebsd parses the
'#!' line in the0
same way that Linux, Solaris, and a few other unixes did. FreeBSD
*used* to have
a different way for parsing that line, but a few years ago I fixed it
to parse the line
the same way every other unix parses it.

As for the 'env' command, the version on FreeBSD is pretty much the
same as `env'
on other unixes, except that I added a few new options which can be very useful
when using 'env' on a '#!' line. Admittedly I have not checked the
latest versions of
linux though, so maybe they added some other options to 'env'.

So I don't know what you are referring to when you ask if it is going
to start acting
like linux...

···

On Mon, Jun 30, 2008 at 3:14 PM, Ryan Davis <ryand-ruby@zenspider.com> wrote:

On Jun 29, 2008, at 20:59 , Garance A Drosehn wrote:

The 'env' command in FreeBSD provides a way around this, by adding some more
options to 'env' so it can parse out the individual options, but I don't
know if any other OS's will notice that and pick up the options. (note:
I'm the guy who added those options to 'env' in FreeBSD...)

I've been told that FreeBSD is going to start acting like linux in this regard... is that true?

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

(apologies if my previous message to this thread
is wrapped very weirdly...)

···

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

Actually relying on env in itself as absolute path is pretty weird.
After all, env is supposed to do away with the problems imposed
by the FHS.

It is a little weird, but I think it's the best tactic we've got for now.

I wonder whether the first shebang line could not just simply be "env"
instead (or the binary in question, without absolute path) and then
there would be a simple file where one could tell env which path
should be used.

The problem is getting this new idea implemented on a large
number of platforms. If you are writing scripts for a single
platform (say, "redhat linux"), then there is no problem using
'/bin/env' or '/usr/bin/env' (both of which exist on the linux
machine I'm looking at).

If you're going to run your scripts on many platforms, and if
you do not like the hard-coded path to 'env', then you need to
come up with some new solution. The problem is that you then
have to get *that* solution implemented on every platform that
you care about. Until you do get it available everywhere,
then you're going to have to fall back to some other solution
for some of the platforms.

···

On Mon, Jun 30, 2008 at 4:31 PM, Marc Heiler <shevegen@linuxmail.org> wrote:

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

What I meant was, currently all the versions of freebsd that I use as well as OSX do a good job of parsing the shebang line so that options and/or trailing arguments are not considered part of the executable name. That is decidedly NOT the case on linux and a constant PITA as far as I'm concerned.

not all ruby command line options have any other equivalent way of activating their functionality. For example, while -I has $:/$LOAD_PATH, -s has no analogous enabler. This means either I can't use the functionality or I can't use /usr/bin/env because it'll break on linux. :confused:

···

On Jul 20, 2008, at 13:10 , Garance A Drosehn wrote:

On Mon, Jun 30, 2008 at 3:14 PM, Ryan Davis <ryand- > ruby@zenspider.com> wrote:

On Jun 29, 2008, at 20:59 , Garance A Drosehn wrote:

The 'env' command in FreeBSD provides a way around this, by adding some more
options to 'env' so it can parse out the individual options, but I don't
know if any other OS's will notice that and pick up the options. (note:
I'm the guy who added those options to 'env' in FreeBSD...)

I've been told that FreeBSD is going to start acting like linux in this regard... is that true?

I'm not sure what you mean. The last I checked, freebsd parses the '#!' line in the0 same way that Linux, Solaris, and a few other unixes did. FreeBSD *used* to have a different way for parsing that line, but a few years ago I fixed it to parse the line the same way every other unix parses it.

How about via RubyGems? (Assume we can use more complex workarounds to get
RubyGems installed...)

Just have RubyGems detect the platform, and, when it installs a script for a
particular Gem, have it add the appropriate shebang.

···

On Sunday 20 July 2008 15:32:55 Garance A Drosehn wrote:

The problem is getting this new idea implemented on a large
number of platforms.

For what it's worth, this is what I do for a safe cross-platform way
to avoid the problem. You could obviously skip the section on setting
a new value for PATH, but my environment is such that ruby believes
some directories in my PATH are world-writeable, when in fact they
are not.

#!/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
export OSRUBYBIN

# Set a safe value for PATH here, as the cheapest way to avoid the
# annoying ruby message: "warning: Insecure world writable dir ..."
# Make a copy of the user's original PATH, in case the script needs it.
PATH_PRERUBY="$PATH"
export PATH_PRERUBY
PATH="/bin:/sbin:/usr/local/bin:/usr/bin:/usr/sbin"
export PATH

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
# -------+---------+---------+-------- + --------+---------+---------+---------+
p "Hello World"
exit 0

···

On Mon, Jul 21, 2008, Ryan Davis <ryand-ruby@zenspider.com> wrote:

What I meant was, currently all the versions of freebsd that I use as
well as OSX do a good job of parsing the shebang line so that options
and/or trailing arguments are not considered part of the executable
name. That is decidedly NOT the case on linux and a constant PITA as
far as I'm concerned.

Not all ruby command line options have any other equivalent way of
activating their functionality. For example, while -I has
$:/$LOAD_PATH, -s has no analogous enabler. This means either I
can't use the functionality or I can't use /usr/bin/env because
it'll break on linux. :confused:

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