Why do we need a shell in Linux? As an example when I type - find . -name xy* - I was told that the shell takes this input and calls the find command (making sure the wild card is correctly interpreted and all that). Can't this be done without the concept of a shell?... if shell keeps track of the various process can't this be done without it?

Also,
why is that I can type >ls xy* and get a proper output while I need to escape * with a \ in find - find . -name xy\*
Is shell doing the wild card expansion for one and not for the other executable?

"Operating system shells generally fall into one of two categories: command-line and graphical. Command-line shells provide a command-line interface (CLI) to the operating system, while graphical shells provide a graphical user interface (GUI). In either category the primary purpose of the shell is to invoke or "launch" another program; however, shells frequently have additional capabilities such as viewing the contents of directories."

As for your other question, the shell is doing wildcard expansion for both commands, but when you are searching for files using find you want find, and not the shell, to do the expansion, since you want it done in the locations find is looking in and not in the location it was invoked from; therefore, you escape the * to stop the shell expanding it, so that find can see it.

so, you say that in Windows the Start button is called a shell? :-)
–
Pavel ShvedSep 6 '09 at 17:30

5

It is not a common usage, but GUIs are arguably shells (at least if they run outside the kernel). The Start button is just a feature of the GUI...
–
dmckeeSep 6 '09 at 17:34

Start button is definitely a thing "that interprets your intent and invokes the appropriate program". OTOH, Linux shell can be just called a feature of TUI (Text User Interface).
–
Pavel ShvedSep 6 '09 at 17:38

11

@Paul: Explorer, the program which provides the start button is the windows shell. In fact, it is a Windows shell; it can be replaced.
–
moonshadowSep 6 '09 at 17:45

1

Yes, the start button can be seen as a shell. Not an interactive shell but a shell nonetheless. Typically though, when someone says "shell" they mean an interactive prompt (for example, the command prompt on windows is a traditional shell)
–
Bryan OakleySep 6 '09 at 17:51

You can of course do everything through a GUI. Windows' Find Files (from XP and earlier) is a somewhat GUIsh equivalent of the command you typed.

Now, why do UNIX (and Linux) users like shell? Because you can take the output, feed it into another program, and get different output. For example:

find | grep burek

These are two commands, find and grep, one feeding the other. find lists all files in current and all child folders, one per line, and grep prints out only those lines that contain burek.

Now, there are other, more complex things, such as:

ls -R | sort | uniq

ls -R lists files in current and child folders, and sort sorts the output. uniq then gives us only unique lines.

Now, while you can code all this into a GUI, you can quickly do such tricky stuff with command line that you can't ordinarily do with GUI unless you go write your own. In which case, it's faster to just type it into command line, isn't it?

Bottomline: If you ask this, you don't need it. Command line is useless for you as a regular user. Command line is however great for sysadmins, for developers, and those who want to mess around with their computer in a fast fast fast way.

Yes you can run the find command without a shell - you'd need some program to start it though,
and you'd need some program to display it's output. A lot of times, you're using features of the shell, and that command will need a shell to interpret the intent.

e.g. piping, redirection and globbing is a feature of the shell, and will need a shell to interpret.
"find . -name myfile" doesn't use any feature of a shell, and could be run without a shell.
"find . -name myfile | sort >output" uses both piping and redirection and you need a shell to interpret that.

As for escaping xy* , there's little difference if it's the input to find or the output of a rediction, the shell will expand it either way.

If there's a file named xyz in the current directory

find . -name xy* will actually run as find . -name xyz , which is probably not what you want.

If you do find . -name xy* and there's no file matching xy* in the current directory,
it will run as find . -name xy*.

Similarly, if there's no file matching xy* in the current directory ls >xy* will create a file named xy* . If there's one file matching - say xyz, it'll mean ls >xyz. If there's several files matching xy* then ls >xy* will fail.

To answer your second question...the shell will attempt to expand whatever it can whenever it can, unless you prevent it. Escaping the * prevents the expansion, which is usually necessary for the find command.

Not to answer a question with a question, how would you know if the ls command was listing the files due to a command line expansion or because the ls command legitimately looked up the directory listing from the filesystem? For instance, i could write a shell for loop like this:

why is that I can type >ls xy* and get a proper output while
I need to escape * with a \ in find - find . -name xy\* Is
shell doing the wild card expansion for one and not for the
other executable?

The point of escaping '*' in the find invocation is to prevent the shell from doing the expansion. By escaping it, you ensure that find sees the arguments: ".", "-name", "xy*".
If you did not escape the '*', find would see ".", "-name", "xya", "xyz" (assuming the shell expands "xy*" to "xya xyz", which will happen if the only files that start xy are xya and xyz). So the answer to your question is no, the shell does not expand the '*' in your invocation of find because you explicitly asked it not to by escaping it.

Shell in Linux is a convenient and conventional way to interact with file system in Linux and run commands with arguments and with respect to environment variables. It provides a plenty of useful features, for example, connecting output of one process to other's input, redirecting input/output streams to/from files, FIFOs, etc. A shell is a good way to easily combine several small programs, each of them doing a relatively small task, to provide something useful. Some of these programs (such as find and ls) were designed for working with them in a shell.

To understand expansion, merely remember that a word (space-bounded sequence of aplhanumeric characters and -, and some other symbols), given it contains * or ? pattern characters, is not escaped or put inside the quotes (") or apostrophes ', is substituted with a series of space-delimited words with filenames that match the pattern. So were you had one word with an asterisk, after expansion you'll have zero, one or several words, which will be treated by bash as several arguments. Here comes the specific design of ls command: it fits this scheme perfectly when used as ls foo* to display all files that start with "foo"! It is expanded into something like

ls foobar boobaz

and ls just prints files from arguments, checking for existence and traversing into fiolders etc.

But that's mostly the question of philosophy. In other systems everything emerges from the "Start" button and taskbar. Some users are fine with it. Some try to install a linux-like shell into such systems. That's a matter of taste, but for programming simple scripts, that deal with files, shell is extremely convenient.

But the key point of shell is that it is a script language: you can create whole programs that are executed in specific situations (boot, session opening, every day, ...). This feature cannot be replaced by other tools.

Of course you could run Linux and never use the shell. Out of the box many standard Linux distros offer a home user exactly what they need if they just want to check facebook, look at pictures and send email.

Linux has many pros, but the shell is probably the best one. The shell allows for I/O redirection. This is what people talk about when the refer to pipes ("|"). For example:

I want to connect to a list of machines and perform a survey of where a user account exists:

There could be 0 hosts in hostnames.txt or there could be thousands. This script will zip through and make the survey, spitting the information to stdout.

Scripting can get very creative. I can use the "/>>" characters to redirect input/output from and to files. I could survey all of those machines in the script above, output the server name from any that have the user to a file, then follow up with another script that connects and performs some task on the user account (lock/unlock/reset pw/remove/add group/etc).