How to pass foo='bar baz' to command from cli arguments

Viewed 153

Here's a stripped down example of what I'm trying to do.

#!/usr/bin/env bash
set -x

echo "$@"

calling it with

bash script -vv --foo='bar baz'

yields

+ echo -vv 'foo=bar baz'
-vv foo=bar baz

Note that the + line (i.e the debug line) is putting single quotes around the entire foo=bar baz. I need it to pass

foo='bar baz'

not

'foo=bar baz'

I have tried several iterations to no avail. Is there a way to get it to pass the former?

1 Answers

set -x doesn't change quotes in your arguments: foo='bar baz' and 'foo=bar baz' are two different ways of writing the same string. Any program you pass these arguments to will be given the C string "foo=bar baz" (those double quotes being C syntax, not literal content) in the relevant position in its argv array. Note that there are no 's anywhere in that string.

This is true because quoting is evaluated on a per-character basis by all POSIX shells (a class in which bash is a member); and syntactic quotes are removed prior to actual execution, thus leaving only literal data.

In foo='bar baz', you have foo= in an unquoted context and bar baz in a single-quoted context being concatenated together into a single string.

In 'foo=bar baz', the shell's debug output shows you a single string containing the results of that operation.

These strings are identical; they just happen to be described using different syntax. Consequently, it is impossible to have any bug caused by the distinction between these two representations, because the value they cause to be passed to the invoked program is exactly identical; the called program cannot tell which one was used, and thus cannot change its behavior based on the distinction. Thus, no bug based on this distinction is possible.

Related