なかだです。

rubyもperlにならって、shebangにrubyという文字列がない場合、ruby script
じゃないとみなしてそこに指定されているプログラムをキックするようになっ
ていますが、しかし、これって本当に今でも必要な機能なんでしょうか。これ
が必要なのは、shebangが実装されていなくて、かつENOEXECなら問答無用で
rubyに渡すという、ちょっとありそうにないシステムだけのような気がします。

そこで、「'ruby'のないshebangは引数なしの-xとみなす」という案はどうでしょ
うか。そうすれば、こういうスクリプトを直接渡されてもそのまま実行できる
ようになります。

  #!/bin/sh
  exec ruby -x ${1+"$@"}
  #!ruby

今これが`ruby foo.rb'と-xなしで実行された場合は、一度 /bin/sh を呼び出
してそこからまたrubyを呼び出す、という二重の手間になっています。


Index: ruby.c =================================================================== RCS file: /cvs/ruby/src/ruby/ruby.c,v retrieving revision 1.103 diff -U2 -p -u -r1.103 ruby.c --- ruby.c 16 Jun 2005 06:43:00 -0000 1.103 +++ ruby.c 24 Jun 2005 08:26:03 -0000 @@ -389,5 +389,5 @@ require_libraries() ruby_current_node = 0; - rb_protect((VALUE (*)(VALUE))rb_require, (VALUE)list->name, &state); + rb_protect((VALUE (*)_((VALUE)))rb_require, (VALUE)list->name, &state); if (state) rb_jump_tag(state); tmp = list->next; @@ -904,4 +904,5 @@ load_file(fname, script) if (xflag) { + search_shebang: forbid_setid("-x"); xflag = Qfalse; @@ -927,33 +928,6 @@ load_file(fname, script) if ((p = strstr(RSTRING(line)->ptr, "ruby")) == 0) { - /* not ruby script, kick the program */ - char **argv; - char *path; - char *pend = RSTRING(line)->ptr + RSTRING(line)->len; - - p = RSTRING(line)->ptr; /* skip `#!' */ - if (pend[-1] == '\n') pend--; /* chomp line */ - if (pend[-1] == '\r') pend--; - *pend = '\0'; - while (p < pend && ISSPACE(*p)) - p++; - path = p; /* interpreter path */ - while (p < pend && !ISSPACE(*p)) - p++; - *p++ = '\0'; - if (p < pend) { - argv = ALLOCA_N(char*, origargc+3); - argv[1] = p; - MEMCPY(argv+2, origargv+1, char*, origargc); - } - else { - argv = origargv; - } - argv[0] = path; - execv(path, argv); - - ruby_sourcefile = rb_source_filename(fname); - ruby_sourceline = 1; - rb_fatal("Can't exec %s", path); + /* not ruby script, assume -x flag */ + goto search_shebang; }
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦