Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I'm baffled by the find command's response to the * (asterisk) wild card. Would anyone be kind enough to explain the results of the three searches below?
Is the explanation of why the quotes are needed a long one? Could you point me in the right direction to research this further? A topic of research perhaps?
The quotes are necessary to prevent the shell from expanding them too early.
When you execute a command using a wildcard (such as rm *), the shell expands the asterisk before calling rm. So if you had a directory containing three files (file1, another_file, third_file), then bash expands the command to:
Code:
rm file1 another_file third_file
The rm command never, ever, ever sees the asterisk; it only sees a list of files and directories.
So take that and apply it to your command:
Code:
find / -iname eddie*
You have two directories that match that pattern: eddie and eddie2. The shell expands the wildcard, so the final command looks like this:
Code:
find / -iname eddie eddie2
The first match (eddie) is applied to the -iname option. The second match (eddie2) is now orphaned. So find thinks you're trying to specify another path for it to look in. So it errors out.
You use the double quotes ("eddie*") to prevent the shell from expanding the asterisk. By doing that, the find command sees the asterisk, and interprets it as you intended.
I think I understand -- the find search can't be completed the because the * wild card is expanded, and the return from the expansion process is used as a part (condition) of the find command. However the return's syntax is wrong -- quite wrong -- and can not be understood by the find command.
I'm confused as to why this situation only applies to the / directory. If you don't mind my asking, why does following command work?
There's no relation to the root directory ( / ) and the problem you were seeing. It's the directory you run the command that influences it.
In your original command, you executed the find command from the root directory. There were two directories at the root level that matched the eddie* pattern: /eddie and /eddie2. If you executed the exact same command from /home, you wouldn't have encountered the same problem. The reason is because (I assume) there are no eddie* directories inside /home. In other words, the eddie* pattern would not match anything in the directory you launched the command from, and that means eddie* is replaced by an empty string. The final command would look something like:
Code:
find / -iname
That might cause the find command to error out because there is no argument for iname, or it might just ignore that option... dunno which... haven't tried.
Actually, if the shell can't expand an expression, it leaves the expression verbatim. This is why the following occurs:
Code:
$ ls non-existant*
ls: non-existant*: No such file or directory
If the shell replaced it with a blank, ls would list all the files in the directory (like ls by itself). This would lead to some very confusing behavior.
If you want to play around with seeing how the shell expands expressions, use echo.
(By the way, this is one way to list files in a directory WITHOUT spawning another process... it's useful to check for a rootkit with a hacked version of ls... )
If more explanation is needed, please let me know and I'd be quite glad to expand on this more.
Good call Matir. As I was writing it, I knew there was something that wasn't quite right, because I'd seen the "blah*: no such file or directory" message you quoted before.
Thanks again folks. I recreated the situation and copied and pasted the text from my terminal (below).
The steps it details are: 1) Delete all files named eddie 2) double check that eddie files are gone. 3) create the eddies. 4) list the eddies. 5) try to find the eddies -- and fail 6) move the eddies. 7) try to find the eddies again (using the same command as before) and succeed.
Code:
[root@localhost /]# find / -iname "*eddie*" -exec rm -f {} \;
[root@localhost /]# find / -iname "*eddie*"
[root@localhost /]# vi eddie; vi eddie2
[root@localhost /]# ls
bin dev eddie2 home lib misc opt root tmp var
boot eddie etc initrd lost+found mnt proc sbin usr
[root@localhost /]# find / -iname eddie*
find: paths must precede expression
Usage: find [path...] [expression]
[root@localhost /]# mv /eddie /home ; mv /eddie2 /home
[root@localhost /]# find / -iname eddie*
/home/eddie
/home/eddie2
[root@localhost /]#
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.