Linux Shell programming Basics

Source: Internet
Author: User
Tags binary to decimal case statement chop echo command file copy

In Linux, you can specify an alias for an alias command: in Linux, if the command is too long and does not conform to the user's habits, you can specify an alias for it. Although you can create a "Link" for a command to solve the problem of long file names, the link is powerless for commands with command line parameters. The alias can solve all such problems. Just give some examples:
Alias L = 'LS-l'; use L instead of the LS-l command (similar l commands are available in XENIX)
Alias CD... = 'CD... '; replacing the CD... command with CD... (it helps a lot for people who use CD... in DOS)
Alias MD = 'mkdir'; replace mkdir with MD (for DOS ...)
Alias C: = 'mount/dev/hda1/mnt/C & CD/mnt/C'; Use the C: Command to replace the command sequence: Install the DOS partition, and then enter.
Generally, we can put the above commands in the. bash_prifle file in our home directory, and use the source. bash_profile command.

Shell programming Basics
We can use any text editor, such as gedit, kedit, emacs, VI, to write shell scripts. It must start with the following line (the first line of the file must be placed ):
#! /Bin/sh
Note: It is best to use "! /Bin/bash "instead of"! /Bin/sh ", if you use TC shell to change to tcsh, others are similar.
Symbol #! The program used to tell the system to execute the script. This example uses/bin/sh. After editing and saving, if you want to execute the script, you must first make it executable:
Chmod + x filename
Enter./filename in the directory where the script is located to run the script.

Directory
• 1 variable assignment and reference
2. Process Control in Shell
O 2.1 If sentence
O 2.2 & | Operator
O 2.3 case statement
O 2.4 SELECT statement
O 2.5 While/For Loop
3. Some special symbols in Shell
O 3.1 quotation marks
• 4 here document
• 5 Functions in Shell
6 shell script example
O 6.1 convert binary to decimal
O 6.2 circular file copy
• 7. Script debugging

In variable assignment and reference shell programming, variables do not need to be declared in advance, and the naming of variable names must follow the following rules:
1 must start with a letter (a-Z, A-Z)
1. There must be no spaces in the middle. You can use underscores (_)
1. punctuation cannot be used.
1. You cannot use keywords in bash (you can use the help command to view reserved keywords)
When you need to assign a value to a variable, you can write it like this:
Variable name = Value

To use the value of a variable, you only need to add $ before the variable name (NOTE: When assigning values to the variable, no space is left on both sides of "=)
#! /Bin/sh
# Assign values to variables:
A = "Hello World" # No space exists on both sides of the equal sign
# Print the value of variable:
Echo "A is:" $

Select your favorite editor, input the above content, save it as the file first, execute chmod + X first to make it executable, and finally input./first to execute the script. The output result is as follows:
A is: Hello World

Sometimes the variable name may be confused with other words, such:
Num = 2
Echo "this is the $ numnd"

The above script does not output "this is the 2nd" but "this is the"; this is because shell will search for the value of the variable numnd, but in fact this variable does not have a value at this time. In this case, we can use curly brackets to tell shell to print the num variable:
Num = 2
Echo "this is the $ {num} Nd"

The output result is: This is the 2nd

Note that the default shell value assignment is a string value assignment. For example:
Var = 1
Var = $ var + 1
Echo $ VaR

The printed result is not 2 but 1 + 1. There are several expressions to achieve the desired effect:
Let "Var + = 1"
Var = $ [$ var + 1]
Var = 'expr $ var + 1' # Pay Attention to the spaces on both sides of the plus sign. Otherwise, the values are assigned as strings.

Note: The first two methods are valid in bash, and errors may occur in Sh.
Let indicates a mathematical operation. expr is used for integer calculation. each item is separated by spaces. $ [] uses the expressions in brackets as mathematical operations to calculate the results before outputting them.
Many variables are automatically set in shell scripts. We will explain them when using these variables. In addition to common shell variables that are valid only in the script, there are also environment variables, that is, those that have been processed by the Export keyword. This article does not discuss environment variables, because they are generally used only in login scripts.

If syntax for Flow Control in Shell
If the "if" expression is true, the part after then is executed:
If...; then
....
Elif...; then
....
Else
....
Fi

In most cases, you can use test commands to test conditions, such as comparing strings, determining whether a file exists, and whether the file is readable ...... Generally, "[]" is used for conditional testing. Note that spaces are important. Make sure that the spaces before and after square brackets are used.
[-F "somefile"]: determines whether it is a file.
[-X "/bin/ls"]: determines whether/bin/ls exists and has the executable permission.
[-N "$ Var"]: determines whether the $ var variable has a value.
["$ A" = "$ B"]: determines whether $ A and $ B are equal.
Run man test to view all types of test expressions that can be compared and judged. The following is a simple if statement:
#! /Bin/sh

If [$ {shell} = "/bin/bash"]; then
Echo "your login shell is the bash (Bourne again shell )"
Else
Echo "your login shell is not bash but $ {shell }"
Fi

The variable $ shell contains the name of the logon shell. We can compare it with/bin/Bash to determine whether the current shell is Bash.

You can also use the test option file name for testing, while the test result uses echo $? To view
Options:-D-F-w-r-X-l
-Eq =-ne-QT>-lt <-Le <=-ge> =

& | Operator
If you are familiar with C, you may like the following expressions:
[-F "/etc/shadow"] & Echo "this computer uses shadow passwords"

& Here is a shortcut operator. If the expression on the left is true, execute the Statement on the right. You can also regard it as a logical operation and operation. The above script indicates that if the/etc/shadow file exists, print "this computer uses shadow passwords ". You can also use or operate (|) in shell programming, for example:
#! /Bin/sh

Mailfolder =/var/spool/mail/James
[-R "$ mailfolder"] | {echo "can not read $ mailfolder"; Exit 1 ;}
Echo "$ mailfolder has mail from :"
Grep "^ From" $ mailfolder

The script first checks whether mailfolder is readable. If it is readable, it prints a line of "from" in the file. If it is not readable or the operation takes effect, print the error message and exit the script. Note that the following two commands must be used:
-Print the error message.
-Exit the program.
We use curly braces to put the two commands together as one command in the form of an anonymous function. The common function will be explained later. We can use the if expression to accomplish anything without the use of and or operators, but the use of and or operators is much more convenient.

Case statement
The case expression can be used to match a given string, not a number (do not confuse switch... case in C ).
Case... in
...) Do something here
;;
...
;;
Esac

The file command can identify the file type of a given file, for example, file lf.gz. The output result is:
Lf.gz: gzip compressed data, deflated, original filename,
Last modified: Mon Aug 27 23:09:18 2001, OS: Unix

We use this to write a script named smartzip, which can automatically decompress Bzip2, Gzip, and zip compressed files:
#! /Bin/sh

FTYPE = 'file "$1" '# Note' and 'is different
Case "$ FTYPE" in
"$1: ZIP Archive "*)
Unzip "$1 ";;
"$1: gzip COMPRESSED "*)
Gunzip "$1 ";;
"$1: Bzip2 COMPRESSED "*)
Bunzip2 "$1 ";;
*) Echo "File $1 can not be uncompressed with smartzip ";;
Esac

You may notice that a special variable $1 is used above, which contains the first parameter value passed to the script. That is, when we run:
Smartzip articles.zip

$1 is the string articles.zip.

Select statement
The Select expression is an extended application of Bash and is good at interactive scenarios. You can select from different values:
Select VaR in...; do
Break;
Done
... Now $ VaR can be used ....

The following is a simple example:
#! /Bin/sh

Echo "What is your favorite OS? "
Select VaR in "Linux" "GNU Hurd" "Free BSD" "other"; do
Break;
Done
Echo "you have selected $ Var"

If the preceding script appears, select: Not found will be #! /Bin/sh #! /Bin/Bash:
What is your favorite OS?
1) Linux
2) GNU Hurd
3) Free BSD
4) Other
#? 1
You have selected Linux

While/For Loop
In shell, you can use the following loop:
While...; do
....
Done

As long as the test expression condition is true, the while loop will continue to run. The keyword "break" is used to jump out of the loop, while the keyword "continue" can skip the rest of the loop and directly jump to the next loop.
The for loop will view a string row table (strings are separated by spaces) and assign it to a variable:
For VaR in...; do
....
Done

The following example prints a B c to the screen:
#! /Bin/sh

For var in a B C; do
Echo "Var is $ Var"
Done

The following is a practical script showrpm. Its function is to print the statistics of some RPM packages:
#! /Bin/sh

# List a Content summary of a number of RPM packages
# Usage: showrpm rpmfile1 rpmfile2...
# Example: showrpm/CDROM/RedHat/RPMS/*. rpm
For rpmpackage in $ *; do
If [-R "$ rpmpackage"]; then
Echo "=====================$ rpmpackage ===================="
Rpm-qi-p $ rpmpackage
Else
Echo "error: cannot read file $ rpmpackage"
Fi
Done

The second special variable $ * is displayed, which contains all the input command line parameter values. If you run showrpm OpenSSH. RPM w3m. RPM webgrep. rpm, $ * contains three strings: OpenSSH. rpm, w3m. rpm, and webgrep. rpm.

Some special symbols in Shell

Quotation marks
Before passing any parameters to a program, the program extends the wildcards and variables. Here, the so-called extension means that the program will replace the wildcard (for example, *) with the appropriate file name, and replace the variable with the variable value. We can use quotation marks to prevent this extension. Let's look at an example. Suppose there are two JPG files in the current directory: mail.jpgand tux.jpg.
#! /Bin/sh

Echo *. jpg

The running result is:
Mail.jpg tux.jpg

Quotation marks (single quotation marks and double quotation marks) can prevent wildcard * extension:
#! /Bin/sh

Echo "*. jpg"
Echo '*. jpg'

The running result is:
*. Jpg
*. Jpg

The single quotation marks are more strict, which can prevent any variable extension. The double quotation marks can prevent wildcard extension but allow variable extension:
#! /Bin/sh

Echo $ Shell
Echo "$ shell"
Echo '$ shell'

The running result is:
/Bin/bash
/Bin/bash
$ Shell

In addition, there is a method to prevent this extension, that is, to use the Escape Character -- backslice bar :\:
Echo \ *. jpg
Echo \ $ Shell

Output result:

*. Jpg
$ Shell

Here document is a good method to pass several lines of text to a command. It is very useful to write a helpful text for each script. If you use here statements, you do not need to use the echo function to output a row. Here document starts with <, followed by a string, which must also appear at the end of the here document. The following is an example. In this example, we rename multiple files and print the help using here documents:
#! /Bin/sh

# We have less than 3 arguments. Print the help text:
If [$ #-lt 3]; then
Cat

Ren -- renames a number of files using sed Regular Expressions usage: Ren 'regexp '''replacement 'files...

Example: rename all *. HTM files in *. html:
Ren 'htm $ ''html' *. htm

Help
Exit 0
Fi
Old = "$1"
New = "$2"
# The shift command removes one argument from the list
# Command line arguments.
Shift
Shift
# $ * Contains now all the files:
For file in $ *; do
If [-F "$ file"]; then
Newfile = 'echo "$ file" | sed "s/$ {old}/$ {New}/g "'
If [-F "$ newfile"]; then
Echo "error: $ newfile exists already"
Else
Echo "Renaming $ file to $ newfile ..."
Mv "$ file" "$ newfile"
Fi
Fi
Done

This example is a bit complicated. We need to spend more time to illustrate it. The first if expression determines whether the number of input command line parameters is smaller than 3 (special variable $ # indicates the number of parameters included ). If the number of input parameters is less than three, the help text is passed to the cat command and then printed on the screen by the cat command. Print the help text and exit the program. If the input parameter is equal to or greater than three, we assign the first parameter to the variable old, and the second parameter to the variable new. Next, we use the shift command to delete the first and second parameters from the parameter list, so that the original third parameter becomes the first parameter in the parameter list $. Then we start the loop. The command line parameter list is assigned to the variable $ file one by one. Then we determine whether the file exists. If yes, we use the SED command to search for and replace the file to generate a new file name. Then, assign the command result in the backslash to newfile. In this way, the old and new file names are obtained. Rename the file using the MV command.

If you have written complex scripts for functions in shell, you may find that the same code may be used in several places. In this case, it is much easier to use functions. The functions are roughly as follows:
Functionname ()
{
# Inside the body $1 is the first argument given to the Function
#$2 the second...
Body
}

You need to declare the function at the beginning of each script.
The following is a script named xtitlebar, which can change the terminal window name. Here we use a function named help, which is used twice in the script:
#! /Bin/sh
# VIM: Set Sw = 4 ts = 4 et:
Help ()
{
Cat Xtitlebar -- change the name of an xterm, gnome-terminal or KDE konsole
Usage: xtitlebar [-H] "string_for_titelbar"
Options:-H help text
Example: xtitlebar "CVS"
Help
Exit 0
}
# In case of error or if-H is given we call the function help:
[-Z "$1"] & Help
["$1" = "-h"] & Help
# Send the escape sequence to change the xterm titelbar:
Echo-e "33] 0; $107"
#
It is a good programming habit to help other users (and themselves) use and understand scripts.

= Command line parameters = We have seen Special variables such as $ * and $1, $2... $9. These special variables include parameters entered by the user from the command line. So far, we have only learned some simple command line syntax (such as some mandatory parameters and the-H option for viewing help ). However, when writing more complex programs, you may find that you need more custom options. The common practice is to add a minus sign before all optional parameters, followed by a parameter value (such as a file name ).
There are many ways to analyze input parameters, but the example using the case expression below is undoubtedly a good method.
#! /Bin/sh

Help ()
{
Cat This is a generic command line parser demo.
Usage example: extends parser-l Hello-f ---somefile1 somefile2
Help
Exit 0
}

While [-n "$1"]; do
Case $1 in
-H) Help; shift 1; # function help is called
-F) opt_f = 1; shift 1; # variable opt_f is set
-L) opt_l = $2; Shift 2; #-l takes an argument-> shift by 2
--) Shift; break; # End of options
-*) Echo "error: no such option $1.-H for help"; Exit 1 ;;
*) Break ;;
Esac
Done

Echo "opt_f is $ opt_f"
Echo "opt_l is $ opt_l"
Echo "first Arg is $1"
Echo "2nd Arg is $2"

You can run the script like this:
Extends parser-l Hello-f ---somefile1 somefile2

The returned results are as follows:
Opt_f is 1
Opt_l is hello
First Arg is-somefile1
2nd Arg is somefile2

How does this script work? The script first loops through all input command line parameters and compares the input parameters with the case expression. If the input parameters match, a variable is set and the parameter is removed. According to the Convention of the UNIX system, the first input should be the parameter containing the minus sign.

Shell script example = general programming procedure = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Now let's discuss the general steps for writing a script. Any excellent script should have help and input parameters. It is a good idea to write a framework script (Framework. Sh) that contains the framework structure required by most scripts. In this way, when writing a new script, you can first execute the following command:
CP framework. Sh myscript

Then insert your own function.
Let's take a look at the two examples below.

Binary to decimal conversion
The script b2d converts the binary number (such as 1101) to the corresponding decimal number. This is also an example of a mathematical operation using the expr command:
#! /Bin/sh
# VIM: Set Sw = 4 ts = 4 et:
Help ()
{
Cat
B2d -- convert binary to decimal

Usage: b2d [-H] binarynum

Options:-H help text

Example: b2d 111010
Will return 58
Help
Exit 0
}

Error ()
{
# Print an error and exit
Echo "$1"
Exit 1
}

Lastchar ()
{
# Return the last character of a string in $ rval
If [-z "$1"]; then
# Empty string
Rval = ""
Return
Fi
# WC puts some space behind the output this is why we need sed:
Numofchar = 'echo-n "$1" | WC-c | SED's // g''
# Now cut out the last char
Rval = 'echo-n "$1" | cut-B $ numofchar'
}

Chop ()
{
# Remove the last character in string and return it in $ rval
If [-z "$1"]; then
# Empty string
Rval = ""
Return
Fi
# WC puts some space behind the output this is why we need sed:
Numofchar = 'echo-n "$1" | WC-c | SED's // g''
If ["$ numofchar" = "1"]; then
# Only One char in string
Rval = ""
Return
Fi
Numofcharminus1 = 'expr $ numofchar "-" 1'
# Now cut all but the last CHAR:
Rval = 'echo-n "$1" | cut-B-$ numofcharminus1'
# The original rval = 'echo-n "$1" | cut-B 0-$ {numofcharminus1} 'encountered an error during running.
# The reason is that cut starts counting from 1. It should be cut-B 1-$ {numofcharminus1}
}

While [-n "$1"]; do
Case $1 in
-H) Help; shift 1; # function help is called
--) Shift; break; # End of options
-*) Error "error: no such option $1.-H for help ";;
*) Break ;;
Esac
Done

# The main program
Sum = 0
Weight = 1
# One Arg must be given:
[-Z "$1"] & Help
Binnum = "$1"
Binnumorig = "$1"

While [-n "$ binnum"]; do
Lastchar "$ binnum"
If ["$ rval" = "1"]; then
Sum = 'expr "$ weight" "+" "$ sum "'
Fi
# Remove the last position in $ binnum
Chop "$ binnum"
Binnum = "$ rval"
Weight = 'expr "$ weight" "*" 2'
Done

Echo "binary $ binnumorig is decimal $ sum"
#

The script uses decimal and binary weights (, 16,...). For example, binary "10" can be converted to decimal:
0*1 + 1*2 = 2

To obtain a single binary number, we use the lastchar function. This function uses WC-C to calculate the number of characters, and then uses the cut command to retrieve the last character. The Chop function removes the last character.

Circular file copy
You may want to do this all the time: Save all sent emails to a file. However, after a few months, the file may become so large that the access speed of the file may be slow. The following script rotatefile can solve this problem. This script can rename the email storage file (assuming outmail) to outmail.1, and the original outmail.1 is changed to outmail.2 and so on...
#! /Bin/sh
# VIM: Set Sw = 4 ts = 4 et:

Ver = "0.1"
Help ()
{
Cat Rotatefile -- rotate the file name
Usage: rotatefile [-H] filename
Options:-H help text
Example: rotatefile out

This will e. g rename out.2 to out.3, out.1 to out.2, out to out.1 [br]
And create an empty out-File

The Max number is 10

Version $ ver
Help

Exit 0
}

Error ()
{
Echo "$1"
Exit 1
}

While [-n "$1"]; do
Case $1 in
-H) Help; shift 1 ;;
--) Break ;;
-*) Echo "error: no such option $1.-H for help"; Exit 1 ;;
*) Break ;;
Esac
Done

# Input check:
If [-z "$1"]; then
Error "error: You must specify a file, use-H for help"
Fi

Filen = "$1"
# Rename any. 1,. 2 etc file:
For N in 9 8 7 6 5 4 3 2 1; do
If [-F "$ filen. $ N"]; then
P = 'expr $ n + 1'
Echo "Mv $ filen. $ N $ filen. $ P"
MV $ filen. $ N $ filen. $ P
Fi
Done

# Rename the original file:
If [-F "$ filen"]; then
Echo "Mv $ filen $ filen.1"
MV $ filen $ filen.1
Fi

Echo touch $ filen
Touch $ filen

How does this script work? After detecting that a file name is provided by the user, perform a loop from 9 to 1. Rename file name. 9 to file name. 10, and rename file name. 8 to file name. 9 ...... And so on. After the loop ends, name the original file as file name. 1 and create an empty file (touch $ filen) with the same name as the original file)

Script debugging
The simplest debugging method is to use the echo command. You can use echo to print variable values wherever possible, which is why most shell Programmers spend 80% of their time debugging. The benefit of shell scripts is that it does not take much time to insert an echo command without recompilation.
Shell also has a real debugging mode. If the script "strangescript" has an error, run the following command to debug it:
Sh-x strangescript

The preceding command executes the script and displays the values of all variables.
Shell also has a mode to check the syntax without executing the script. The command is as follows:
Sh-N your_script

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.