changing the shebang of ruby files best way ?

U

Une Bévue

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

Greg Donald

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


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



--=20
Greg Donald
http://destiney.com/
 
U

Une Bévue

Greg Donald said:
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

fine, thanks, i'll switch from ruby to zsh ;-)
 
I

Igal Koshevoy

Greg said:
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
 
E

e

[email protected] (=?ISO-8859-1?Q?Une_B=E9v?= said:
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
 
R

Ryan Davis

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

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

only NOT passed as an argument to "ruby", it is considered part of =20
ruby (eg "ruby -w") and horks the exec.

If you're tweaking shebang lines JUST FOR YOU, this is fine... but I =20
get a bunch of tickets filed against my software that it doesn't work =20=

for them (mitigated by installing via rubygems). I try to tell them to =20=

file a bug against their linux distro, but they don't seem to agree =20
with me most of the time. :)
 
U

Une Bévue

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

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

Greg Donald

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

Garance A Drosehn

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

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 mor=
e
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...)

--=20
Garance Alistair Drosehn =3D (e-mail address removed)
Senior Systems Programmer
Rensselaer Polytechnic Institute; Troy, NY; USA
 
R

Ryan Davis

On Sat, Jun 28, 2008 at 2:41 PM, Ryan Davis <ryand-


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

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

Ryan Davis

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

Marc Heiler

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

Garance A Drosehn

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.

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

Garance A Drosehn

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

Ryan Davis

On Mon, Jun 30, 2008 at 3:14 PM, Ryan Davis <ryand-


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.

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. :/
 
D

David Masover

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

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

Garance A Drosehn

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

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,125
Latest member
VinayKumar Nevatia_
Top