From: John Carter Date: 2007-06-28T11:57:29+09:00 Subject: Hash banging #! - Distributing precompiled sharable linux binaries 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..) http://tinyurl.com/287pez 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 #include #include const char LD_LINUX []="/opt/ruby/ruby-1.8.6-p36/dll_hell-1.0/ld-linux.so.2"; 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); /* printf("argc=%d\n",argc); 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]; } /* printf("\nnew_argc=%d\n",new_argc); 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 Carter Phone : (64)(3) 358 6639 Tait Electronics Fax : (64)(3) 359 4632 PO Box 1645 Christchurch Email : john.carter@tait.co.nz New Zealand