zerkms
zerkms

Reputation: 254926

How to escape a space returned from nested bash command

The title is slightly confusing since the problem itself is confusing.

Prerequisites:

I use this script script.sh as a playground for the parameters passed:

#!/bin/bash

echo $1
echo $2
echo $3

Problem:

I expect this call

./script.sh $( echo "foo \"bar baz\"" )

to behave exactly as

./script.sh foo "bar baz"

Correspondingly, I expect to get

foo
bar baz

as the output result but it returns

foo
"bar
baz"

Obviously, I need to escape something. I suspect it's a space, but I'm not sure.

The question: how the nested echo call should look like so that the outer call received 2 arguments

PS: this is a simplification of a more complicated script, but the main problem of the original call is kept.

Upvotes: 2

Views: 539

Answers (1)

Gordon Davisson
Gordon Davisson

Reputation: 125798

You can't do this. Whatever $(somecommand) will be treated as data, not interpreted as shell syntax, so any quotes and escapes in it will simply be treated as regular characters. This is what you're seeing -- the double-quotes that echo prints are being treated as parts of the arguments to ./script.sh, rather than as delimiters around arguments.

Another way to think of this is in terms of the process that the shell goes through as it parses a command line. Here's a highly simplified summary:

  1. Parse the command line, including quotes and escapes. Note that the quotes and escapes get removed in this process.
  2. Expand things like variables ($var) and command substitutions ($( ) and backquoted commands).
  3. Perform word splitting and wildcard expansion on the results of those expansions (unless they were in double-quotes from step 1).

Note that by the time the results of any variable expansion or command substitution is part of the command line, quote and escape parsing has already been done; the shell simply doesn't apply that processing to the results of those expansions.

Now, depending on what you're actually trying to do, there might be another way to accomplish it. For example, there are ways to use read or xargs to split a string while respecting quotes/escapes within it. There's also eval, but avoid that if at all possible -- it has a well-deserved reputation as a bug magnet.

Upvotes: 2

Related Questions