How to echo "$@" so the result is valid bash and maintains proper quoting?

Viewed 217

What do I put in wrapper.sh, if I want this:

wrapper.sh "hello world" arg2 '' "this ' thing"

to output:

Now please run:
other-command "hello world" arg2 '' "this ' thing"

I realize and am fine with that the original quotation is lost and the output perhaps will be quoted differently, as long as other-command gets the correct parameters when the command is cut'n'pasted to the shell.

I'm aware of "$@" which works well for calling other programs, but not for echoing valid bash to STDOUT as far as I can tell.

This looks pretty nice but requires Perl and String::ShellQuote (which I'd like to avoid):

$ perl -MString::ShellQuote -E 'say shell_quote @ARGV' other-command "hello world" arg2 '' "this ' thing"
other-command 'hello world' arg2 '' 'this '\'' thing'

This doesn't work - notice how the zero-length arg is missing:

$ perl -E 'say join(" ", map { quotemeta $_ } @ARGV)' other-command "hello world" arg2 '' "this ' thing"
other\-command hello\ world arg2  this\ \'\ thing

again, I'd like to avoid using Perl or Python...

2 Answers

You can use the @Q parameter transformation.

$ set -- "hello world" arg2 '' 'this " thing'
$ echo other-command "${@@Q}"
other-command 'hello world' 'arg2' '' 'this " thing'

If you intend the output to be re-evalulated, then you need to printf "%q". You script could look like:

echo Now please run:
echo "other-command$(printf " %q" "$@")"
Related