I decided to read a book about Linux/Unix.
I've reached a chapter where they try to explain how to pass the output of commands as expansions to the shell.
The following command
file $(ls /usr/bin/* | grep zip)
gives me the error "cannot open "file name (No such file or directory)".
On the contrary, when I do
file $(ls | grep zip)
everything appears normally, no matter the folder. Why? Is it some kind of argument restriction?
If I do this
file $(ls Pictures/ | grep jpg)
I get the following:
1234.jpg: ERROR: cannot open 1234.jpg (No such file or directory)
while moving right in the directory that I want to list
nassosdim@ubuntu:~$ cd Pictures/
nassosdim@ubuntu:~/Pictures$ file $(ls | grep jpg)
prints out the result of file
1234.jpg: JPEG image data, JFIF standard 1.01
Can someone explain to me what's going on? 🙁
Best Answer
The error is coming because bash is trying to expand the
*
in your argument to ls using glob pattern matching. It will always through such an error when the glob doesn't match the pattern. The*
then gets passed tols
as a real asterisk, which doesn't match a file either sols
will error!There are several bits about what you are doing that are redundant. I know you are trying to learn a construct, but let's break down some of the bits of what you just accomplished and how it could have been done.
ls /usr/bin
is sufficient to list files in the bin directory, you don't need the star at all.ls
at all, it is ambiguous and potentially dangerous.ls /usr/bin/*zip*
, but thels
is still redundant, you can just pass the glob expantion to file:file /usr/bin/*zip*
Lastly,
find
is usually a better tool for finding files. You could do what you are after like this: