# Regression; see below.
reopen 453345
thanks

On Wed, Nov 28, 2007 at 05:31:16PM -0500, Adam Katz wrote:
> Two bits of extraneous code to remove:
> 
> lines 30-33:
>   30 case $PATH in
>   31  *::) : "not *DIR:" ;;
>   32   *:) PATH="$PATH:" ;;
>   33 esac
> 
> Unless this is for some weird nonstandard bourne implementation, the
> argument "not *DIR:" to the colon (:) builtin on line 31 is ignored,

For the record, ": foo" is a not entirely uncommon alternative way to
write comments in Bourne shell; it's also the only way to squeeze a
comment and a trailing ";;" onto a single line.

> lines 47-49:
>   47     if [ -z "$ELEMENT" ]; then
>   48      ELEMENT=.
>   49     fi
> 
> I've never heard of somebody's path including an empty string; this only
> triggers on a path like PATH="/usr/local/bin:'':/usr/bin."  I think
> this is another misunderstanding of Bourne shell tokenization.  The only
> other application I can see for this would be if Bourne interpreted a
> PATH="/usr/local/bin::/usr/bin" as having the tokens '/usr/local/bin'
> and '' and '/usr/bin' (which it does not), in which case there would be
> an empty token,

I think real-life tests generally trump everything else. :-) In Debian's
default shell, bash:

  $ PATH=/usr/local/bin::/usr/bin
  $ IFS=:
  $ for ELEMENT in $PATH; do echo "'$ELEMENT'"; done
  '/usr/local/bin'
  ''
  '/usr/bin'

> but why should that be interpreted as the current directory?

As Clint notes, empty strings do represent the current working
directory. Chapter and verse can be found in
http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html:

  This variable shall represent the sequence of path prefixes that
  certain functions and utilities apply in searching for an executable
  file known only by a filename. The prefixes shall be separated by a
  colon (':'). When a non-zero-length prefix is applied to this
  filename, a slash shall be inserted between the prefix and the
  filename. A zero-length prefix is a legacy feature that indicates the
  current working directory. It appears as two adjacent colons ("::"),
  as an initial colon preceding the rest of the list, or as a trailing
  colon following the rest of the list. A strictly conforming
  application shall use an actual pathname (such as .) to represent the
  current working directory in PATH. The list shall be searched from
  beginning to end, applying the filename to each prefix, until an
  executable file with the specified name and appropriate execution
  permissions is found. If the pathname being sought contains a slash,
  the search through the path prefixes shall not be performed. If the
  pathname begins with a slash, the specified path is resolved (see
  Pathname Resolution). If PATH is unset or is set to null, the path
  search is implementation-defined.

> In the event there IS an empty string in handed to the loop on line 46,
> nothing will happen unless the argument ("$PROGRAM") happens to exist as
> a file in / with executable permissions (assuming you remove lines
> 47-49, otherwise it searches the current directory).

I believe that Clint is incorrect that this was the intent; it certainly
wasn't my intent, as that does not correspond to the shell's command
search semantics. It's just an unremarkable accident of the obvious
implementation. ELEMENT is not supposed to be empty in that case branch.

In your later mail, you wrote:
> Line 31 is still messy and counter-intuitive.  How about this instead:
>     case $PATH in
>       *[^:]:) PATH="$PATH:" ;;
>     esac

That isn't valid POSIX shell, per
http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_13:

  The description of basic regular expression bracket expressions in the
  Base Definitions volume of IEEE Std 1003.1-2001, Section 9.3.5, RE
  Bracket Expression shall also apply to the pattern bracket expression,
  except that the exclamation mark character ('!') shall replace the
  circumflex character ('^') in its role in a "non-matching list" in the
  regular expression notation. A bracket expression starting with an
  unquoted circumflex character produces unspecified results.

So you need "*[!:]:" there.

This mistake results in a regression. Using bash (it's possibly worth
noting that dash doesn't implement a trailing colon in PATH correctly):

  $ touch foo
  $ chmod +x foo
  $ type foo
  -bash: type: foo: not found
  $ which foo
  $ PATH=/usr/bin:/bin: type foo
  foo is ./foo
  $ PATH=/usr/bin:/bin: which foo
  $

Please fix this by changing the pattern to "*[!:]:", or back to the
perfectly good and arguably clearer (if longer) code that was there
before.

Cheers,

-- 
Colin Watson                                       [EMAIL PROTECTED]



-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to