SHELLEXP(3)

πŸ“¦ version 0.9.40, in ubuntu jammy

πŸ’… NAME πŸ’…

okay bestie, meet shellexp β€” she matches a string against a cruft filter pattern. that's the whole vibe. ✨


πŸŽ€ SYNOPSIS πŸŽ€

extern int shellexp(const char *string, const char *pattern);

✨ DESCRIPTION ✨

so shellexp() is basically fnmatch(3)'s cooler cousin, except instead of standard glob(7) patterns she works with cruft patterns. iconic behavior honestly.

She returns a true value when string matches the cruft pattern pattern, and a false value (0) otherwise. And if the pattern has a syntax error? She returns -1. not her fault, the pattern was messy. πŸ’€

Cruft patterns are similar to glob(7) patterns but not fully compatible β€” think "inspired by, not copying." πŸ¦‹ The special characters she supports are:

  • ? (a question mark) β€” matches exactly one character of string, and not a slash. just one. she's picky.
  • * β€” matches zero or more characters of string, again not a slash. zero is allowed, she's generous like that. πŸ’–
  • /** or /**/ β€” matches zero or more path components in string. okay but hear me out, the rules here are specific:
    • you can only use ** when it's directly following a slash, and
    • furthermore only when it's either directly preceding a slash or at the very end of pattern.
    • a ** followed by anything other than a slash makes pattern invalid. periodt.
    • a ** following anything else than a slash gets reduced to having the same effect as *. she's humbled. πŸ™ˆ
  • [character-class] β€” matches any character between the brackets exactly once. Named character classes are NOT supported, sorry to the [:alpha:] girlies. If the first character of the class is ! or ^, the meaning is inverted (so it matches any character NOT listed between the brackets). Wanna put a literal closing bracket in the class? specify it as the first character after the opening bracket β€” or the second, if you're negating. also, simple ASCII-order ranges are supported using a dash character (peep the examples section πŸ‘€).
  • Any other character matches itself. simple. no drama. 🌸

🌈 EXAMPLES 🌈

  • /a/b*/*c β€” matches /a/b/xyz.c, as well as /a/bcd/.c, but not /a/b/c/d.c.
  • /a/**/*.c β€” matches all of the following: /a/a.c, /a/b/a.c, /a/b/c/a.c and /a/b/c/d/a.c. she ate that. πŸ‘‘
  • /a/[0-9][^0-9]* β€” matches /a/1abc, but not /a/12bc.

πŸ’€ BUGS πŸ’€

ngl there's some stuff you should know:

  • She uses constant-length 1000 byte buffers to hold filenames. yeah. 1000. exactly.
  • She also uses recursive function calls, which are not very efficient. it's giving "works but don't stress her."
  • She does not validate the pattern before matching, so any pattern errors (unbalanced brackets or misplaced **) are only reported when and if the matching algorithm reaches them. so like, she'll find out mid-match. live your truth I guess. 😭

🫢 SEE ALSO 🫢

fnmatch(3), glob(3), cruft(8) and dash-search(1).


πŸ’œ AUTHOR πŸ’œ

This manual page was written by Marcin Owsiany <porridge@debian.org>, for the Debian GNU/Linux system (but may be used by others). shoutout to them fr fr. πŸŽ€


and that's a wrap bestie!! this page is from the Library Functions Manual, dated October 17, 2007 β€” SHELLEXP(3) forever in our hearts. bye bye, go match some patterns responsibly πŸ’…βœ¨
πŸ“¦ where this page comes from