While parsing bracket expression ('[...]'), DASH recognizes only '!' as a special character for negation/inversion, but POSIX specifies '^'. The POSIX specification (2018 edition) states: ^ The <circumflex> shall signify a non-matching list expression when it occurs first in a list, immediately following a <left-square-bracket> (see RE Bracket Expression). DASH: $ i='123 asd' && printf "%s\n" "${i##*[!a-z]}" asd $ i='123 asd' && printf "%s\n" "${i##*[^a-z]}" <empty expansion> BASH (with --posix): $ i='123 asd' && printf "%s\n" "${i##*[!a-z]}" asd $ i='123 asd' && printf "%s\n" "${i##*[^a-z]}" asd Make <circumflex> ('^') a special character used to specify negation/inversion in bracket expressions: $ i='123 asd' && printf "%s\n" "${i##*[^a-z]}" asd Signed-off-by: Dimitar Yurukov <mscalindt@xxxxxxxxx> --- src/expand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/expand.c b/src/expand.c index 1730670..06392ff 100644 --- a/src/expand.c +++ b/src/expand.c @@ -1565,7 +1565,7 @@ pmatch(const char *pattern, const char *string) startp = p; invert = 0; - if (*p == '!') { + if (*p == '!' || *p == '^') { invert++; p++; } -- 2.32.0