How to write shell scripts

xiaoxiao2021-03-06  43

Summary: This article combines a large number of examples to explain how to write a shell script.

Why do shell programming

In the Linux system, although there are a wide variety of graphical interface tools, the shell is still a very flexible tool. Shell is not only a collection of commands, but also a great programming language. You can use shell to automate a large number of tasks, Shell is particularly good at system management tasks, especially for more important tasks that are more important, maintainability, and portability.

Below, let's take a look at how shell works:

Create a script

There are many different shells in Linux, but usually we use Bash (Bash Again Shell) for shell programming, because Bash is free and easy to use. So the scripts provided in this article are bash (but in most cases, these scripts can also run in Bash's big sister, Bourne Shell).

Like other languages, we use any of the text editor, such as Nedit, Kedit, Emacs, VI

Wait, write our shell programs.

The program must start with the following row (must be in the first line of the file):

#! / bin / sh

Symbol #! It is used to tell the system that the parameters behind it are used to execute the file. In this example we use / bin / sh to execute the program.

When editing the script, if you want to execute this script, you must also make it executable.

To make the script executable:

CHMOD X FileName

Then you can perform your script by entering: ./filename.

Comment

When the shell programming is performed, the sentence is indicated by the sentence until the end of this line. We sincerely recommend that you use comments in the program. If you use a comment, even if you don't use this script, you can understand the role and working principle of this script in a short period of time.

variable

You must use a variable in other programming languages. In the shell program, all variables are composed of strings and you do not need to declare variables. To assign a variable, you can write this:

Variable name = value

Removing the variable value can add a dollar sign ($) in front of the variable:

#! / bin / sh # Assignment assignments: a = "Hello World" # Now print variable A content: echo "a is:" Echo $ A

Enter the above content in your editor and save it as a file first. After executing CHMOD X First

Make it executable and finally entered ./first executes the script.

This script will output:

A is: Hello World

Sometimes the variable name is easy to confuse with other words, such as:

Num = 2echo "this is the $ numnd"

This will not print "this is the 2nd", but only print "this is the", because the shell will go to search the variable Numnd value, but there is no value when this variable is. You can use the curly brackets to tell Shell We want to print NUM variables:

Num = 2echo "this is the $ {num} nd"

This will print: this is the 2nd

Many variables are automatically set by the system, which will be discussed when these variables are used later.

If you need to process mathematical expressions, you need to use programs such as EXPR (see below).

In addition to the general SHELL variables only in the program, there are environment variables. Variables processed by the export keyword are called environment variables. We don't discuss environment variables because usually use environment variables only in the login script. Shell command and process control

The three types of commands can be used in the shell script:

1) UNIX command:

Although any UNIX command can be used in the shell script, it is still a relatively more common command. These commands are usually used for files and text operations.

Common command syntax and function

Echo "Some Text": Print the text content on the screen

Ls: file list

Wc -l filewc -w filewc -c file: calculates the number of characters in the number of words in the file calculation file

CP Sourcefile Destfile: File Copy

MV OldName NewName: Rename file or mobile file

RM File: Delete files

GREP 'PATTERN' FILE: Search strings in the file such as: grep 'searchString' file.txt

Cut -b colnum file: Specify the scope of the file you want to display, and output them to standard output devices such as: Output Each line of the 5th to nine characters cut -b5-9 file.txt must not confuse with the CAT command This is two completely different orders

CAT file.txt: Output file content to standard output device (screen)

File Somefile: get file type

Read var: prompt user input and assign the input to the variable

Sort file.txt: Sort by rows in file.txt files

UNIQ: Deleting the rows of text files such as Sort File.txt | Uniq

EXPR: Mathematical operations EXAMPLE: Add 2 and 3EXPR 2 " " 3

Find: Search files, such as: Search for Find. -name FileName -Print according to the file name

TEE: Output data to standard output devices (screens) and files such as: SomeCommand | Tee Outfile

BaseName File: Returns a file name that does not contain the path, such as: BaseName / Bin / Tux will return TUX

DirName File: Returns the path where the file is located, for example: dirname / bin / tux will return / bin

Head file: Print the text file a few lines

TAIL FILE: Print the end of the text file

Sed: SED is a basic lookup replacement. You can read text from standard inputs (such as command pipes), and output the result to the standard output (screen). This command is searched using a regular expression (see). Don't confuse the wildcards in the shell. For example: replace LinuxFocus for Linuxfocus: cat text.file | Sed 's / linuxfocus / linuxfocus /'> NewText.file

AWK: AWK is used to extract fields from a text file. By default, the field split is a space, you can use -f to specify other splites. Cat file.txt | awk -f, '{print $ 1, "$ 3}" We use, as a field split, and print one and the third field. If the file is as follows: Adam Bor, 34, Indiakerry Miller, 22, USA command output is: Adam Bor, Indiakerry Miller, USA

2) Concept: Pipe, Redirection and Backtick

These are not system commands, but they are really important. The pipe (|) uses the output of a command as the input of another command.

GREP "Hello" file.txt | wc -l

Searching in file.txt and contains rows with "Hello" and calculates the number of rows.

The output of the grep command here as the input of the WC command. Of course you can use multiple commands.

Redirection: Output the result of the command to the file instead of the standard output (screen).

> Write files and overwrites old files

>> Add to the end of the file, keep the old file content.

Short short slanting

Using the short-short slash can use the output of a command as a command line argument for another command.

command:

Find. -mtime -1 -Type F -PRINT

Used to find files that have been modified within the last 24 hours (-mtime -2 indicating the past 48 hours). If you want to make all the files you find a package, you can use the following script:

#! / bin / sh # The Ticks Are Backthericks (`) NOT NORMAL quotes ('): tar -zcvf lastmod.tar.gz` Find. -mtime -1 -type f -print`

3) Process control

"IF" expression If the condition is true, the part is executed behind:

IF ....; the .... elif ....; the .... else ....

In most cases, the test command can be used to test the condition. For example, you can compare the string, determine if the file exists and whether it is readable, etc.

Usually "[]" is used to represent the condition test. Note that the space here is important. To ensure the space of square brackets.

[-f "somefile"]: Judging whether it is a file [-x "/ bin / ls"]: Judgment / bin / LS exists and has executable permissions [-n "$ var"]: Determine if the $ VAR variable is Value ["$ a" = "$ b"]: Judging whether $ A and $ B are equal

Performing Man Test You can view all test expressions that can be compared and determined.

Perform the following script directly:

#! / bin / shif ["$ shell" = "/ bin / bash"]; the echo "Your login shell is the bash (bourne again shell)" Else Echo "Your Login Shell Is Not Bash But $ Shell" Fi

Variable $ shell contains the name of the login shell, and we compare it with / bin / bash.

/ ***************************************** /

Quick operator

Friends who are familiar with C language may like the following expressions:

[-f "/ etc / shadow" && echo "this Computer Uses Shadow PassWors"

Here && is a shortcut, if the expression on the left is true, perform the statement on the right. You can also think that it is a logical operation. In the above example, if the / etc / shadow file exists, "this Computer Uses Shadow PassWors" is printed. Also or operate (||) is also available in shell programming. Here is an example:

#! / bin / shmailfolder = / var / spool / mail / james [-r "$ mailfolder"] '' {echo "can not read $ mailfolder"; EXIT 1;} echo "$ mailfolder Has mail from:" grep " ^ "$ Mailfolder This script first determines whether the MailFolder is readable. If readable, print "from" one line in the file. If you do not read or operate, the script exits after the error message is printed. There is a problem here, that is, we must have two commands:

- Print error message

-exit the program

We put two commands together as a command as a command in the form of anonymous function as an anonymous function. The general function will be mentioned below.

Don't use and or operate, we can also use IF expressions, but use or operators will be more convenient.

The CASE expression can be used to match a given string instead of a number.

Case ... in ...) Do Something Here ;; ESAC

Let us look at an example. File commands can identify file types of a given file, such as:

File Lf.gz

This will return:

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 called Smartzip that automatically extracts the compressed file of BZIP2, Gzip, and Zip types:

#! / bin / shftype = `file" $ 1 "` case "$ ftype" in "$ 1: zip archive" *) unzip "$ 1" ;; $ 1: gzip compressed "*) Gunzip" $ 1 ";; $ 1: BUNZIP2 "*) Bunzip2" $ 1 ";; *) Error" File $ 1 can not be uncompressed with smartzip ";; ESAC

You may notice that we use a special variable with $ 1 here. This variable contains the first parameter value passed to the program. That is, when we run:

Smartzip Articles.zip $ 1 is string articles.zip

SELECT expression is an extension application of Bash, especially in interactive use. Users can choose from a set of different values.

SELECT VAR IN .... DO BREAKDONE .... NOW $ VAR CAN BE Used .... Below is an example: #! / bin / shecho "What is your favorite OS?" Select Var in "Linux" GNU Hurd "" Free BSD "" Other "; Do Breakdoneecho" You Have SELECTED $ VAR "

Here is the result of this script run:

What is your favorite OS? 1) Linux2) Gnu Hurd3) Free BSD4) Other #? 1you Have SELECTED Linux

You can also use the following LOOP expression in the shell:

While ...; do .... done

While-loop will run until the expression test is true. Will Run While The Expression That We Test for Is True. Keyword "BREAK" is used to jump out of the loop. The keyword "continue" is used to directly skip to the next loop directly. For-loop expression View a string list (string space separated) and assign it to a variable:

For var in ....; do .... done

In the following example, the ABC to the screen will be printed separately:

#! / bin / shfor var in a b c; do echo "var is $ var" DONE

Here is a more useful script showrpm, which is 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/*.rpmfor rpmpackage in $ *; do if [-r "$ rpmpackage"]; then echo "=============== $ rpmpackage =============== ====" rpm -qi -p $ rpmpackage else echo "Error: Cannot Read file $ rpmpckage" Fidone

The second special variable is there thereon, which contains all input command line parameter values. If you run ShowrPM OpenSSH.RPM W3M.rpm WebGrep.rpm

At this point $ * contains 3 strings, ie openssh.rpm, w3m.rpm and webgrep.rpm.

quotation marks

The program expands wildcards and variables before passing any parameters to the program. The so-called extension here is that the program will replace the wildcard (such as *) to the appropriate file name, and its variable replaces a variable value. In order to prevent this replacement, you can use quotation marks: Let's take an example, assume some files, two JPG files, mail.jpg, and tux.jpg in the current directory.

#! / bin / shecho * .jpg

This will print the result of "mail.jpg tux.jpg".

Quotation marks (single quotes and dual quotes) will prevent this wildcard extension:

#! / bin / shecho "* .jpg" echo '* .jpg'

This will print "* .jpg" twice.

Single quotes are more stringent. It prevents any variable extensions. Dual quotes can prevent wildcards from expand but allow variables to expand.

#! / bin / shecho $ shellecho "$ shell" echo '$ shell'

The result of the operation is:

/ BIN / BASH / BIN / BASH $ shell

Finally, there is also a way to prevent this extension, that is, use escape characters - anti-screw rod:

echo * .jpGecho $ shell

This will output:

* .jpg $ shellhere Documents

When you want to pass a few lines to a command, Here Documents (Translator Note: There is currently no way to translate the word) a good method. It is useful to write a part of the helpibility for each script. At this time, if we have the four Here Documents, you don't have to use the Echo function to output a row of rows. A "here document" with << starts, after connecting a string, this string must also appear at the end of the Here Document. Here is an example in which we rename multiple files and use Here Documents Print Help: #! / Bin / sh # We Have Less Than 3 Arguments. Print The Help Text: IF [$ # - LT 3]; Thencat

USAGE: REN 'Regexp' 'Replacement' FILES ...

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

Help exit 0fiold = "$ 1" new = "$ 2" # The Shift Command Removes One Argument from the list of # Command Line Arguments.shiftshift # $ * contains now all the files: for file in $ *; do if [-f " $ file "]; then newfile =` Echo "$ file" | SED "S / $ {old} / $ {new} / g" `IF [-f" $ newfile "]; the echo" Error: $ newfile exists Already "Else Echo" Renaming $ File to $ Newfile ... "MV" $ file "" $ newfile "FI FIDONE

This is a complex example. Let us discuss in detail. The first IF expression determines whether the input command line argument is less than 3 (special variable $ # means a number of parameters). If the input parameter is less than 3, the help text is passed to the CAT command, and then print it on the screen by the CAT command. Print help text post-programs exit. If the input parameter is equal to or greater than 3, we assign the first parameter to the variable OLD, and the second parameter assigns the variable New. Next, we use the shift command to remove the first and second parameters from the parameter list, so the original third parameter is the first parameter of the parameter list *. Then we start loop, the command line parameter list is assigned to the Variable $ File by one. Then we determine if the file exists, if there is, search and replace the new file name via the SED command search. Then, the result of the insection of the inside the slash is then assigned to newfile. This way we have achieved our goal: got old file name and new file name. Then use the mv command to rename it.

function

If you have written some slightly complex programs, you will find the same code in several places in a few places, and you will find that if we use a function, it will be much more convenient. A function is this look:

FunctionName () {# inside the body $ 1 is The first argument given to the function # $ 2 The second ... body} You need to declare the function in each program.

Below is a script called Xtitlebar, you can change the name of the terminal window using this script. A function called Help is used here. As you can see, this definition function is used twice.

#! / bin / sh # Vim: set sw = 4 TS = 4 et:

Help () {cat

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" #

Providing help in scripts is a good programming habit, so that other users (and you) use and understand scripts.

Command line parameters

We have seen $ * and $ 1, $ 2 ... $ 9 and other special variables, including the parameters input from the command line from the command line. So far, we only understand some simple command line syntax (such as some mandatory parameters and viewing the -h option). But when writing more complex programs, you may find more custom options. The usual convention is to add a minus sign before all optional parameters, and then add the parameter values ​​(such as file name).

There is a lot of ways to achieve analysis of input parameters, but the following examples use case expressions are a nice way.

#! / bin / shhelp () {cat

While [-n "$ 1"]; DOCASE $ 1 in -H) Help; Shift 1 ;; # function help is caled -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 ;; esacdone

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 this script like this:

cmdparser -l hello -f - -somefile1 somefile2

The result of returning is:

Opt_f is 1OPT_L IS HELLOFIRST ARG IS --SOMEFILE12ND Arg Is Somefile2 How does this script work? The script is first compared in all input command line parameters, comparing the input parameters to the CASE expression, set a variable if the match is matched and the parameter is removed. According to UNIX systems, the first input should be a parameter containing minus.

/ ************************************ / instance

General programming step

Now let's discuss the general steps to write a script. Any excellent script should have help and input parameters. And write a fake script (framework.sh), which contains the framework structure that most scripts need, is a very good idea. At this time, we only need to execute the copy command when writing a new script:

CP Framework.sh Myscript

Then insert your own function.

Let us look at two examples:

Binary to decimal conversion

The script B2D converts the binary number (such as 1101) into the corresponding decimal number. This is also an example of mathematical operation with an expr command:

#! / bin / sh # Vim: set sw = 4 TS = 4 et: Help () {cat

USAGE: B2H [-H] binarynum

Options: -h Help Text

Example: B2H 111010WILL RETURN 58HELP 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 0 - $ {numofcharminus1} `} While [-n" $ 1 "; docase $ 1 in -H) Help; Shift 1 ;; # function help is caled -) Shift; Break ;; # end of options - *) error "error: no such option $ 1. -H for help" ;; *) Break ; esacdone

# THE main program = 0weight = 1 # One Arg Must Be Given: [-z "$ 1"] && helpbinnum = "$ 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 algorithm used by this script is to use decimal and binary value (1, 2, 4, 8, 16, ..), such as binary "10" can be converted into Ten-based:

0 * 1 1 * 2 = 2

In order to get a single binary number, we use the lastchar function. This function uses the WC-C calculating the number of characters and then uses the CUT command to take out a character. The function of the CHOP function is to remove the last character.

File cycle program

Perhaps you want to save all sent messages to one of the people in a file, but after a few months, this file may become great to make the accesses for the file slow down. The following script RotateFile can solve this problem. This script can rename the mail save file (assuming to Outmail) is Outmail.1, and it has become Outmail.2, etc. for Outmail.1, etc. ...

#! / bin / sh # Vim: set sw = 4 TS = 4 et: Ver = "0.1" Help () {cat

Options: -h Help Text

Example: RotateFile Outthis Will E.g Rename out.2 to out.3, out.1 to out.2, out to out.1and create an Empty Out-file

THE MAX NUMBER IS 10

Version $ VERHELP EXIT 0}

Error () {echo "$ 1" exit 1} while [-n "$ 1"]; DOCASE $ 1 in -h) Help; Shift 1 ;; -) Break ;; - *) Error: No Such Option $ 1. -h for help "; exit 1 ;; *) Break ;; esacdone

# INPUT CHECK: IF [-z "$ 1"]; ThenError "Error: You Must Specify A File, Use -h for Help" FIFILEN = "$ 1" # rename any .1, .2 etc File: for n in 9 8 7 6 5 4 3 2 1; Do IF [-f "$ filen. $ N"]; The P = `expr $ N 1` Echo" MV $ Filen. $ N $ filen. $ P "MV $ Filen. $ p filen. $ p fidone # rename The Original File: IF [$ filen "]; THEN Echo" MV $ Filen $ Filen.1 "MV $ Filen $ FILEN.1FIECHO TOUCH $ Filentouch $ Filen

How is this script work? After the user provides a file name, we will perform a cycle of 9 to 1. The file 9 is named 10, and the file 8 is renamed 9 and so on. After the loop is complete, we name the original file to file 1 to establish a empty file with the same name as the original file.

debugging

The easiest debug command is of course using an echo command. You can print any variable values ​​using Echo in any place where you doubt. This is also the cause of 80% of the time to debug the procedure. The advantage of the shell program does not need to recompile, and insert an echo command does not need much time.

The shell also has a real debug mode. If there is an error in the script "STRANGEScript", you can debug this:

SH -X StrangeScript

This will execute the script and display the value of all variables.

There is still a mode that doesn't need to perform scripts just check the syntax. It can be used like this:

sh -n your_script

This will return all syntax errors.

We hope that you can start writing your own shell script, I hope you have fun.

转载请注明原文地址:https://www.9cbs.com/read-54177.html

New Post(0)