An intro to finding things in Linux
madebygps.com
madebygps.com
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)
This should be the first sentence in any shell manual. It will bite you sooner or later.
> 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-Exp....
One doesn't use shellcheck when using the shell interactively though, so it's still good habits to take.
However, this does not cover the case where an unexpected globbing happens like in this find situation.
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.
find /home -name test.\*
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/
I am sure that well-versed users can achieve wonderful things with it; myself, I either use fd or pipe "du -a" into grep (or rg), and move on with my life.
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/f...
locate.
These search engines are very powerful because they do deep file scanning, are based on mature frameworks such as Apache Lucene.
For KDE, this was called Nepomuk https://userbase.kde.org/Nepomuk and is nowadays called Baloo https://community.kde.org/Baloo, and can be used in fact from the command line (baloosearch)
For GNOME, this is (apparently, not using GNOME in the last years) called Tracker https://gitlab.gnome.org/GNOME/tracker
$ ag -l -g which /usr/bin/
/usr/bin/which
/usr/bin/kpsewhich
/usr/bin/sgmlwhich
$ ag -l -g /which$ /usr/bin/
/usr/bin/whichWhich you can install as a binary, or via cargo. fd is spectacular.
To that you can add: https://github.com/junegunn/fzf
Which you can bind to a key in your shell for convenience.
52 │ export FZF_DEFAULT_OPTS='--reverse --border --exact --height=50%'
53 │ export FZF_ALT_C_COMMAND='fd --type directory'
54 │ export FZF_CTRL_T_COMMAND="mdfind -onlyin . -name ."
Obviously mdfind is mac only.Given that `which` is not POSIX compliant you wonder why it is so popular compared with command -v which is just slightly more complicated.
grep --include='*.js' -rn methodName
will recursively search the current directory and all subdirectories for .js files containing the word 'methodName'Obviously IDEs can do this as well, but since you can supply regex, you can get some pretty complicated cases.
Random arbitrary example but difficult to do with an IDE -
grep --include='*.js' -rn methodName\([^,]*,[^,]*,[^,]\*\)
same as above, but only find methods with 3 arguments find . -print0|grep -z something|xargs -0 ls -lI use an implementation I have written in the shell itself whose database format is nothing more than every file path on the system separated by null bytes, that is simply grepped to find files; the speed difference is absurd.
—— — time locate */meme.png
/storage/home/user/pictures/macro/meme.png
real 0m0.885s
user 0m0.806s
sys 0m0.010s
—— — time greplocate /meme.png$
/storage/home/user/pictures/macro/meme.png
real 0m0.089s
user 0m0.079s
sys 0m0.011s
This implementation is highly naïve and simplistic, and offloads all the searching to GNU Grep, yet outperforms the actual `locate` command by an order of magnitude.(Disclosure: I'm the author of plocate.)
—— — true
—— — false
—— 1 sh -c 'exit 120'
120 sh -c 'exit 20'
— 20
It doesn't show the colors here of course.mdfind in the terminal if you prefer it that way.
54 │ export FZF_CTRL_T_COMMAND="mdfind -onlyin . -name ."
Unfortunately it's not instant - it takes about a second for the tens of thousands of file entries to populate. But fzf searching that list is practically instant. After selecting the file I want, enter just returns me to the command line with the full path to the file. I can then ctrl-a and type 'vim' or 'code' or whatever. It's not a perfect workflow, but it's pretty good for finding files in complex folder structures.To skip the .git directory:
`find . -type d -a -name .git -prune -o -type f -a -iname '*.json' -print`
dpkg -L packagename | grep doc
On Debian for instance.
Or even finding out which package installed a specific file with apt-file.
dnf repoquery -l packagename
To list the files within a package. dnf whatprovides "**/bin/executable"
To find what package provides a certain file. Definitely very useful when trying to build packages from source and not sure in what packages the reported missing libs/headers are located. dnf search <something> strace some_app 2>&1 | grep open
And it will tell me what files is it opening. You will also see files it tried but failed to open, i.e. missing files.To include dired would be nice, but I understand that is not the everybody's sauce.
Even when someone gathers enough knowledge to write an introductory guide to using the damn thing, it turns out it's all wrong, has bugs, fails in unexpected ways or is a deprecated method that's being phased out.
Respect to those of you who work with it.
It's a problem with a tutorial written by someone who is underqualified to be doing so, so that she can get page hits to boost her "brand."
She's a fucking streamer, employed by Microsoft to be a .NET "advocate" https://developer.microsoft.com/en-us/advocates/gwyneth-pena...
Her site is just regurgitating the usual novice guides, of which you can find a dozen better examples.
Being a streamer and a .NET advocate does not make one incompetent in POSIX shell. Thing is, POSIX shell is tricky and it's all too easy to fall into traps, even for experienced people.
In the shell area, there are attempts to fix the syntax, like fish [1]. I'm afraid this kind of things is doomed to remain niche, because when you deeply understand what it is trying to do, you are also probably used to classic POSIX shell enough that you may not want to change. Fish users also need to go back to bash or zsh to follow a number of tutorials and documentations, so even them can't avoid POSIX shells.
I myself adopted zsh to have the features of fish and keep the bash-like syntax since I need to deal with this syntax either way.
In the Windows world, and actually Unix too, there is also Powershell. Can't comment that much since I don't know it, but it does not seem to have taken off on Unix, and many people on Windows seem to use bash through WSL anyway.
My conclusion is that bash and bash-like shells are ruling the world, even on Windows, and we are stuck with the POSIX shell syntax for now and probably a long time.
Some reasons could be: not installed on machine, and not allowed (or not supposed to) install it globally or locally, embedded machines which don't have space to install new software.