Skip to content

docs(parameter expansion): prefix/suffix removal uses pattern-lists #918

@mgkurtz

Description

@mgkurtz

Abstract

After updating a shell script, it ceased to work for people with ksh as system shell (pdfjam/pdfjam#99). The incompatibility was caused by ksh interpreting | as OR operator in a construct such as ${parameter%word|separated|by|bars}, while other shells interpret | literally. This behaviour persists even after set -o posix.

Example

Here is some shell session that removes the smallest match for |* from x|y resulting in x, which works for at least bash, dash and zsh:

$ a="x|y"
$ echo ${a%|*}'
x

In ksh, the |* matches the empty string and removes nothing:

$ a="x|y"
$ echo ${a%|*}'
x|y
$ set -o posix
$ a="x|y"
$ echo ${a%|*}'
x|y

Resolving as script author

One can escape the special meaning of | using a backslash, which works in all tested shells including ksh:

$ a="x|y"
$ echo ${a%\|*}'
x

The POSIX requirements

The parameter expansion section of the POSIX Shell Command Language requires

The following four varieties of parameter expansion provide for character substring processing. In each case, pattern matching notation (see 2.14 Pattern Matching Notation), rather than regular expression notation, shall be used to evaluate the patterns. […]

${parameter%[word]}
Remove Smallest Suffix Pattern. The word shall be expanded to produce a pattern. The parameter expansion shall then result in parameter, with the smallest portion of the suffix matched by the pattern deleted. […]

Wish

Either

  • a) change the behaviour to what the other shells do, or
  • b) keep and document the behaviour and change it to the POSIX compliant way when asking for POSIX standard mode.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions