Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 12 Sep 2009 01:14:22 +0200
From:      Jilles Tjoelker <jilles@stack.nl>
To:        Eygene Ryabinkin <rea-fbsd@codelabs.ru>
Cc:        freebsd-hackers@freebsd.org, Doug Barton <dougb@FreeBSD.org>
Subject:   Re: Problem in bin/sh stripping the * character through ${expansion%}
Message-ID:  <20090911231422.GA41683@stack.nl>
In-Reply-To: <ruze2YSbnZSTRbUbUJTTZyWDlyA@PR865FKBRXbdFBYZMkH1tmebpCc>
References:  <4A7B1DB0.1040602@FreeBSD.org> <ruze2YSbnZSTRbUbUJTTZyWDlyA@PR865FKBRXbdFBYZMkH1tmebpCc>

next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, Aug 07, 2009 at 03:26:50AM +0400, Eygene Ryabinkin wrote:
> Thu, Aug 06, 2009 at 11:15:12AM -0700, Doug Barton wrote:
> > I came across this problem during a recent portmaster update. When
> > trying to strip off the * character using variable expansion in bin/sh
> > it doesn't work. Other "special" characters do work if they are
> > properly escaped.

> > The attached mini-script clearly shows the problem:

> > $ sh sh-strip-problem
> > var before stripping: foo\*
> > var after stripping: foo\*

> > var before stripping: foo\$
> > var after stripping: foo\

> According to the sh(1), it is not a problem.  Namely,
>  - \* being unquoted at all will produce a lone '*';
>  - '*' when treated as the smallest pattern, will result in a stripping
>    of a zero-length string -- it is the smallest pattern in the case of
>    '*' that matches anything.

That is indeed an explanation why it works that way, but I think it is
wrong. Generally, the shell command language avoids unnecessary levels
of quoting. In the POSIX spec, "Shell Command Language", note the part
about "${x#*}" (pattern) and ${x#"*"} (literal asterisk). Also compare
with  case $something in \*) echo asterisk;; esac  which matches a
literal asterisk.

Two PRs already exist for aspects of stripping: bin/57554 (double
quotes) and bin/117748 (trying to match pattern matching characters
literally).

> In order to strip the trailing star you should use
> -----
> var=${var%[*]}
> -----
> This gives you the pattern of '[*]' that is properly treated as the
> single star -- it's a weird way to escape the star in the patterns.

This is indeed a good workaround.

-- 
Jilles Tjoelker



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20090911231422.GA41683>