Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a script be used as an interpreter by the #! hashbang line?

I'm trying to write a bash script which will behave as a basic interpreter, but it doesn't seem to work: The custom interpreter doesn't appear to be invoked. What am I doing wrong?

Here's a simple setup illustrating the problem:

/bin/interpreter: [owned by root; executable]

#!/bin/bash

echo "I am an interpreter running " $1

/Users/zeph/script is owned by me, and is executable:

#!/bin/interpreter

Here are some commands for the custom interpreter.

From what I understand about the mechanics of hashbangs, the script should be executable as follows:

$ ./script
I am an interpreter running ./script

But this doesn't work. Instead the following happens:

$ ./script 
./script: line 3: Here: command not found

...It appears that /bin/bash is trying to interpret the contents of ./script. What am I doing wrong?

Note: Although it appears that /bin/interpreter never invoked, I do get an error if it doesn't exist:

$ ./script
-bash: ./script: /bin/interpreter: bad interpreter: No such file or directory

(Second note: If it makes any difference, I'm doing this on MacOS X).

like image 428
Tom Rees Avatar asked Jul 09 '11 19:07

Tom Rees


2 Answers

To make this work you could add the interpreter's interpreter (i.e. bash) to the shebang:

#!/bin/bash /bin/interpreter

Here are some commands for the custom interpreter.

bash will then run your interpreter with the script path in $1 as expected.

like image 197
Martin Avatar answered Oct 07 '22 09:10

Martin


You can't use a script directly as a #! interpreter, but you can run the script indirectly via the env command using:

    #!/usr/bin/env /bin/interpreter

/usr/bin/env is itself a binary, so is a valid interpreter for #!; and /bin/interpreter can be anything you like (a script of any variety, or binary) without having to put knowledge of its own interpreter into the calling script.

like image 39
Matthew Slattery Avatar answered Oct 07 '22 10:10

Matthew Slattery