From Bash and Korn to C shell: Evaluate the shell in Linux

Source: Internet
Author: User
Tags function examples shebang



Shell is like the editor: everyone has their own choice and tries to defend the choice and tell you why it should be used ). Indeed, shell provides different functions, but they all implement the core concept of development decades ago.

I used modern shell for the first time in 1980s, When I was developing software on SunOS. When I understand the ability to use the output of one program as the input of another program or even use it repeatedly, I have a simple and efficient way to create filters and conversions. This core concept provides a way to build some simple tools that are flexible enough to work with other tools. In this way, shell not only provides a way to interact with the kernel and devices, but also provides integrated services such as pipelines and filters as common design patterns in software development ).

Let's first briefly introduce the development history of modern shell, and then explore some useful shells that can be used in Linux.

Shell Development History

Shell or command line interpreter) has a long history, but we discuss from the first UNIX®Shell. Ken Thompson developed the first UNIX shell named V6 shell in 1971. Similar to its predecessor in Multics, this shell (/bin/sh) is an independent user program executed outside the kernel. The concept of globbing parameter extension pattern matching, such as *. txt) is implemented in an independent utility named glob, just like the if command used to evaluate the conditional expression. This independence can keep shell small. For less than 900 lines of C source code, see references to obtain the source code links ).

This shell is a redirection <> and>) and pipeline | or ^) introduces a compact syntax that has been extended to modern shell. You can also find the support for calling sequential commands;) and asynchronous commands.

What Thompson shell lacks is the ability to write scripts. It is used only as an interactive shell command interpreter) to call commands and view results.

UNIX shell since 1977

Aside from the Thompson shell, we began to look at the modern shell introduced when the Bourne shell was introduced in 1977. The Bourne shell was created by Stephen Bourne at AT&T Bell Labs for V7 UNIX and is still a useful shell in some cases used as the default root shell ). The author developed the Bourne shell after studying the ALGOL68 compiler, so you will find that its syntax is more similar to Algorithmic Language (ALGOL) than other shells ). Despite C development, the source code itself even uses macros to give it an ALGOL68 feature.

The Bourne shell has two main goals: to use it as a command interpreter to execute interactive operating system commands, and to write scripts to write reusable scripts that can be called by shell ). In addition to replacing Thompson shell, Bourne shell also provides multiple advantages over its predecessor. Bourne introduces control flows, loops, and variables to the script, providing a more powerful language for interaction with the operating system, including interactive and non-interactive ). This shell also allows you to use shell scripts as filters to provide support for signal processing integration, but lacks the ability to define functions. Finally, it integrates many of the features we are using today, including command replacement with reverse quotation marks) and the HERE document used to embed the reserved string text into the script.

The Bourne shell is not only an important step forward, but also the basis for many derivative shells, many of which are now applied in typical Linux systems. Figure 1 demonstrates the series of important shells. Bourne shell leads to the development of Korn shell (ksh), almshells (ash), and popular Bourne Again shell or Bash. C shell (csh) is under development when the Bourne shell is released. Figure 1 shows the main series, but does not show all the influences, and does not show shell with significant contributions.


Figure 1. Linux shell since 1977
 

We will analyze some of the shells later to view the language and function examples that contribute to their progress.

Basic shell Architecture

The basic architecture of a hypothetical shell is simple. The shell of Bourne is evidence ). As shown in figure 2, the basic architecture looks like a pipe, which analyzes and parses the input and expands the symbols using various methods, such as parentheses, tildes, variables, parameter extensions, and replacements, and file name generation), and finally execute the command using the built-in shell command or external command ).


Figure 2. Simple architecture of hypothetical shell
 

In the references section, you can find some links to learn about the Open Source Bash shell architecture.

Explore Linux shell

Now let's look at some of the shells, review their contributions and view the sample scripts in each shell. You can view C shell, Korn shell, and Bash.

Tenex C shell

C shell was developed for the Berkeley SoftwareDistribution (BSD) UNIX system at the University of California at Berkeley in 1978. Five years later, the shell introduced functions that are popular in the dec pdp system from the Tenex system. Tenex introduces the file name and command completion functions, as well as the command line editing function. Tenex C shell (tcsh) is still backward compatible with csh, But it improves its overall interactive function. Tcsh was developed by Ken Greer at Carnegie Mellon University.

An important design goal of the C shell is to create a scripting language similar to the C language. This is a useful goal, because C language is the main language used, and the operating system is mainly developed in C language ).

One of the useful features referenced by Bill Joy in C shell is the command history. This function maintains the history of previously executed commands and allows users to check and easily select previous commands for execution. For example, if you type the command history, the command previously executed is displayed. You can use the up and down arrows to select commands, or you can use !! Run the previous command. You can also reference the parameters of previous commands, such! * Reference all parameters of the previous command! $ Reference the last parameter of the previous command.

Take a look at a simple example of the tcsh script in Listing 1 ). This script gets a directory name with a parameter) and outputs All executable files in the Directory and the number of files found. I will reuse this script design in each example to demonstrate the difference.

The tcsh script can be divided into three basic parts. First, note that I have used the shebang or hashbang symbol to declare this file as a defined shell executable file. In this example, it is a tcsh binary file. This allows me to execute this file in the form of a regular executable file, without adding the interpreter binary file before it. It maintains the number of executable files found, so I initialized the number to 0.


Listing 1. scripts written in tcsh to find all executable files

#!/bin/tcsh
# find all executables

set count=0

# Test arguments
if ($#argv != 1) then
  echo "Usage is $0 <dir>"
  exit 1
endif

# Ensure argument is a directory
if (! -d  $1) then
  echo "$1 is not a directory."
  exit 1
endif

# Iterate the directory, emit executable files
foreach filename ($1/*)
  if (-x $filename) then
    echo $filename
    @ count = $count + 1
  endif
end

echo
echo "$count executable files found."

exit 0

The first part tests the parameters passed by the user. # The argv variable indicates that the number of input parameters does not include the command name itself ). You can specify the indexes of these parameters to access them. For example, #1 indicates that the first parameter is short for argv [1 ). This script requires a parameter. If this parameter is not found, an error message is output. $0 indicates the command name argv [0] entered on the console.

The second part ensures that the input parameter is a directory. If this parameter is a directory, the-d operator returns True. However, please note that I specified one first! Symbol, which indicates invalid. In this way, the expression indicates that if the parameter is not a directory, an error message is output.

The last part iterates the files in the directory to test whether they are executable files. I use the convenient foreach iterator, which loops every item in the directory in this example) and then tests each item in the loop. In this step, use the-x operator to test whether the file is executable. If yes, output the file and add one to the number. At the end of the script, I output the number of executable files.

Korn shell

Designed by David Korn, Korn shell (ksh) was introduced in the same period as Tenex C shell. One of the most interesting features of the Korn shell is that it is not only backward compatible with the original Bourne shell, but can also be used as a scripting language.

Korn shell was released in the form of open source in 2000 based on the Common Public License) has been a dedicated software. In addition to providing strong backward compatibility with the Bourne shell, the Korn shell also contains other shell functions, such as the historical functions of csh ). The shell also provides more advanced features that can be found in modern scripting languages such as Ruby and Python-such as associating arrays and floating point algorithms. The Korn shell can be used in a variety of operating systems, including IBM®AIX®And HP-UX, dedicated to supporting Portable Operating System Interface for UNIX (POSIX) shell language standards.

The Korn shell is a derivative of the Bourne shell, so it looks more like the Bourne shell and Bash than the C shell. Let's look at a list of Korn shell examples for finding executable files 2 ).


Listing 2. scripts written with ksh to find all executable files

#!/usr/bin/ksh
# find all executables

count=0

# Test arguments
if [ $# -ne 1 ] ; then
  echo "Usage is $0 <dir>"
  exit 1
fi

# Ensure argument is a directory
if [ ! -d  "$1" ] ; then
  echo "$1 is not a directory."
  exit 1
fi

# Iterate the directory, emit executable files
for filename in "$1"/*
do
  if [ -x "$filename" ] ; then
    echo $filename
    count=$((count+1))
  fi
done

echo
echo "$count executable files found."

exit 0

In Listing 2, the first point you will notice is its similarity with listing 1. In terms of structure, the script is basically the same, but there are significant differences in execution conditions, expressions, and iteration methods. Without a test operator similar to C, ksh uses typical Bourne-style operators-eq,-ne, and-lt ).

The Korn shell also has some differences related to iteration. In the Korn shell, the for in structure is used, and the command replacement is used to represent the list of files created from the standard output of the command ls '$1/* indicating the content of the specified sub-directory.

In addition to other features defined above, Korn also supports the alias function to replace a word with a user-defined string ). Korn has many other features that are disabled by default, such as file name completion), but can be enabled by users.

Bourne-Again Shell

Bourne-Again Shell or Bash) is an open source GNU project designed to replace the Bourne shell. Bash, developed by Brian Fox, has become one of the world's most popular shells in Linux, Darwin, Windows®, Cygwin, Novell, and Haiku ). As the name suggests, Bash is a superset of The Bourne shell, and most of the Bourne scripts can be executed intact.

In addition to supporting script backward compatibility, Bash also integrates features from Korn and C shell. You will find command history, command line editing, a directory stack pushd and popd), many useful environment variables and command completion.

Bash continues to develop and has many new features that support regular expressions like Perl) and associated arrays. Although some of these functions may not exist in other scripting languages, you can write scripts compatible with other languages. In this case, the sample script shown in listing 3 is equivalent to the Korn shell script from listing 2), except for the shebang difference (/bin/bash ).


Listing 3. scripts written in Bash to find all executable files

				
     
#!/bin/bash
# find all executables

count=0

# Test arguments
if [ $# -ne 1 ] ; then
  echo "Usage is $0 <dir>"
  exit 1
fi

# Ensure argument is a directory
if [ ! -d  "$1" ] ; then
  echo "$1 is not a directory."
  exit 1
fi

# Iterate the directory, emit executable files
for filename in "$1"/*
do
  if [ -x "$filename" ] ; then
    echo $filename
    count=$((count+1))
  fi
done

echo
echo "$count executable files found."

exit 0

A key difference between these shells is the license for their release. As you may have guessed, Bash was developed in the GNU project and published based on GPL, csh, tcsh, zsh, ash, and scsh are all released based on BSD or a license similar to BSD. The Korn shell can be used according to the Common Public License.

External shell

A bold developer can use an alternative shell Based on your needs or interests. Scheme shell (scsh) provides a script environment that uses a derivative of the SchemeLisp language. Pyshell is an attempt to create a script similar to the Python language. Finally, for embedded systems, BusyBox can be used to merge a shell and all commands into a binary file to simplify distribution and management.

Listing 4 shows a script written in Scheme shell (scsh) to find all executable files. This script may seem strange, but it implements a feature similar to the script class we currently provide. This script contains three functions and uses the executable code at the end) to test the number of parameters. This script is truly powerful in the showfiles function, which iterates a list and is constructed after with-cwd), and CALLS write-ln after each element of the list. This list is generated by iterating the specified directory and filtering out files that are executable files.


Listing 4. scripts written in scsh to find all executable files

#!/usr/bin/scsh -s
!#

(define argc
        (length command-line-arguments))

(define (write-ln x)
        (display x) (newline))

(define (showfiles dir)
        (for-each write-ln
                (with-cwd dir
                        (filter file-executable? (directory-files "." #t)))))

(if (not (= argc 1))
        (write-ln "Usage is fae.scsh dir")
        (showfiles (argv 1)))

Conclusion

Many concepts and a large number of interfaces of the early shell have not changed in the next 35 years-this is a strong proof of contributions to the original authors of the early shell. In an industry that is constantly self-transforming, shell has been greatly improved, but has not undergone major changes. Despite some attempts to create a special shell, the derivatives of the Bourne shell are still the main Shells used.

Http://www.ibm.com/developerworks/cn/linux/l-linux-shells/index.html? Ca = drs-




Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.