How to keep quotes in Bash arguments?

Viewed 131557

I have a Bash script where I want to keep quotes in the arguments passed.

Example:

./test.sh this is "some test"

then I want to use those arguments, and re-use them, including quotes and quotes around the whole argument list.

I tried using \"$@\", but that removes the quotes inside the list.

How do I accomplish this?

14 Answers

I needed this for forwarding all arguments to another interpreter. What ended up right for me is:

bash -c "$(printf ' %q' "$@")"

Example (when named as forward.sh):

$ ./forward.sh echo "3 4"
3 4
$ ./forward.sh bash -c "bash -c 'echo 3'"
3

(Of course the actual script I use is more complex, involving in my case nohup and redirections etc., but this is the key part.)

Just use:

"${@}"

For example:

# cat t2.sh
for I in "${@}"
do
   echo "Param: $I"
done
# cat t1.sh
./t2.sh "${@}"

# ./t1.sh "This is a test" "This is another line" a b "and also c"
Param: This is a test
Param: This is another line
Param: a
Param: b
Param: and also c

As Gary S. Weaver shown in his source code tips, the trick is to call bash with parameter '-c' and then quote the next.

e.g.

bash -c "<your program> <parameters>"

or

docker exec -it <my docker> bash -c "$SCRIPT $quoted_args"

If you need to pass all arguments to bash from another programming language (for example, if you'd want to execute bash -c or emit_bash_code | bash), use this:

  • escape all single quote characters you have with '\''.
  • then, surround the result with singular quotes

The argument of abc'def will thus be converted to 'abc'\''def'. The characters '\'' are interpreted as following: the already existing quoting is terminated with the first first quote, then the escaped singular single quote \' comes, then the new quoting starts.

Yes, seems that it is not possible to ever preserve the quotes, but for the issue I was dealing with it wasn't necessary.

I have a bash function that will search down folder recursively and grep for a string, the problem is passing a string that has spaces, such as "find this string". Passing this to the bash script will then take the base argument $n and pass it to grep, this has grep believing these are different arguments. The way I solved this by using the fact that when you quote bash to call the function it groups the items in the quotes into a single argument. I just needed to decorate that argument with quotes and pass it to the grep command.

If you know what argument you are receiving in bash that needs quotes for its next step you can just decorate with with quotes.

Related