1. Linux script compiling Basics 1.1 Basic syntax Introduction Start with 1.1.1 Program The following line must start (the first line of the file must start ): #! /Bin/sh Symbol #! The parameter used to tell the system that the program is used to execute the file. In this example, we use/bin/sh to execute the program. When editing a script, you must make it executable if you want to execute it. To make the script executable: Compile chmod + x filename to run it with./filename. 1.1.2 notes During shell programming, a sentence starting with # represents a comment until the end of this line. We sincerely recommend that you use annotations in your program. If you have used annotations, you can understand the functions of the script in a short time even if the script is not used for a long time. And working principles. 1.1.3 Variables In otherProgramming LanguageYou must use the variable. In shell programming, all variables are composed of strings, and you do not need . To assign a value to a variable, you can write as follows: #! /Bin/sh # Assign values to variables: A = "Hello World" # Print the content of variable: Echo "A is :" Echo $ Sometimes the variable name is easily confused with other words, such: Num = 2 Echo "this is the $ numnd" This does not print "this is the 2nd", but only prints "this is the", because shell will search for the value of the variable numnd, But this variable has no value. We can use curly braces to tell shell that we want to print the num variable: Num = 2 Echo "this is the $ {num} Nd" This will print: This is the 2nd 1.1.4 Environment Variables Variables processed by the Export keyword are called environment variables. We will not discuss the environment variables, because normally we only log on Use environment variables in the script. 1.1.5 shell command and Process Control Three types of commands can be used in shell scripts: 1) Unix command: Although any Unix command can be used in shell scripts, some more common commands are used. These commands are usually used For file and text operations. Common command syntax and functions Echo "some text": print the text on the screen Ls: file list WC-l filewc-W filewc-C file: calculate the number of file lines. Calculate the number of words in the file. Calculate the number of characters in the file. CP sourcefile destfile: file copy MV oldname newname: rename a file or move a file RM file: delete an object Grep 'pattern' file: searches for strings in a file, for example, grep 'searchstring' file.txt. Cut-B colnum file: specify the content range of the file to be displayed, and output them to the standard output device, such as: Output Cut-b5-9 file.txt, which contains 5th to 9th characters per line, must not be confused with Cat commands, These are two completely different commands. Cat file.txt: output file content to the standard output device (screen) File somefile: get the file type Read var: prompt the user to input and assign the input value to the variable. Sort file.txt: sorts the rows in the file.txt file. Uniq: Delete the columns in a text file, for example, sort file.txt | uniq Expr: perform mathematical operations example: Add 2 and 3 expr 2 "+" 3 Find: search for a file. For example, search for find.-Name filename-print based on the file name. Tee: outputs data to the standard output device (screen) and files such as: somecommand | tee OUTFILE Basename file: returns a file name that does not contain a path, for example, basename/bin/tux. Dirname file: the path of the returned file. For example, dirname/bin/tux will return/bin. Head file: prints the first few lines of a text file. Tail file: number of rows at the end of a text file Sed: SED is a basic search replacement program. You can read text from standard input (such as command pipeline) and The result is output to the standard output (screen ). This command uses a regular expression (see references) for search. Do not confuse with wildcards in shell. For example, replace linuxfocus Linuxfocus: CAT text. File | SED's/linuxfocus/'> newtext. File Awk: awk is used to extract fields from text files. By default, the field delimiter is a space. You can use-F to specify other separators. Cat file.txt | awk-F, '{print $1 "," $3}', which is used here as a field delimiter and printed at the same time The first and third fields. If the file contains the following content: Adam Bor, 34, indiakerry Miller, 22, USA Command output result: Adam Bor, indiakerry Miller, USA 2) concept: pipelines, redirection, and backtick These are not system commands, but they are really important. The pipeline (|) uses the output of a command as the input of another command. Grep "hello" file.txt | WC-l Search for a row containing "hello" in file.txt and calculate the number of rows. Here, the grep command output serves as the WC command input. Of course, you can use multiple commands. Redirection: output the command result to a file instead of a standard output (screen ). > Write the file and overwrite the old file > Add it to the end of the file to retain the content of the old file. Backlash You can use a backslash to output a command as a command line parameter of another command. Command: Find.-mtime-1-type F-print Used to search for files modified in the past 24 hours (-mtime-2 indicates the past 48 hours. If you You can use the following script to pack all the searched files: #! /Bin/sh # The ticks are backticks (') not normal quotes ('): Tar-zcvf lastmod.tar.gz 'Find.-mtime-1-type F-print' 3) Process Control 1. If If the expression "if" is true, the part after then is executed: If...; then .... Elif...; then .... Else .... Fi In most cases, you can use test commands to test the conditions. For example, you can compare strings and determine files. Whether it exists and whether it is readable... "[]" Is usually used to represent a conditional test. Note that spaces are important. Make sure that the square brackets have spaces. [-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. Directly execute the following script: #! /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 compared it with/bin/bash. Shortcut Operators If you are familiar with the C language, you may like the following expressions: [-F "/etc/shadow"] & Echo "this computer uses shadow passwors" Here & is a shortcut operator. If the expression on the left is true, execute the Statement on the right. You can also think of it as a logical operation. In the preceding example, if the/etc/shadow file exists Print "this computer uses shadow passwors ". Similarly, the operation (|) is also used in shell programming. Available. Here is an 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, the "from" line in the file is printed. If not Or the operation takes effect. Print the error message and exit the script. There is a problem here, that is, we must have two commands: -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. General functions will be mentioned below. We can use the if expression to do anything without the sum or operator, but it is much more convenient to use the sum or operator. 2. Case case: The expression can be used to match a given string, not a number. case... in ...) do something here; esac let's take a look at an example. The file command can identify the file type of a given file, for example: 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 used this to write a script called smartzip, which can automatically decompress Bzip2, gzip and zip compressed files: #! /Bin/sh FTYPE = 'file "$1" ' 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 we use a special variable $1 here. The variable contains the first parameter value passed to the program. that is, when we run: smartzip articles.zip $1 is the string articles.zip 3. selsect The Select expression is a bash extension application, especially for interactive use. You can select from a group of different values. Select VaR in...; do Break Done ... Now $ VaR can be used .... The following is an 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" The following is the result of running the script: What is your favorite OS? 1) Linux 2) GNU Hurd 3) Free BSD 4) Other #? 1 You have selected Linux 4. Loop loop expression: while...; DO ... done while-loop runs until the expression test is true. Will run while the expression that we test for is true. the keyword "break" is used to jump out of the loop. The keyword "continue" is used to directly jump to the next loop without executing the remaining part. the for-loop expression is used to view a string list (strings are separated by spaces) and then assigned to a variable: for VAR in ....; DO .... done In the following example, ABC is printed to the screen: #! /Bin/sh for VAR in a B C; DO echo "Var is $ Var" done The following is a more useful script showrpm. Its function is to print 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 $ * appears. Contains all 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. 5. 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 put the wildcard (For example, *) Replace the variable with the variable value with the appropriate file name. You can use Quotation marks: Let's look at an example. Suppose there are some files in the current directory, two JPG files, mail.jpg and tux.jpg. 1.2 compile shell scripts # Ch #! /Bin/sh mod + x filename Cho *. jpg is slow. Why ?. /Filename to execute your script. This will print the result of "mail.jpg tux.jpg. Quotation marks (single quotation marks and double quotation marks) will prevent such wildcard extension: #! /Bin/sh Echo "*. jpg" Echo '*. jpg' This will print "*. jpg" twice. Single quotes are stricter. It can prevent any variable extension. 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 Finally, there is also a method to prevent this extension, that is, to use the Escape Character -- reverse oblique ROD: Echo *. jpg Echo $ Shell This will output: *. Jpg $ Shell 6. Here documents When you want to pass several lines of text to a command, here documents) A good method. It is very useful to write a helpful text for each script. If we have the here documents You do not need to use the echo function to output a row. A "Here document" starts with <, followed by a string, this string It must also appear at the end of the here document. The following is an example. In this example, we rename multiple files and Print help with 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' 'replace '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 is a complex example. Let's discuss it in detail. The first if expression determines that the input command line parameter is No less than 3 (special variable $ # indicates the number of included parameters ). If the number of input parameters is less than 3, the text will be passed. Run the cat command and print it on the screen. Print the help text and exit the program. If you enter parameters If the value is greater than or equal to three, the first parameter is assigned to the variable old, and the second parameter is assigned to the variable new. Next, I You can use the shift command to delete the first and second parameters from the parameter list, so that the original third parameter becomes a parameter. The first parameter of the number 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, we can achieve our goal: Get the old file name and the new File Name. Use the MV command to rename the file. 4) Functions If you write a slightly more complex program, you may find that the same Code , And you will also find it much easier if we use a function. A function looks like this: Functionname () { # Inside the body $1 is the first argument given to the Function #$2 the second... Body } You must declare the function at the beginning of each program. The following is a script named xtitlebar. You can use this script to change the name of the terminal window. Here we use a function called help. As you can see, this defined function is used twice. #! /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 you) use and understand scripts. Command Line Parameters We have seen Special variables such as $ * and $1, $2... $9. These special variables include The parameter entered by the row. 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 ( For example, file name ). There are many ways to analyze input parameters, but the following example using the case expression is 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 as follows: Extends parser-l Hello-f ---somefile1 somefile2 The returned result is: 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. Compare with the case expression. If the expression matches, set a variable and remove this parameter. According to the Conventions of Unix systems, First, enter a parameter that contains the minus sign. Part 1 instances Now let's discuss the general steps for writing a script. Any excellent script should have help and input parameters. And write a pseudo script (Framework. Sh) that contains the framework structure required by most scripts, which is a very good idea. At this time, when writing a new script, we only need to execute the Copy command: CP framework. Sh myscript Then insert your own function. Let's look at two more examples: 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 < B2H -- convert binary to decimal Usage: B2H [-H] binarynum Options:-H help text Example: B2H 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 () {< br> # 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 '< BR> # Now cut all but the last CHAR: rval = 'echo-n "$1" | cut-B 0-$ {numofcharminus1} ' }< br> 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" TheAlgorithmIs the use of decimal and binary value (, 16,...), such as binary "10" Can Convert 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, Then, use the cut command to extract the last character. The Chop function removes the last character. File loop Program Maybe you want to save all emails to one of the people in a file, but after a few months In the future, this file may become so large that the access speed to this file may be slowed down. The following script rotatefile This problem can be solved. This script can rename the email storage file (assuming outmail) to outmail.1, For outmail.1, it becomes 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 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 the user provides a file name, we perform a 9-1 loop. File 9 is named 10, file 8 is renamed to 9, and so on. After the loop is completed, we name the original file as file 1 and create an empty file with the same name as the original file. Debugging The simplest debugging command is the echo command. You can use echo to print any variable value in any suspected error. This is why most shell Programmers spend 80% of their time debugging programs. The benefit of a shell program is that it does not need to be re-compiled, and it does not take much time to insert an echo command. Shell also has a real debugging mode. If an error occurs in the script "strangescript", you can debug it as follows: Sh-x strangescript This will execute the script and display the values of all variables. Shell also has a mode that only checks the syntax without executing the script. It can be used as follows: Sh-N your_script This will return all syntax errors. |