From owner-freebsd-hackers@FreeBSD.ORG Fri Sep 11 23:14:23 2009 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EF84A106566B; Fri, 11 Sep 2009 23:14:23 +0000 (UTC) (envelope-from jilles@stack.nl) Received: from mx1.stack.nl (relay02.stack.nl [IPv6:2001:610:1108:5010::104]) by mx1.freebsd.org (Postfix) with ESMTP id B7CB48FC0A; Fri, 11 Sep 2009 23:14:23 +0000 (UTC) Received: from snail.stack.nl (snail.stack.nl [IPv6:2001:610:1108:5010::131]) by mx1.stack.nl (Postfix) with ESMTP id CCBB335A829; Sat, 12 Sep 2009 01:14:22 +0200 (CEST) Received: by snail.stack.nl (Postfix, from userid 1677) id B0850228CD; Sat, 12 Sep 2009 01:14:22 +0200 (CEST) Date: Sat, 12 Sep 2009 01:14:22 +0200 From: Jilles Tjoelker To: Eygene Ryabinkin Message-ID: <20090911231422.GA41683@stack.nl> References: <4A7B1DB0.1040602@FreeBSD.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.18 (2008-05-17) Cc: freebsd-hackers@freebsd.org, Doug Barton Subject: Re: Problem in bin/sh stripping the * character through ${expansion%} X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 11 Sep 2009 23:14:24 -0000 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