Bash string substitution bug (?)

2008-01-11 Thread Dmitry V Golovashkin

Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: x86_64-redhat-linux-gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' 
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-redhat-linux-gnu' 
-DCONF_VENDOR='redhat' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' 
-DSHELL -DHAVE_CONFIG_H  -I.  -I. -I./include -I./lib   -O2 -g -pipe -m64
uname output: Linux acl201.unx.sas.com 2.6.9-42.ELsmp #1 SMP Wed Jul 12 
23:32:02 EDT 2006 x86_64 x86_64 x86_64 GNU/Linux

Machine Type: x86_64-redhat-linux-gnu

Bash Version: 3.0
Patch Level: 15
Release Status: release

Description:
   unexpected bad substitution:
   enter the following simple list:

prompt:  CLUSTER='1 2'; echo ${CLUSTER/${HOSTNAME%%.*}}
output:   1 2

   the idea of the above line is to remove short HOSTNAME (without the 
trailing domain)
 from the CLUSTER - works fine (CLUSTER was assigned a dummy 
value - irrelevant)
   however the same operation with slash results in a bad substitution 
error.

   the substitution appears to be a valid one.

  prompt: CLUSTER='1 2'; echo ${CLUSTER/${HOSTNAME/.*}}
  output: -bash: ${HOSTNAME: bad substitution
  


Repeat-By:

Fix:





Re: Bash string substitution bug (?)

2008-01-11 Thread Bernd Eggink

Dmitry V Golovashkin schrieb:


Description:
   unexpected bad substitution:
   enter the following simple list:

prompt:  CLUSTER='1 2'; echo ${CLUSTER/${HOSTNAME%%.*}}
output:   1 2

   the idea of the above line is to remove short HOSTNAME (without the 
trailing domain)
 from the CLUSTER - works fine (CLUSTER was assigned a dummy 
value - irrelevant)
   however the same operation with slash results in a bad substitution 
error.

   the substitution appears to be a valid one.

  prompt: CLUSTER='1 2'; echo ${CLUSTER/${HOSTNAME/.*}}
  output: -bash: ${HOSTNAME: bad substitution


Apparently bash interprets this as  ${parameter/pattern/string}
where pattern = ${HOSTNAME. Looks like a bug; it works in ksh.

As a workaround, you could use:

H=${HOSTNAME/.*}
echo ${CLUSTER/$H}

Regards,
Bernd

--
Bernd Eggink
[EMAIL PROTECTED]
http://sudrala.de




Re: Bash string substitution bug (?)

2008-01-11 Thread Chet Ramey

Bernd Eggink wrote:


  prompt: CLUSTER='1 2'; echo ${CLUSTER/${HOSTNAME/.*}}
  output: -bash: ${HOSTNAME: bad substitution


Apparently bash interprets this as  ${parameter/pattern/string}
where pattern = ${HOSTNAME. Looks like a bug; it works in ksh.


That is, in fact, what is happening.  I'm not sure you can call it
a bug, though -- bash is behaving exactly as documented.  The fact
that Korn chose to implement it a certain way in ksh and not document
the implementation doesn't help compatibility, but the public
specification of the feature is the same between both shells.

Chet

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
   Live Strong.  No day but today.
Chet Ramey, ITS, CWRU[EMAIL PROTECTED]http://cnswww.cns.cwru.edu/~chet/




Re: Bash string substitution bug (?)

2008-01-11 Thread Bernd Eggink

Chet Ramey schrieb:

Bernd Eggink wrote:


  prompt: CLUSTER='1 2'; echo ${CLUSTER/${HOSTNAME/.*}}
  output: -bash: ${HOSTNAME: bad substitution


Apparently bash interprets this as  ${parameter/pattern/string}
where pattern = ${HOSTNAME. Looks like a bug; it works in ksh.


That is, in fact, what is happening.  I'm not sure you can call it
a bug, though -- bash is behaving exactly as documented.


Where exactly is that documented? The only statement I can find in the 
documentation referring to this problem is:


"When braces are used, the matching ending brace is the first `}' not 
escaped by a backslash or within a quoted string,  and  not
within an embedded arithmetic expansion, command substitution, or 
parameter expansion."


I may be wrong, but to me this means that the first opening brace 
matches the last closing one, and that the token ${HOSTNAME/.*} is a 
correct parameter expansion.


Bernd

--
Bernd Eggink
[EMAIL PROTECTED]
http://sudrala.de




Re: Bash string substitution bug (?)

2008-01-11 Thread Chet Ramey

Bernd Eggink wrote:

Chet Ramey schrieb:

Bernd Eggink wrote:


  prompt: CLUSTER='1 2'; echo ${CLUSTER/${HOSTNAME/.*}}
  output: -bash: ${HOSTNAME: bad substitution


Apparently bash interprets this as  ${parameter/pattern/string}
where pattern = ${HOSTNAME. Looks like a bug; it works in ksh.


That is, in fact, what is happening.  I'm not sure you can call it
a bug, though -- bash is behaving exactly as documented.


Where exactly is that documented? The only statement I can find in the 
documentation referring to this problem is:


The pattern and `string' in ${parameter/pattern/string} aren't defined
to obey the rules of parameter brace expansions.  The search for the
matching `/' is just a string search.

It would be less confusing if the code that searched for the closing
slash were smarter about skipping over embedded brace expansions, though.
It shouldn't be too hard to change that for the next release.

Chet
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
   Live Strong.  No day but today.
Chet Ramey, ITS, CWRU[EMAIL PROTECTED]http://cnswww.cns.cwru.edu/~chet/




Re: Comparison failure

2008-01-11 Thread Chet Ramey

Dave Rutherford wrote:


I know test's quirks.  Does [[ have quirks?  Are they the same?
Is there room in my grey matter to hold both sets of quirks
and keep them straight?


[[ was designed to remedy test's quirks, so it shouldn't really have
any of its own.  In addition to the functionality provided by the
new operators and extended matching there is:

1.  a more regular grammar, including operator short-circuiting and
better parsing ( [[ -f ]] is an error, for instance; and
[[ -f = ]] doesn't throw an error like the system v test)

2.  no word splitting or pathname expansion performed on arguments --
each argument ends up as a single word

3.  parameter and variable expansion is more convenient, since [[ is
not a command invoked after all expansions a performed.  The intent
is to eliminate the need for excessive quoting:  [[ -n $n ]] and
[ -n $n ] behave differently when `n' is unset or null; [ requires
quoting arguments but even that isn't sufficient in all cases

Since [[ was new and had a single specification, the intent was that
users would not have to deal with the portability problems inherent in
the different historical test implementations (Dave Korn implemented it
in the pre-Posix era, remember).

Posix tried to fix some of test's shortcomings within the constraint
of leaving it a builtin command, mostly by defining the behavior based
on the number of arguments and specifying some operator precedence,
but [[ still has its advantages.  That means that test is more portable
than [[, of course.

Chet

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
   Live Strong.  No day but today.
Chet Ramey, ITS, CWRU[EMAIL PROTECTED]http://cnswww.cns.cwru.edu/~chet/




Re: Bash string substitution bug (?)

2008-01-11 Thread Dmitry V Golovashkin

either
   VALUE=host1.blah.com
   echo ${VALUE//.*}
or
echo ${VALUE/.*}

is accepted by Bash and works exactly as I would expect it - meaning
it correctly produces "host1" - removes the dot (dot is just a character 
- we are not

in the regular expression world) - so the dot and the trailing domain
name are removed. Bash works fine in both above cases, produces expected 
output;

${VALUE/.*} naturally seems to be a valid parameter expansion.

Please try once more:

CLUSTER='host5 host1 host2';
VALUE=host1.blah.com;
echo ${CLUSTER//${VALUE%%.*}}

again works perfectly: Outputs  'host5 host2' just as i would expect it.
${VALUE%%.*} similarly to ${VALUE//.*} just removes the first
dot-and-the-trailing domain name.
it is logical to assume and the manual supports it that
echo ${CLUSTER//${VALUE%%.*}}
is a valid parameter expansion. Again - it works fine.

Therefore it seems to be inconsistent that the nearly identical
expansion
  echo ${CLUSTER//${VALUE/.*}}

is throwing "bad substitution" exception.

To sum things up, consider these two lines (without the "dot"):

echo ${CLUSTER//${VALUE%%*}}
echo ${CLUSTER//${VALUE//*}}

the first works great. the second results in "bash: ${VALUE: bad 
substitution"


It really does seem remarkably inconsistent: We have parameter expansion
within parameter expansion, one works fine, nearly identical another one
throws an exception... Seems a bug to me.

Thanks!
dm

PS echo ${CLUSTER//${VALUE##.*}}
also works superb - in this case ${VALUE##.*} is empty - because VALUE 
does not start with a dot.
Bash works great here too.  It is only when "//" is used - Bash 
misbehaves...




Bernd Eggink wrote:

Chet Ramey schrieb:
  

Bernd Eggink wrote:


  prompt: CLUSTER='1 2'; echo ${CLUSTER/${HOSTNAME/.*}}
  output: -bash: ${HOSTNAME: bad substitution


Apparently bash interprets this as  ${parameter/pattern/string}
where pattern = ${HOSTNAME. Looks like a bug; it works in ksh.
  

That is, in fact, what is happening.  I'm not sure you can call it
a bug, though -- bash is behaving exactly as documented.



Where exactly is that documented? The only statement I can find in the
documentation referring to this problem is:

"When braces are used, the matching ending brace is the first `}' not
escaped by a backslash or within a quoted string,  and  not
within an embedded arithmetic expansion, command substitution, or
parameter expansion."

I may be wrong, but to me this means that the first opening brace
matches the last closing one, and that the token ${HOSTNAME/.*} is a
correct parameter expansion.

Bernd

--
Bernd Eggink
[EMAIL PROTECTED]
http://sudrala.de