bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: BUG about quote removal inside parameter expansion.


From: TobiX
Subject: Re: BUG about quote removal inside parameter expansion.
Date: Thu, 7 Nov 2002 20:28:59 +0100
User-agent: Mutt/1.4i

> Think of your example as being identical to `echo "${hello//r/' '}"'
> with a literal TAB between the single quotes (which it is). The
> single-quoted string is within double quotes. Inside double quotes,
> single quotes are retained. 

It is not identical.
If it were, the following two lines would produce the same output:

   echo "hello '<TAB>' world"
   echo "hello $'\t' world"

where <TAB> is a literal tab character. Instead they produce different
output, because inside double quotes, other quotes aren't removed.
Every single quote remains there, as does the dollar sign, backslash...

In my example things are different. Inside the parameter expansion,
which in turn is inside double quotes, $'\t' gets half-expanded: the 
dollar sign gets removed and the \t becomes a tab character, but the
two single quotes remain there!

With a string as $'\t', either it is not expanded and remains literal
(as in echo "$'\t'") or it is fully expanded and it becomes a single tab
character (as in echo $'\t'). 
The half-expansion which is taking place is not good.



To simplify things, I will explain you the case which made me discover
this bug.

I have a variable which contains some random string. I need to include
that string into an eval, or into the -c parameter of a bash invocation.
(Why I have to do so is beyond the scope of this discussion.)

In order to do so, I need to put the string inside single quotes and
substitute every single quote in the string with '\'' . 
This is simpler than using double quotes and backslashing dollars, etc.

So if the variable definition is:

  var="Dear O'Brian,"
  
then the final invocation should become:

  bash -c "echo 'Dear O'\''Brian,'"

One way to do that (which works) is the following:

  bash -c "echo '$(sed "s/'/'\\\\''/g" <<<"$var")'"

(Please copy & paste to see that it works.)
But it spawns a sed process, which is not good if it's not strictly
necessary. Also, there are too much baclslashes in that! 

The ideal way of doing that using parameter substitution would be:

  bash -c "echo '${var//'/'\''}'"

  bash -c "echo '${var//'/'\\''}'"
  
or something along these lines.

But it doesn't work, because of the bug I described above.
I have not found a single way to substitute every ' with '\'' using
parameter expansion inside double quotes.

Tinker with this construct and you'll realize it's a real bug.


TobiX

PS: Sorry for the dupe mail! I forgot to put the CCs.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]