Shell Script Authoring Tutorial

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


Create a script
There are many different shells in Linux, but usually we use Bash (Bourne again shell) for Shell programming because bash is free and easy to use. So the script I've provided in this article is all about using bash (but in most cases these scripts can also be run in Bash's eldest sister, Bourne Shell).
Like other languages, we use any kind of text editor, such as Nedit, Kedit, Emacs, VI
And so on to write our shell program.
The program must start with the following line (must be in the first line of the file):
#!/bin/sh
The symbol #! is used to tell the system that the parameter behind it is the program used to execute the file. In this example we use/BIN/SH to execute the program.
When you edit a script, you must also make it executable if you want to execute the script.
To make the script executable:
chmod +x filename
You can then execute your script by entering:./filename.
Comments
In shell programming, a sentence that begins with # represents a comment until the end of the line. We sincerely recommend that you use annotations in your programs. If you use annotations, you can understand the script's function and how it works in a very short time, even if you haven't used the script for quite a long period of time.
Variable
In other programming languages, you must use variables. In shell programming, all variables are made up of strings, and you do not need to declare the variables. To assign a value to a variable, you can write:
Variable name = value
You can add a dollar sign ($) in front of the variable to remove the variable value:
#!/bin/sh
#Assign a variable
A= "Hello World"
# now print the contents of variable a:
echo "A is:"
Echo $a
Enter the above in your editor and save it as a file first. Then execute chmod +x First
Make it executable, and last enter./first executes the script.
The script will output:
A is:
Hello World
Sometimes variable names are easily confused with other words, such as:
num=2
echo "The $numnd"
This does not print out "This is the 2nd" and simply prints "This is the" because the shell will go to search for the value of the variable numnd, but this variable has no value. You can use curly braces to tell the shell that we're printing num variables:
num=2
echo "This is the ${num}nd"
This will print: This is the 2nd
There are many variables that are automatically set by the system, which are discussed later when these variables are used.
If you need to work with mathematical expressions, you need to use programs such as expr (see below).
In addition to the usual shell variables that are only valid within the program, there are environment variables. Variables processed by the EXPORT keyword are called environment variables. We do not discuss environment variables, because environment variables are typically used only in logon scripts.
Shell command and Process Control
There are three types of commands that can be used in shell scripts:
1) Unix command:
Although you can use any Unix command in a shell script, there are some relatively common commands. These commands are usually used for file and text operations.
Common command syntax and functions
echo "Some text": Print text content on the screen
LS: File list
Wc–l filewc-w filewc-c File: Count the number of words in the file count the number of characters in the file
CP sourcefile destfile: File copy
MV oldname newname: Renaming files or moving files
RM file: Deleting files
grep ' pattern ' file: Search for strings within a file such as: grep ' searchstring ' file.txt
Cut-b colnum File: Specifies the range of files to display and outputs them to a standard output device such as: Output from 5th to 9th characters per line cut-b5-9 file.txt never be confused with cat commands, this is two completely different commands
Cat file.txt: Output file contents to standard output device (screen)
File somefile: Get the files type
Read Var: Prompts the user for input and assigns the input to the variable
Sort file.txt: Sorting rows in a file.txt file
Uniq: Delete columns that appear in a text file such as: sort File.txt | Uniq
Expr: Perform mathematical operations Example:add 2 and 3expr 2 "+" 3
Find: Search for files like: Search for Find by file name. -name Filename-print
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 a path such as: Basename/bin/tux will return Tux
DirName file: Returns the path of the files such as: Dirname/bin/tux will return/bin
Head file: Print text file at the beginning of a few lines
Tail File: Print text file at the end of a few lines
Sed:sed is a basic find-and-replace program. You can read text from standard input, such as a command pipeline, and output the results to a standard output (screen). the command is searched using a regular expression (see Reference). Do not confuse with wildcard characters in the shell. For example: Replace Linuxfocus with Linuxfocus:cat text.file | Sed ' s/linuxfocus/linuxfocus/' > Newtext.file
The Awk:awk is used to extract fields from a text file. By default, the field separator is a space, and you can use-f to specify additional delimiters. Cat File.txt | Awk-f, ' {print $ ', ' $ i} ' here we use, as field separators, while printing the first and third fields. If the contents of the file are as follows: Adam Bor, Indiakerry Miller, the USA command output is: Adam Bor, Indiakerry Miller, USA
2) Concepts: piping, redirection and Backtick
These are not system commands, but they are really important.
Pipe (|) The output of one command as input to another command.
grep "Hello" file.txt | Wc-l
Searches for a row containing "Hello" in File.txt and calculates its number of rows.
Here the output of the grep command is used as input to the WC command. Of course you can use multiple commands.
Redirect: Outputs the result of the command to a file instead of the standard output (screen).
> Write files and overwrite old files
>> add to the end of the file, preserving the contents of the old file.
Anti-Short Slash
Use a backslash to make the output of one command a command-line argument for another command.
Command:
Find. -mtime-1-type F-print
Used to find files that have been modified in the last 24 hours (-mtime–2 represents the last 48 hours). If you want to hit a package with all the files you find, you can use the following script:
#!/bin/sh
# The Ticks is Backticks (') not normal quotes ('):
TAR-ZCVF lastmod.tar.gz ' Find. -mtime-1-type F-print '
3) Process Control
The "If" expression executes the following part if the condition is true:
If ....; Then
....
Elif ...; Then
....
Else
....
Fi
In most cases, you can use test commands to test the condition. For example, you can compare strings, determine whether the file exists and whether it is readable, etc...
The condition test is usually represented by "[]". Note that the space here is important. The space to ensure the square brackets.
[-F "somefile"]: Determine if it is a file
[-X "/bin/ls"]: Determine if/bin/ls exists and has executable permissions
[-N ' $var]: Determine if the $var variable has a value
["$a" = "$b"]: Determine if $ A and $b are equal
Execute man test to see the types that all test expressions can compare and judge.
Execute the following script directly:
#!/bin/sh
If ["$SHELL" = "/bin/bash"]; Then
echo "Your login shell is the bash (Bourne again shell)"
Else
echo "Your login shell isn't bash but $SHELL"
Fi
The variable $shell contains the name of the login shell, which we compared with/bin/bash.
Shortcut operator
A friend familiar with C might like the following expression:
[-F "/etc/shadow"] && echo "This computer uses Shadow Passwors"
Here && is a shortcut operator that executes the statement on the right if the expression on the left is true. You can also think of it as an operation in a logical operation. The above example prints "This computer uses Shadow Passwors" if the/etc/shadow file exists. Same OR operation (| |) is also available in Shell programming. Here's an example:
#!/bin/sh
Mailfolder=/var/spool/mail/james
[-R "$mailfolder"] "{echo" Can not read $mailfolder "; exit 1;}
echo "$mailfolder have mail from:"
grep "^from" $mailfolder
The script first determines whether the mailfolder is readable. Prints the "from" line in the file if it is readable. If unreadable or the operation takes effect, the script exits after the error message is printed. Here's the problem: we have to have two commands.
-Print error message
-Exit Program
We use curly braces to put two commands together as a command in the form of an anonymous function. The general functions are mentioned below.
Without the and and or operators, we can do anything with an if expression, but using and or operators is much more convenient.
A case expression can be used to match a given string, not a number.
Case ... in
...) do something here;;
Esac
Let's look at an example. The file command can identify the type of files for a given file, such as:
File lf.gz
This will return:
Lf.gz:gzip compressed data, deflated, original filename,
Last Modified:mon 23:09:18 2001, Os:unix
We use this to write a script called Smartzip, which automatically extracts compressed files of bzip2, gzip, and zip types:
#!/bin/sh
Ftype= ' file ' $ "'
Case ' $ftype ' in
"$1:zip Archive" *)
Unzip "$";;
"$1:gzip Compressed" *)
Gunzip "$";;
"$1:bzip2 Compressed" *)
Bunzip2 "$";;
*) Error "File" can not is uncompressed with smartzip ";
Esac
You may notice that we are using a special variable here. The variable contains the first parameter value passed to the program. In other words, when we run:
Smartzip Articles.zip
$ $ is the string articles.zip
The select expression is an extended application of bash and is particularly adept at interactive use. Users can choose from a different set of values.
Select Var in ...; Do
Break
Done
.... Now $var can be used ....
Here is an example:
#!/bin/sh
echo "What's your favourite OS?"
Select Var in "Linux", "Gnu Hurd" "Free BSD" and "other"; Do
Break
Done
echo "You have selected $var"
The following is the result of the script running:
What is your favourite OS?
1) Linux
2) Gnu Hurd
3) Free BSD
4) Other
#? 1
You 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. Would run while the expression, the We test for is true. The keyword "break" is used to jump out of a loop. The keyword "Continue" is used to skip to the next loop without executing the rest of the section.
The For-loop expression looks at a list of strings (strings separated by spaces) and assigns them to a variable:
for Var in ...; Do
....
Done
In the following example, the ABC is printed separately 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, which functions to print some RPM package statistics:
#!/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
There is a second special variable, $*, that contains all the input command-line parameter values. If you run showrpm openssh.rpm w3m.rpm webgrep.rpm
At this point $* contains 3 strings, namely openssh.rpm, w3m.rpm and webgrep.rpm.
Quotes
The program expands wildcard characters and variables before passing any parameters to the program. The so-called extension means that the program replaces the wildcard character (such as *) with the appropriate file name, and the variable is replaced with the variable value. To prevent the program from making this substitution, you can use quotation marks: Let's take a look at an example, assuming there are some files in the current directory, two JPG files, mail.jpg and tux.jpg.

#!/bin/sh
Echo *.jpg
This will print out the results of "mail.jpg tux.jpg".
quotation marks (single and double quotation marks) prevent this wildcard extension:
#!/bin/sh
echo "*.jpg"
Echo ' *.jpg '
This will print "*.jpg" two times.
Single quotes are more restrictive. It prevents any variable expansion. Double quotes prevent wildcard expansion but allow variable expansion.
#!/bin/sh
Echo $SHELL
echo "$SHELL"
Echo ' $SHELL '
The result of the operation is:
/bin/bash
/bin/bash
$SHELL
Finally, there is a way to prevent this extension by using the escape character-the backslash:
Echo *.jpg
Echo $SHELL
This will output:
*.jpg
$SHELL
Here documents
When you want to pass a few lines of text to a command, here documents is a good way to see that the word is suitable for translation. It is useful to write a piece of helpful text for each script, at which point we don't have to use the Echo function to output a row of lines if we have the four. A "Here document" begins with <<, followed by a string, which must also appear at the end of here document. Here is an example where we rename multiple files and use the here documents to print help:
#!/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= "$"
New= "$"
# The SHIFT command removes one argument from the list of
# 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 complicated example. Let's discuss it in detail. The first if expression determines whether the input command-line argument is less than 3 (the special variable $# represents the number of parameters included). If the input parameter is less than 3, the help text is passed to the Cat command, which is then printed on the screen by the cat command. The program exits after printing the help text. If the input parameter is equal to or greater than 3, we assign the first parameter to the variable old and the second parameter to the variable new. Next, we use the shift command to remove the first and second arguments from the argument list, so that the third argument becomes the first parameter of the argument list $*. Then we start the loop, and the command-line argument list is assigned to the variable $file one by one. We then determine if the file exists and, if it exists, it is searched and replaced by the SED command to generate a new file name. The command result in the backslash is then assigned to NewFile. So that we can achieve our goal: to get the old file name and the new filename. Then use the MV command to rename it.
Function
If you write a slightly more complex program, you will find that the same code may be used in several places in the program, and you will find that if we use the function, it will be much easier. This is what a function looks like:
functionname ()
{
# inside the body argument given to the function
# The second ...
Body
}
You need to declare the function at the beginning of each program.

Here is a script called Xtitlebar that you can use to change the name of the terminal window. A function called Help is used here. As you can see, this defined function is used two times.
#!/bin/sh
# Vim:set sw=4 ts=4 et:
Help ()
{
Cat <
Xtitlebar-Change the name of a 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 are given we call the function Help:
[-Z "$"] && Help
["$" = "-H"] && Help
# Send the escape sequence to the xterm Titelbar:
Echo-e "33]0;$107"
#
Providing help in a script is a good programming habit, which makes it easier for other users (and you) to use and understand scripts.
Command-line arguments
We've seen $* and $ $ ... $9 and other special variables that contain the parameters that the user entered from the command line. So far, we've only learned a few simple command-line syntax (such as some mandatory parameters and the-h option for viewing help). But when you're writing more complex programs, you may find that you need more custom options. The usual practice is to add a minus sign before all optional arguments, followed by a parameter value (such as a file name).
There are many ways to analyze input parameters, but the following examples of using case expressions are a good idea.
#!/bin/sh
Help ()
{
Cat <
This was a generic command line parser demo.
USAGE example:cmdparser-l hello-f---somefile1 somefile2
Help
Exit 0
}
While [-N "$"]; Do
Case $ 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 $. -H for Help "; exit 1;;
*) break;;
Esac
Done

echo "Opt_f is $opt _f"
echo "opt_l is $opt _l"
echo "First Arg is $"
echo "2nd Arg is $"
You can run the script this way:
Cmdparser-l hello-f---somefile1 somefile2
The results returned are:
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 the input command-line arguments, compares the input parameters to the case expression, sets a variable if the match, and removes the argument. According to the practice of UNIX systems, the first entry should be a parameter that contains a minus sign.
Instance
General programming steps
Now let's discuss the general steps for writing a script. Any good script should have help and input parameters. and write a pseudo-script (framework.sh), which contains the framework structure that most scripts need, is a very good idea. At this point, we only need to execute the copy command when writing a new script:
CP framework.sh MyScript
And then insert your own function.
Let's take a look at two more examples:
Conversion of binary to decimal
The script b2d converts the binary number (for example, 1101) to the corresponding decimal number. This is also an example of a mathematical operation with 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
would return 58
Help
Exit 0
}
Error ()
{
# Print an error and exit
echo "$"
Exit 1
}
Lastchar ()
{
# return the last character of a string in $rval
If [-Z ']; Then
# empty string
Rval= ""
Return
Fi
# WC puts some space behind the output this is why we need sed:
Numofchar= ' Echo-n ' | wc-c | Sed ' s///g '
# now cut out of the last Char
Rval= ' Echo-n ' | Cut-b $numofchar '
}

Chop ()
{
# Remove the last character in string and return it in $rval
If [-Z ']; Then
# empty string
Rval= ""
Return
Fi
# WC puts some space behind the output this is why we need sed:
Numofchar= ' Echo-n ' | wc-c | Sed ' s///g '
If ["$numofchar" = "1"]; Then
# only one char in string
Rval= ""
Return
Fi
numofcharminus1= ' expr $numofchar '-' 1 '
# now cut all and the last char:
Rval= ' Echo-n ' | Cut-b 0-${numofcharminus1} '
}
While [-N "$"]; Do
Case $ in
-h) Help;shift 1;; # function Help is called
--) Shift;break; # End of options
-*) Error "error:no such option $. -H for help ";;
*) break;;
Esac
Done
# The main program
Sum=0
Weight=1
# One ARG must be given:
[-Z "$"] && Help
Binnum= "$"
Binnumorig= "$"

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 the script is to take advantage of decimal and binary number weights (1,2,4,8,16,..), such as the binary "10" can be converted to decimal:
0 * 1 + 1 * 2 = 2
In order to get a single binary number we are using the Lastchar function. The function uses Wc–c to calculate the number of characters, and then uses the Cut command to remove the end character. The function of the chop function is to remove the last character.
File Recycling Program
Maybe you're one of those people who want to save all the sent messages to a file, but after a few months, the file can become so large that it slows down the file. The following script rotatefile can solve this problem. This script can rename the message to save the file (assuming outmail) is OUTMAIL.1, and 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 would e.g rename out.2 to Out.3 Out.1 to Out.2
and create an empty out-file
The max number is 10
Version $ver
Help
Exit 0
}

Error ()
{
echo "$"
Exit 1
}
While [-N "$"]; Do
Case $ in
-h) Help;shift 1;;
--) break;;
-*) echo "error:no such option $. -H for Help "; exit 1;;
*) break;;
Esac
Done
# input Check:
If [-Z ']; Then
Error "Error:you must specify a file, use-h for help"
Fi
Filen= "$"
# 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 a file name provided by the user, we perform a 9 to 1 loop. File 9 is named 10, file 8 is renamed to 9, and so on. After the loop is complete, we name the original file 1 and create an empty file with the same name as the original file.
Debugging
The simplest debug command, of course, is to use the echo command. You can use Echo to print any variable value in any place where you suspect it is wrong. That's why most shell programmers spend 80% of their time debugging programs. The advantage of a shell program is that it doesn't need to be recompiled, and it doesn't take much time to insert an echo command.
The shell also has a real debug mode. If there is an error in the script "Strangescript", you can debug it this way:
Sh-x Strangescript
This executes the script and displays the values of all variables.
The shell also has a pattern that does not need to execute a script just to check the syntax. This can be used:
Sh-n Your_script
This will return all syntax errors.





Shell Script Authoring Tutorial


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.