views:

181

answers:

5

Hi, I'm trying to write a bash script that "wraps" whatever the user wants to invoke (and its parameters) sourcing a fixed file just before actually invoking it.

To clarify: I have a "ConfigureMyEnvironment.bash" script that must be sourced before starting certain executables, so I'd like to have a "LaunchInMyEnvironment.bash" script that you can use as in:

LaunchInMyEnvironment <whatever_executable_i_want_to_wrap> arg0 arg1 arg2

I tried the following LaunchInMyEnvironment.bash:

#!/usr/bin/bash
launchee="$@"
if [ -e ConfigureMyEnvironment.bash ];
     then source ConfigureMyEnvironment.bash;
fi

exec "$launchee"

where I have to use the "launchee" variable to save the $@ var because after executing source, $@ becomes empty.

Anyway, this doesn't work and fails as follows:

myhost $ LaunchInMyEnvironment my_executable -h
myhost $ /home/me/LaunchInMyEnvironment.bash: line 7: /home/bin/my_executable -h: No such file or directory
myhost $ /home/me/LaunchInMyEnvironment.bash: line 7: exec: /home/bin/my_executable -h: cannot execute: No such file or directory

That is, it seems like the "-h" parameter is being seen as part of the executable filename and not as a parameter... But it doesn't really make sense to me. I tried also to use $* instead of $@, but with no better outcoume.

What I'm doing wrong?

Andrea.

+2  A: 

Have you tried to remove double quotes in exec command?

mouviciel
No way, in that case the "-h" doesn't even get passed to my_executable
abigagli
Works fine for me.
Cirno de Bergerac
Sorry, yours is the right answer, actually removing the quotes in the exec command is the right thing to do. I was fooled by a problem in my executable that wasn't handling the "-h" option correctly so I thought it wasn't receiving the "-h" at all...
abigagli
A: 

You might want to try this (untested):

#!/usr/bin/bash
launchee="$1"
shift
if [ -e ConfigureMyEnvironment.bash ];
     then source ConfigureMyEnvironment.bash;
fi

exec "$launchee" $@

The syntax for exec is exec command [arguments], however becuase you've quoted $launchee, this is treated as a single argument - i.e., the command, rather than a command and it's arguments. Another variation may be to simply do: exec $@

Chris J
As I said in my original post, I cannot use directly $@ because it seems it gets cleared out when "sourcing", that's why I use the $launchee, so exec "$launchee" $@ doesn't seem viable to me
abigagli
+2  A: 

Try this:

#!/usr/bin/bash
typeset -a launchee
launchee=("$@")
if [ -e ConfigureMyEnvironment.bash ]; 
  then source ConfigureMyEnvironment.bash; 
fi 
exec "${launchee[@]}"

That will use arrays for storing arguments, so it will handle even calls like "space delimited string" and "string with ; inside"

Upd: simple example

test_array() { abc=("$@"); for x in "${abc[@]}"; do echo ">>$x<<"; done; } test_array "abc def" ghi

should give

>>abc def<<
>>ghi<<
ony
I tried that, but I get exactly the same failure as in my original post: myhost $ LaunchInMyEnvironment my_executable -h myhost $ /home/me/LaunchInMyEnvironment.bash: line 7: /home/bin/my_executable -h: No such file or directory myhost $ /home/me/LaunchInMyEnvironment.bash: line 7: exec: /home/bin/my_executable -h: cannot execute: No such file or directory
abigagli
That means that you are using some strange bash. I've tried that scenario at bash version 2.05b.0(1)-release. Try to source file which justs prints something to check that feature. And make sure that you've put `[@]` (square brakets and "at" symbol) where you are doing exec. As well echeck that you've put `("$@")` (with curly brakets) in variable. First line with `typeset` in my case isn't required, but...
ony
A: 

Just execute it normally without exec

#!/usr/bin/bash
launchee="$@"
if [ -e ConfigureMyEnvironment.bash ];
     then source ConfigureMyEnvironment.bash;
fi

$launchee
ghostdog74
exec - means replace current content of process with new ($launchee). Your variant will spawn another process and will wait for finish (two process $launchee and bash waiting for it). And omiting quotes will cause normal execution, probably, but if you'll specify parameter which contains space (i.e. filename with space) it will be interpreted as several parameters.
ony
As ony pointed out, the difference is that this will simply spawn a new process (in contrast with my version that uses exec), but the problems are the same: i.e. without quotes it works but doesn't get any parameter, with double quotes I get the same failure I showed in the original post
abigagli
A: 

Try dividing your list of argumets:

ALL_ARG="${@}"
Executable="${1}"
Rest_of_Args=${ALL_ARG##$Executable}

And try then:

$Executable $Rest_of_Args
(or exec $Executable $Rest_of_Args)

Debugger