10

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).

Tom Rees
  • 681
  • 4
  • 17

4 Answers4

10

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.

Martin
  • 37,119
  • 15
  • 73
  • 82
6

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.

Matthew Slattery
  • 45,290
  • 8
  • 103
  • 119
4

Read the execve man page for your system. It dictates how scripts are launched, and it should specify that the interpreter in a hash-bang line is a binary executable.

glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • Thanks for the advice. Both `man execve` and `man 3 exec` mention nothing specific on OS X 10.6 about the interpreter needing to be binary, but nevertheless this appears to be the issue at heart. There are surprisingly few Google results for similar problems, though! – Tom Rees Jul 09 '11 at 22:19
0

I asked a similar question in comp.unix.shell that raised some pertinent information.

There was a second branch of the same thread that carried the idea further.

The most general unix solution is to have the shebang point to a binary executable. But that executable program could be as simple as a single call to execl(). Both threads lead to example C source for a program called gscmd, which is little more than a wrapper to execv("gs",...).

luser droog
  • 18,988
  • 3
  • 53
  • 105