4 ms·
IMHO this is a design error in find. Tools should not heavily depend on characters which are also shell metacharacters, particularly in ways which are similar e
by twic 5y ago
IMHO this is a design error in find. Tools should not heavily depend on characters which are also shell metacharacters, particularly in ways which are similar enough to the way the shell uses them to cause confusion when they collide.
find . -name %.jpg
Solved.
- hnbad 5y agoI'd argue that this is a design error in glob expansion. It's highly unintuitive that globs are passed "raw" when nothing matches and it's perfectly expected that users will be confused about how globs behave if their behavior depends entirely on the contents of the file system. Human brains simply don't work that way and it's terrible user experience to expect users to be able to predict whether the glob will match before executing it. A more intuitive solution would be to resolve globs to nothing (the empty string) if they don't match. In most users' mental models "*.jpg" means "any file ending with .jpg" when they pass it to a command like "rm" or "mv", but in reality it means "any file ending with .jpg in the current directory, or the literal string '*.jpg' if there are none" which is nonsensical. If it expanded to nothing, it would be obvious that it needs escaping when passed to commands like find because find would complain about not being passed a file name. The failure case is outright user-hostile and error-prone. Also if every tool used its own metacharacters, users would have to re-learn them for every tool. It's common for config files to also use globs, for example. Even if we just had one set of characters for shells and one set for other tools, it's often difficult to draw the line, especially if tools use shells and thus would need to translate from one set to another. If this is a design error in find, it's a design error in all tooling that isn't a shell and we need to throw it all out and start from scratch.
- FDSGSG 5y agoYep, just use a better shell ~ echo f43f3f*gsdgds zsh: no matches found: f43f3f*gsdgds ~ bash user@debian:~$ echo f43f3f*gsdgds f43f3f*gsdgds
- ukfarmer 5y ago"A more intuitive solution would be to resolve globs to nothing (the empty string) if they don't match." I agree, so I use shopt -s nullglob in both bash scripts and interactive shells. It retrained my interactive habits with find very quickly because unquoted wildcards no longer work in the common case where there's no match in the current directory. (I like dotglob, extglob, globstar and pipefail everywhere too: saner defaults than emulating traditional shell behaviours.)
- twic 5y agobash has a couple of shell options [1] which can improve handling of unmatched globs: > failglob > If set, patterns which fail to match filenames during filename expansion result in an expansion error. > nullglob > If set, Bash allows filename patterns which match no files to expand to a null string, rather than themselves. [1] https://www.gnu.org/software/bash/manual/bash.html#The-Shopt-Builtin https://www.gnu.org/software/bash/manual/bash.html#The-Shopt...
- loudmax 5y agoI don't think it's that easy. The syntax of `find` is weird enough as it is, with flags that need to be passed in in the correct order and so many options to choose. So on top of all of that, one now needs to learn an exclusive new regex or globbing system. I don't see that as any easier to learn than remembering to put quotes around the search term. I don't disagree with your central point that this problem can be fixed with better design. But the ergonomics are a hard problem to solve.
- dredmorbius 5y agoThere are tools that use their own metacharacters (mmv(1) comes to mind). The issue with find here is that globs act consistently, but the returned behaviour is dependent on when the evaluation is performed. find(1) treats * just as the shell does, but only if the shell hasn't got to the * first. So to prevent the shell from pattern-matching any * characters, you've got to quote or escape them using single quotes (') or backstrokes (\). Quoting to prevent interpretation of metacharacters is actually commonly encountered in computer contexts. I'm having to quote instances of * but not \ for example in this comment to HN as both have semantic meaning to the content parser. Note that the escape character '\' is only significant when used immediately preceding a *.