Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

changing the shebang of ruby files best way ?

0 views
Skip to first unread message

Une Bévue

unread,
Jun 27, 2008, 4:21:43 PM6/27/08
to
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

Greg Donald

unread,
Jun 27, 2008, 4:46:33 PM6/27/08
to
On Fri, Jun 27, 2008 at 3:22 PM, Une Bévue
<unbewus...@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


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

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

Une Bévue

unread,
Jun 27, 2008, 5:10:35 PM6/27/08
to
Greg Donald <gdo...@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

fine, thanks, i'll switch from ruby to zsh ;-)
--
Une Bévue

Igal Koshevoy

unread,
Jun 27, 2008, 5:55:50 PM6/27/08
to
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

e

unread,
Jun 28, 2008, 12:01:50 AM6/28/08
to
In article <1ij7ltk.jdqdo9zynmjxN%unbewus...@weltanschauung.com.invalid>, unbewus...@weltanschauung.com.invalid (=?ISO-8859-1?Q?Une_B=E9v?=

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

Ryan Davis

unread,
Jun 28, 2008, 3:41:04 PM6/28/08
to

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

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


Une Bévue

unread,
Jun 29, 2008, 6:56:03 AM6/29/08
to
e <efried...@yahoo.com> wrote:

>
> 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...
--
Une Bévue

Greg Donald

unread,
Jun 29, 2008, 1:09:10 PM6/29/08
to
On Sat, Jun 28, 2008 at 2:41 PM, Ryan Davis <ryand...@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.

Garance A Drosehn

unread,
Jun 29, 2008, 11:59:46 PM6/29/08
to
On Sat, Jun 28, 2008 at 3:41 PM, Ryan Davis <ryand...@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.
>

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

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

Ryan Davis

unread,
Jun 30, 2008, 2:55:01 PM6/30/08
to

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

> On Sat, Jun 28, 2008 at 2:41 PM, Ryan Davis <ryand-
> ru...@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.

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


Ryan Davis

unread,
Jun 30, 2008, 3:14:50 PM6/30/08
to

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?


Marc Heiler

unread,
Jun 30, 2008, 4:31:45 PM6/30/08
to
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/.

Garance A Drosehn

unread,
Jul 20, 2008, 4:10:29 PM7/20/08
to

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

Garance A Drosehn

unread,
Jul 20, 2008, 4:12:05 PM7/20/08
to
(apologies if my previous message to this thread
is wrapped very weirdly...)

Garance A Drosehn

unread,
Jul 20, 2008, 4:32:55 PM7/20/08
to
On Mon, Jun 30, 2008 at 4:31 PM, Marc Heiler <shev...@linuxmail.org> wrote:
> 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.

Ryan Davis

unread,
Jul 21, 2008, 2:54:54 AM7/21/08
to

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

> On Mon, Jun 30, 2008 at 3:14 PM, Ryan Davis <ryand-
> ru...@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.

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


David Masover

unread,
Jul 23, 2008, 12:16:59 AM7/23/08
to
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.

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.

Garance A Drosehn

unread,
Jul 26, 2008, 7:00:44 PM7/26/08
to
On Mon, Jul 21, 2008, Ryan Davis <ryand...@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. :/

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

0 new messages