Analyzing a Linux command

cantguess

New Member
Credits
66
Hello!

I'm a beginner Linux user. The University I study at makes it a compulsory course for us.
We got some questions, but I can't answer them. Any help is much appreciated!

There is this line (command): sudo find / -type f -exec file ’{}’ \; | grep ’Shell script’ | wc -l

The questions are the following:

1. What would happen if we left the '' signs out of the exec file ’{}’ command and why?
2. What would happen if we left the \ sign out and why?
3. What would happen if we left the '' signs out of the grep 'Shell script' command and why?

I overall understand that this line searches all the files in which "Shell script" can be found, and counts them. However, I don't understand it in depth at all.

Many thanks for the answers in advance!
 


JasKinasis

Well-Known Member
Credits
4,005
Wow!! Well have you tried RUNNING the commands to see what happens?

What that command is SUPPOSED to do is find ALL files in /, runs the file command to find out the type of file, uses grep to find results containing the string "Shell script" and then counts the number of results returned by grep.

So in other words, it SHOULD determine the number of shell-scripts you have on your PC.

In answer to the questions:
1. The quotes aren't required around the {} braces. The find command with the -exec will work with, or without quotes around the braces.
The {} braces are a placeholder for the path/file that was found by find, which will be substituted into find's -exec command each time find "finds" a file.

2. -exec expects a semi-colon that has been escaped by a backslash \ character e.g. \; To indicate the end of the command that is to be executed each time a file is found.
If you leave the \ (escape character) out - the semi-colon ; gets treated as a literal semi-colon character. So you'll get a syntax error because -exec has not been terminated correctly and it will affect the shells interpretation of the rest of the line.

3. If you left the quotes out of the 'Shell script' parameter to grep - then in the grep command, the space would be interpreted as a literal space, so the shell would treat the words "Shell" and "script" as separate entities.
In other words - in the context of the grep command:
"Shell" would be the search term and the word "script" would be the file (or directory) for grep to search in. AND on top of that you're getting the filename from find piped into the end of the grep command too.
So you'll at least get an error about a file/directory called script not existing. UNLESS you have a file, or directory called script in the current working directory. In which case - grep may or may not get a result, depending on whether the script file/directory contains anything with the word "Shell" anywhere in it.

So in the grep command, the quotes are required because the space character in "Shell script" is part of the search term.

Note: When quoting, you can use single quotes, or double quotes.
The difference between single quotes and double quotes are - strings inside single quotes are literal strings.
Strings that are inside double quotes can use shell expansions - e.g. variable substitutions, command substitutions, arithmetic substitutions. So by using double quotes you can build strings using values from variables, or using the output of other commands.

It is also possible to include the space in the search without using the quotes - by escaping any space characters with a \ backslash.
e.g.
Bash:
sudo find / -type f -exec file {} \; | grep Shell\ script | wc -l

FINALLY - your original command WILL run without any errors, but it should be noted that it will almost certainly return an incorrect count of 0. Which is probably a deliberate bug put in by your professor (or perhaps it was just a typo on your part?!).

Here is your original command again:
Bash:
sudo find / -type f -exec file ’{}’ \; | grep ’Shell script’ | wc -l
Why do I know it will return 0? Because if you run the file command on a bash shell-script it says:
"/path/to/filename: Bourne-Again shell script, ASCII text executable"

Your grep command is searching for "Shell script" NOT "shell script". And by default, greps searches are case-sensitive. So because of the capital S - you'll get no matches. And because there are no matches from grep - wc will return a count of 0; Which is incorrect!

So in order to get any positive results from grep - you either need to use greps -i option, or change the uppercase S at the start of the search term, to a lower-case s.

So in order to get the intended output - the correct command should be either:
Bash:
sudo find / -type f -exec file {} \; | grep -i 'Shell script' | wc -l
OR:
Bash:
sudo find / -type f -exec file {} \; | grep -i "Shell script" | wc -l
OR:
Bash:
sudo find / -type f -exec file {} \; | grep -i Shell\ script | wc -l
OR:
Bash:
sudo find / -type f -exec file {} \; | grep 'shell script' | wc -l
OR:
Bash:
sudo find / -type f -exec file {} \; | grep "shell script" | wc -l
OR:
Bash:
sudo find / -type f -exec file {} \; | grep shell\ script | wc -l
All of the above commands are equivalent and should yield the same result, which will be the number of shell-scripts on the current system.

The first three use grep's case-insensitive search. The last three specify the all lower-case "shell script".
And the only other differences are the quoting methods used. Single quotes, double quotes and no-quotes (but escaping space characters).

I hope this clears things up for you!
 
Last edited:

Condobloke

Well-Known Member
Credits
5,020

70 Tango Charlie

Well-Known Member
Credits
986
@JasKinasis @Condobloke
Both you guys are worth every penny - or dime - or thousands - or whatever you are getting paid!!!!
Old Geez
 


Members online


Top