A shell script is a script written for the shell, or command line interpreter, of an operating system. It is often considered a simple domain-specific programming language. Typical operations performed by shell scripts include file manipulation, program execution, and printing text.
Many shell script interpreters double as command line interface, such as the various Unix shells, Windows PowerShell or the MS-DOS
COMMAND.COM. Others, such as AppleScript or the graphical Windows Script Host (WScript.exe), add scripting capability to computing environments without requiring a command line interface. Other examples of programming languages primarily intended for shell scripting include DCL and JCL.
This example also demonstrates the use of wildcard characters, a simple way of matching multiple related files ("*" denotes any sequence of characters). Most shells implement basic pattern matching capabilities like this, which allow them to perform commands on groups of items with similar names and sometimes parse simple strings of text.
Although each shell scripting language is different, there are a number of additional features which are often provided. One is a mechanism for manipulating some form of variables, in other words, named values which can be inserted elsewhere in the script at specified locations. For example, this script copies all .txt and .mp3 files from the current directory to the directory named by the variable "fuzzy":
By changing the value of the variable "fuzzy", the user can specify to where the files are copied. However, rewriting a script to change a variable's definition each time the script is run would be a nuisance, so scripting languages typically also support special variables which provide access to any arguments passed to the script on the command line. For example,
$9 refer to the first nine arguments given to a Bourne shell script, as do
%9 in DOS batch files. Also, a shell's internal variables are often integrated with the operating system's notion of per-process or per-session environment variables.
Another common feature of shell scripting languages is some way of dealing with return codes, which are numbers returned from executed programs to indicate whether they succeeded or failed. In the Bourne shell, for example, the notation
a && b means to first execute
a, then execute
b only if
Many modern shells also supply various features usually found only in more sophisticated general-purpose programming languages, such as control-flow constructs (if, while, goto), mutable variables, comments, subroutines, and so on. With these sorts of features available, it is sometimes possible to write reasonably sophisticated applications as shell scripts, although of course the more demanding, complex or large-scale systems will usually require more powerful programming languages. Though the shells are powerful in their way, they have few structuring mechanisms, limited built-in commands, and are generally interpreted relatively slowly.
For tasks that are too large or complex to be comfortably handled with ordinary shell scripts, but for which the advantages of a script are desirable and the development overhead of a full-blown, compiled programming language would be disadvantageous, many powerful scripting languages have been introduced. The specifics of what separates scripting languages from high-level programming languages is a frequent source of debate.
On the other hand, shell scripting is prone to costly errors. Inadvertent typing errors such as rm -rf * / (instead of the intended rm -rf */) are folklore in the Unix community; a single extra space converts the command from one that deletes everything in the sub-directories to one which deletes everything - and also tries to delete everything on the root partition. Similar problems can transform cp and mv into dangerous weapons, and misuse of the > redirect can delete the contents of a file. This is made more problematic by the fact that many UNIX commands differ in name by only one letter: cp, cn, cd.
Another significant disadvantage is the slow execution speed and the need to launch a new process for almost every shell command executed. When a script's job can be accomplished by setting up a pipeline in which efficient filter commands perform most of the work, the slowdown is mitigated, but a complex script is typically several orders of magnitude slower than a conventional compiled program that performs an equivalent task.
Similarly, more complex scripts can run into the limitations of the shell scripting language itself; the limits make it difficult to write quality code and extensions by various shells to ameliorate problems with the original shell language can make problems worse.
Many disadvantages of using some script languages are caused by design flaws within the language syntax or implementation, and are not necessarily imposed by the use of a text-based command line; there are a number of shells which use other shell programming languages or even full-fledged languages like Scsh (which uses Scheme).