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?

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.

  • 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
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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.