On 8/9/25 16:40, Robert Elz wrote:

   | Lets just choose one behavior, and add it to our testsuites
   | to "solidify" it, so that it doesn't changes unnoticed
   | in the future.

Which one should be picked?

Ok, I'll try

${VAR#PATTERN}:

PATTERN is processed and then given (on the C level) to fnmatch()
(or fnmatch()-equivalent internal matching function) to match
beginning of VAR.

The parts of the PATTERN may contain variables and may be quoted
with "" or unquoted.

The quoted parts are processed to add glob pattern escapes
to characters like *, ?, \, [ to match everything literally.

The shell should try to correctly escape only those characters
which do need escaping: "[a]" should be escaped as "\[a]",
but "[]" does not need escaping, etc.
(This may be impractical to get totally correct since the shell
may not know what types of [...] libc implements in fnmatch(),
there are various ... "extensions" in various libcs).

If an unquoted part of PATTERN results in an unpaired backslash,
it is preserved and concatenated to the remaining part of PATTERN,
if any:

backslash='\'
asterisk='*'
$backslash            in PATTERN expands to \
$backslash*           in PATTERN expands to \*
$backslash$asterisk   in PATTERN expands to \*
$backslash"*"         in PATTERN expands to \\*
$backslash"$asterisk" in PATTERN expands to \\*
(the last two rules somewhat unexpectedly will NOT match '*' as literal)

If shell implements internal fnmatch(), the trailing incomplete backslash
should match one '\' character:

VAR='\abc'; ${VAR#$backslash} returns 'abc'

(Users are recommended to use ${VAR#"$backslash"} to not depend on it)


Reply via email to