4 ms·
find /home -type f -name test.* This will silently fail if you happen to have one file that matches test.* (like test.txt) in the current working directory, be
by jraph 5y ago
find /home -type f -name test.*
This will silently fail if you happen to have one file that matches test.* (like test.txt) in the current working directory, because test.* will be replaced by the name of this file and that's what find will see.
This will fail in zsh if no files match in the current working directory, because globbing will fail.
You need to quote this to avoid unintuitive results, in any shell.
find /home -type f -name 'test.*'
Not doing this will probably work most of the time, but it will probably confuse you the one time it won't and drive you crazy if you don't realize what is going on.
I've become very aware of this kind of things by using zsh which is stricter with failing globs than bash. Also quote anything that contains {, }, [, ], (, ), ?, ! or $ for similar reasons. Beware of ~ too. And & or | obviously, and also ;.
Do yourself a favor, quote the hell everything in shells that's not simple, alphanumeric strings or option names. Even if it's only alphanumeric actually, if it is a parameter value, quote it. This way, when you edit your command and somehow add a special character, you are already covered. It also makes your values stand out, making your command arguably easier to read because they might look more uniform.
edit: and quote with single quotes, unless you need variable expansion or to quote simple quotes (but be extra careful then)
- hdjjhhvvhga 5y ago> Do yourself a favor, quote the hell everything in shells that's not simple, alphanumeric strings or option names. This should be the first sentence in any shell manual. It will bite you sooner or later.
- oweiler 5y agoThis is before glob expansion happens before running the program. > The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and filename expansion. Straight from the manual https://www.gnu.org/software/bash/manual/html_node/Shell-Expansions.html#:~:text=The%20order%20of%20expansions%20is,word%20splitting%3B%20and%20filename%20expansion https://www.gnu.org/software/bash/manual/html_node/Shell-Exp....
- IiydAbITMvJkqKf 5y agoshellcheck warns about constructs like these, and many more.
- jraph 5y agoAbsolutely. One doesn't use shellcheck when using the shell interactively though, so it's still good habits to take.
- pabs3 5y agoGlobs in an interactive shell should get expanded and then force you to press enter to confirm the command with expanded globs. Are there any shells that implement this?
- louiskottmann 5y agoThat would become unreadable in many cases, like du -sh *
- deleted 5y ago[deleted]
- jraph 5y agoIn zsh, you can press tab after something that will get expanded, and it expands in place. I actually use it quite often to check whether the expansion is right. However, this does not cover the case where an unexpected globbing happens like in this find situation.
- massysett 5y agoI looked through zshoptions(1) and didn’t see anything like this. However you can turn off globbing entirely with “unsetopt glob”. There are however other expansions that occur outside of globbing, such as parameter substitution. It might be possible to implement this using zsh’s line editor, but it would take some digging through the man pages to figure this out (or finding a zsh expert). Try zshzle(1). Yeah this is probably a much more complicated answer than you were looking for.
- hulitu 5y agofind /home -type f -name test.*
- sys_64738 5y agoAlso: find /home -name test.\*
- maddyboo 5y agoAlso = when prefixed with a space, which works basically like `command -v`, expanding to the full path of the executable. For example `echo =grep` results in `/usr/bin/grep`.
- nextaccountic 5y agoWhat you really should do is to stick shopt -s failglob On top of shell scripts (and on ~/.bashrc), so that a glob that doesn't expand will always be an error. That way, you won't have that unquoted test.* work by accident, and thus it's easier to train yourself to always quote. Or, just use zsh, which has this behavior by default. Anyway here are other shell scripting tips: https://sipb.mit.edu/doc/safe-shell/ https://sipb.mit.edu/doc/safe-shell/