├── Makefile ├── README.md └── shebang.c /Makefile: -------------------------------------------------------------------------------- 1 | 2 | shebang: shebang.c 3 | $(CC) -o $@ $< 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | Sometimes `#!/usr/bin/env` isn't sufficient. What if you wanted this: 3 | 4 | #!/usr/bin/env jruby --1.9 5 | puts RUBY_VERSION 6 | 7 | You'd get: 8 | 9 | /usr/bin/env: jruby --1.9: No such file or directory 10 | 11 | That sucks. Use shebang instead. 12 | 13 | #!/usr/bin/shebang jruby --1.9 14 | puts "Hello from #{RUBY_VERSION}" 15 | 16 | Working output: 17 | 18 | Hello from 1.9.2 19 | 20 | -------------------------------------------------------------------------------- /shebang.c: -------------------------------------------------------------------------------- 1 | /* shebang helper. 2 | * 3 | * This tool lets you sanely execute things from the shebang line 4 | * at the top of a script. 5 | * 6 | * Problem solved by this program: 7 | * This line won't work like you might expect: 8 | * #!/usr/bin/env scriptname arg1 arg2 ... 9 | * 10 | * When executed, this will run this: 11 | * /usr/bin/env "scriptname arg1 arg2 ..." 12 | * 13 | * The above is likely not what you wanted, you wanted: 14 | * /usr/bin/env "scriptname" "arg1" "arg2" ... 15 | * 16 | * If you use this program, it'll work as expected: 17 | * #!/usr/bin/shebang scriptname arg1 arg2 18 | */ 19 | 20 | #include /* for printf */ 21 | #include /* for execvp */ 22 | #include /* for calloc */ 23 | #include /* for memcpy */ 24 | 25 | int main(int argc, char **argv) { 26 | char *cmd; 27 | char **newargv; 28 | 29 | newargv = calloc(argc + 3, sizeof(char *)); 30 | newargv[0] = "/bin/sh"; 31 | newargv[1] = "-c"; 32 | asprintf(&(newargv[2]), "%s \"$@\"", argv[1]); 33 | memcpy(newargv + 3, argv + 1, (argc - 1) * sizeof(char *)); 34 | 35 | //for (int i = 0; i < argc + 2; i ++) { 36 | //printf("newargv[%d]: %s\n", i, newargv[i]); 37 | //} 38 | 39 | execvp("/bin/sh", newargv); 40 | return -1; 41 | } 42 | --------------------------------------------------------------------------------