Hash banging #! - Distributing precompiled sharable linux bi

This may, in a very odd set of circumstances, be useful to somebody…

If you try interpret a #! script with another #! script it fails. (I
wrote about this problem before…)

One fix is to use #!/usr/bin/env in the interpreted script, but
doesn’t help you is you wish, as I did, to interpose something between
lots and lots of #!/usr/bin/ruby scripts and ruby.

Here is another way, write a wee C program that does it for you…

In this case it wraps a ruby in an invocation of ld-linux.so.2 that
loads up the copies of the latest libraries so a precompiled version
will run on an old machine / distro…

// Autogenerated

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

const char LD_LINUX
const char DLL_HELL []=“/opt/ruby/ruby-1.8.6-p36/dll_hell-1.0”;
const char BARE_RUBY []=“/opt/ruby/ruby-1.8.6-p36/bin/.__bare__ruby”;
/* We’ve been called as…
ruby arg_1 arg_2… arg_argc-1

must call..
 ld-linux-so.2 --library-path dll_hell /opt/..../bare_ruby


int main( int argc, char * argv[])
int i;
int new_argc = argc+3;
const char ** new_argv = (const char**)malloc(
sizeof(char*)*new_argc + 1);

for( i = 0; i <= argc; ++i) {
printf( “argv[%3d]=%s\n”,i, argv[i]);
new_argv[0] = “ruby”;
new_argv[1] = “–library-path”;
new_argv[2] = DLL_HELL;
new_argv[3] = BARE_RUBY;

for( i = 1; i <= argc; ++i) {
   new_argv[i+3] = argv[i];

for( i = 0; i <= new_argc; ++i) {
printf( “new_argv[%3d]=%s\n”,i, new_argv[i]);

execv( LD_LINUX, (char * const *)new_argv);

perror( "Should haved execv'ed!");
return 1;


John C. Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : [email protected]
New Zealand

Guess what. JRuby of all things runs into this problem[1], and they
refuse bundle a fix.

Perhaps someone would also like to report this issue to the Linux-Kernel
Mailing List, although it could be years before a fix sufficiently
widespread in the wild for us to stop having to work around it.


[1] http://jira.codehaus.org/browse/JRUBY-1134