bug-bash
[Top][All Lists]
Advanced

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

Unexpected behavior observed when using ${parameter[@]/pattern/string} c


From: Stahlman Family
Subject: Unexpected behavior observed when using ${parameter[@]/pattern/string} construct
Date: Sun, 31 Dec 2006 16:18:43 -0600

While writing a script that uses the ${parameter[@]/pattern/string} construct,
I encountered behaviors I cannot reconcile with the text in the bash manual.
I've pasted snippets from a command line session below (with comments
interspersed) that shows the apparent issues.

Perhaps some of the confusion would be cleared up by an explicit description
of the handling of quoted strings within the <string> portion of the parameter
expansion construct; specifically, will a "nested" string be parsed as though
it were at the top level? Case 2 appears to indicate yes, while case 3
indicates no...

Case 1 is included because it shows an (apparent) issue with respect to word
splitting; specifically, that it is performed on the results of the expansion,
even though IFS is set to null.

Note that the goal in the examples below is to prepend "-iname '" (portion
within double quotes only) to each of the 2 elements in the original array,
without changing the number of words. i.e., the new array should contain the
following 2 words:
-iname 'abc
-iname 'def

$ a=(abc def)

# Prevent word splitting
$ IFS=

# ***
# *** Case 1 *** (Doesn't work because of undesired word splitting)
# ***
$ a2=(${a[@]/#/"-iname '"})

$ echo "${#a2[@]}"
4

$ for el in "${a2[@]}"; do echo "$el"; done
-iname
'abc
-iname
'def

# Conclusion: The resulting list (after parameter pattern substitution is
# applied to each element in the original array) undergoes word splitting,
# even though IFS is set to null! Why?
# Note that word splitting does not occur when the ${parameter/pattern/string}
# form is used.
# Example:

$ s='abc'

$ set - ${s/b/1 2 3}

$ echo $#
1

$ echo "$1"
a1 2 3c


# ***
# *** Case 2 *** (Doesn't work because of unterminated single quote)
# ***
$ a2=("${a[@]/#/-iname '}")
'


Conclusion: This attempt needed to be Ctrl-C'd because bash first considered
that the single quote was unterminated, then apparently, considered the curly
brace to be unterminated; i.e., the single quote is not considered to be
"within" the double quotes that surround the entire parameter. In and of
itself, this would not seem strange to me, but it appears to be inconsistent
with the following case, in which the double quotes in <string> are aware that
they are themselves within double quotes.

# ***
# *** Case 3 *** (Doesn't work because double quotes within <string> are kept)
# ***
$ a2=("${a[@]/#/"-iname '"}")

$ echo "${#a2[@]}"
2

$ for el in "${a2[@]}"; do
echo "$el"
done
"-iname '"abc
"-iname '"def

Conclusion: Unlike case 2, the quote characters within <string> (double quotes
in this case, single quotes in case 2) are *not* considered by bash to be
string delimiters, but are simply included literally in the expanded string.
Again, there is nothing inherently wrong with this, but if nested strings are
not possible, why was the single quote in case 2 considered to be
unterminated?

Thanks,
Brett S.





reply via email to

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