1

Sorry if the question statement wasn't very clear.

I'd like to have a bash script that I can edit to change the behavior of a bunch of other scripts.

For instance--I have some groovy scripts. they can be run either with the groovy interpreter "groovy" or with a special runner called "groovyclient". I might want to change which one runs it (Or do something completely different like compile them into Java class files and run them with Java)

So if I have an indirect script: /home/me/groovy/groovyrun, that is a shell script, it might look like this:

/usr/bin/groovy %*

or like this:

/home/me/groovy/groovyclient $*

I tried a #! line on the original scripts that looks like this:

#!/home/me/groovy/groovyrun

and quickly realized that bash wasn't being invoked so it had no idea what to do with groovyrun

I then tried:

#!/bin/bash /home/me/groovy/groovyrun

But now I think that the $*

That should run it but I believe it has issues with getting to the original argument list (The $* in the called script is probably wrong).

Now I'm fairly lost as far as how to do this and I figure it's probably a common pattern and I'm just not familiar enough with Linux to know it (or even know how to find it), so I ask.

I could easily solve it if I forgo the #! altogether and just pass the groovy script to a shell script directly, but what fun is that?

Bill K
  • 294
  • 2
  • 10

2 Answers2

2

If I understand correctly, you want to create a level of indirection, where the program that you specify through a shebang in a script is itself a script with a shebang. Linux accepts nested shebangs, but other Unix variants don't. So you can put

#!/home/me/groovy/groovyrun

at the top of your Groovy scripts and

#!/bin/sh

at the top of /home/me/groovy/groovyrun.

To execute groovyclient or groovy from the wrapper script, use something like

#!/bin/sh
if …; then
  exec groovyclient "$@"
else
  exec groovy "$@"
fi

"$@" stands for the list of parameters passed to the script, copied exactly as they are (correctly preserving spaces and so on in arguments). Don't use $*, which concatenates the arguments with spaces in between (so that groovyrun 'foo bar' would degenerate into groovyrun 'foo' 'bar'), and never leave a variable expansion unquoted. Regarding exec, see reason for exec in wrapper scripts

0

It should work if you specify the shebang in your groovyrun script.

As a quick experiment, create shell1 containing

#!/bin/sh
echo shell1: "$@"
sh "$@"

and shell2 containing

#!/.../shell1
echo shell2: "$@"

(with the correct path to shell1); running shell2 Hello then produces

shell1: ./shell2 Hello
shell2: Hello

As you can see, the parameters passed to each script look correct in both cases.

Stephen Kitt
  • 434,908
  • Sorry, I don't know how I missed that--too simple? – Bill K Apr 27 '16 at 17:55
  • As a follow up, is there any way to make the path to the second script relative to the directory of the first script? #!../groovyrun in the first script seems to be relative to the directory from which you launch the first script. – Bill K Apr 27 '16 at 18:00
  • Not that I'm aware of... – Stephen Kitt Apr 27 '16 at 18:20