Reputation: 361
Consider a simple script program.sh
:
$ cat program.sh
echo program: I have "$#" arguments, they are "$@"
$ ./program.sh 1 2 3
program: I have 3 arguments, they are 1 2 3
$ ./program.sh '1 1' 2 3
program: I have 3 arguments. they are 1 1 2 3
Now I want a wrapper script wrapper.sh
that invokes program.sh
in the same way it was invoked:
$ cat wrapper.sh
echo wrapper: I have "$#" arguments, they are "$@"
./program.sh "$@"
$ ./wrapper.sh 1 2 3
wrapper: I have 3 arguments, they are 1 2 3
program: I have 3 arguments, they are 1 2 3
$ ./wrapper.sh '1 1' 2 3
wrapper: I have 3 arguments. they are 1 1 2 3
program: I have 3 arguments. they are 1 1 2 3
This works perfectly, but I want to use the shift
builtin within wrapper.sh
, which creates a problem because then I cannot use "$@"
anymore in the invocation to program.sh
:
$ cat wrapper.sh
echo wrapper: I have "$#" arguments, they are "$@"
shift
./program.sh "$@"
$ ./wrapper.sh 1 2 3
wrapper: I have 3 arguments, they are 1 2 3
program: I have 2 arguments, they are 2 3
$ ./wrapper.sh '1 1' 2 3
wrapper: I have 3 arguments. they are 1 1 2 3
program: I have 2 arguments. they are 2 3
I have tried initially setting the value of $@
to a temporary variable, but nothing I tried seems to work for wrapper.sh
to invoke program.sh
exactly the way it was originally invoked. What is the proper way to handle this?
Upvotes: 2
Views: 36
Reputation: 113864
It is easy to save $@
. Just save it as an array:
$ cat wrapper.sh
echo wrapper: I have "$#" arguments, they are "$@"
save=("$@")
shift
./program.sh "${save[@]}"
This produces the output:
$ wrapper.sh '1 1' 2 3
wrapper: I have 3 arguments, they are 1 1 2 3
program: I have 3 arguments, they are 1 1 2 3
The key here is that save
is a bash array. Trying to store $@
as a shell string does not work. Saving it as an array does work.
Upvotes: 4