Use Bash to write Linux shell scripts-parameters and sub-shells

Source: Internet
Author: User

To become a flexible tool, a qualified script must provide additional information to describe the role of the script, how it is executed, and where it is executed. Like the command, the script also uses parameters. Switches and parameters increase reusability, reduce costs, and save time.

Positioning parameters

There are three effective methods for Linux scripts to use parameters. First, use the positioning parameter. The script calls the parameter based on the location where the parameter appears in the command line. Because the other two depend on the positioning parameter, we will discuss this first.

Bash variables use "$0" to indicate the script path. It does not need to be a full path name, but it defines the path of the execution script.

$ Printf "% s \ n" "$0"

/Bin/bash

In this example, bash and the start command/bin/bash are used.

When the parameter command combines the basename command, only the Script Name is left, and the rest of the path is deleted.

Some micro-versions use the bash string replacement function to avoid executing externalProgram.

$ Declare-rxscript =$ {0 ##*/}

$ Printf "% s \ n" "$ script"

Bash

You can use "$0" to find the Script Name. After the script is copied and renamed, there will be no potential threats to the wrong file name. Script always keeps the correct Script Name.

The variable "$ #" contains the number of script or shell session parameters. If no parameter exists, $ # is always 0. This parameter does not include the Script Name in $0.

$ Printf "% d \ n" $ #

0

The first nine parameters are placed in the variable $1 ~ $9. (If you want to access nine parameters, use braces ). If the nounset shell option is set, an error occurs when an undefined parameter is accessed, just like an undefined variable name error.

$ Printf "% s \ n" $9

Bash: $9: unboundvariable

Variable "$ @" or "? * "Returns all parameters as a string.

When positioning parameters are used, Bash does not distinguish between parameters and switches. For scripts, each item in the command line is treated as an independent parameter.

Consider the following scripts for listing 9.1:

Listing 9.1 Params. Sh

#! /Bin/bash

#

# Params. sh: apositional parameter demonstration

Printf "there are % dparameter (s) \ n" "$ #"

Printf "The completelist is % s \ n" "$ @"

Printf "The firstparameter is % s \ n" "$1"

Printf "The secondparameter is % s \ n" "$2"

When this script is run with the parameters "-c" and "t2341", it indicates that "$1" is "-c" and "$2" is "t2341 ".

$ Bash parms. Sh-C t2341

There are 2 parameter (s)

The complete list is-ct2341

The first parameter is-C

The second parameter ist2341

Although "$ @" and "$ *" both represent all parameters, the meanings of the parameters are different if they are enclosed in double quotation marks. "$ @" Is split based on the first character of the IFS Variable. If ifs is empty, spaces are used. If ifs is not defined, nothing is used. "$ *" Uses a group of parameters as a separate group.

"$ @" Is always separated by spaces and parameters are considered as separate items, even if they are enclosed in double quotation marks. "$ @" Is usually used to transmit the entire set of switches to another command (for example, ls $ @).

Although positioning parameters are a simple method to traverse switches and parameters, they do not always traverse the parameter list directly in this way. There is a built-in command shift, it can discard the parameter "$1" and forward the following parameters to one place. With the shift command, you can check every parameter, just as they are always the first parameter.

List 9.2 shows a complete example of how to use Shift:

Listing 9.2 param2.sh

#! /Bin/bash

#

# Param2.sh

#

# This script expectsthe switch-C and a company name. -- Help (-h)

# Is also allowed.

Shopt-S-O nounset

Declare-rxscript =$ {0 ##*/}

# Make sure there is atleast one parameter or accessing $1

# Later will be anerror.

If [$ #-EQ 0]; then

Printf "% s \ n" "Type -- Help for help ."

Exit 192

Fi

# Process the parameters

While [$ #-GT 0]; do

Case "$1" in

-H | -- Help) # Show Help

Printf "% s \ n" "Usage: $ script [-H] [-- help]-C companyid"

Exit 0

;;

-C) Shift

If [$ #-EQ 0]; then

Printf "$ Script: $ lineno: % s \ n" "company for-C is missing"> & 2

Exit 192

Fi

Company = "$1"

;;

-*) Printf "$ Script: $ lineno: % s \ n" "Switch $1 not supported"> & 2

Exit 192

;;

*) Printf "$ Script: $ lineno: % s \ n" "extra argument or missing switch"> & 2

Exit 192

;;

Esac

Shift

Done

If [-Z "$ company"]; then

Printf "% s \ n" "companyName missing"> & 2

Exit 192

Fi

# <-- Begin work here

Exit 0

The last related parameter is "$ _" (the dollar sign is underlined ). This switch has two functions: first, when the shell script starts first, it represents the path name of the shell or shell script. Second, after each command is executed, the current command is placed in an environment variable.

$/Bin/date

Fri Jun 29 14:39:58 edt2001

$ Printf "% s \ n" "$ _"

/Bin/date

$ Date

Fri Jun 29 14:40:04 edt2001

$ Printf "% s \ n" "$ _"

Date

You can use "$ _" to repeat the previous parameter.

Getopts command

There are two restrictions on the use of positioning parameters. First, the programmer needs to test the error and create the corresponding message. Second, the shift command will delete all parameters. If you want to access them again in the future, it will be impossible.

To solve these problems. Bash contains a built-in command getopts, which can extract and check the switch without messing up the positioning parameters. Unexpected parameters or missing parameters will be re-identified and reported.

To use getopts, you need to take some preparation work. First, you must set it to a string to use the switch. This variable is usually called optstring. If the switch requires a parameter, add a colon after the switch.

For example, param2.sh requires-H and-C parameters with the company logo, and optstring is "HC :".

A second parameter is required after the option list. This parameter stores the currently used parameters of the shell command.

Each time getopts runs, the second switch of the command line will be checked for inclusion in the parameter list, and the name will be saved in the variable switch. The next parameter to be checked is called opting. If it does not exist, opting is automatically set to 1 before the first script parameter check. If a parameter exists, it is saved in the optarg variable. List 9.3 shows a step. It tests the first parameter of the script.

Listing 9.3 getopts. Sh

#! /Bin/bash

#

# Getopts. Sh

Declare Switch

Getopts "HC:" Switch

Printf "the first switchis switch = % s optarg = % s optind = % s \ n "\

"$ Switch" "$ optarg" "$ optind"

In this script, an unknown switch is assigned a question mark to the switch variable and an error message is displayed.

$ Bash getopts. Sh-H

The first switch isswitch = H optarg = optind = 2

$ Bash getopts. Sh-C a4327

The first switch isswitch = C optarg = a4327 optind = 3

$ Bash gettopts. Sh-

T. sh: Illegal option --

The first switch isswitch =? Optarg = optind = 1

The error message can be hidden by adding a colon Before the first character of the switch list. If ": HC:" is used, the error will not be displayed when "-a" is used, however, this error toggle is stored in the optarg for custom error messages.

$ Bash getopts. Sh-

The first switch isswitch =? Optarg = A optind = 1

You can also create an opterr variable and assign a value of 0 to hide the error message. It will be overwritten by valid switch strings.

The while and case statements are usually used to check the switch. See list 9.4:

Listing 9.4 getopts_demo.sh

# Getopts_demo.sh

#

# This script expectsthe switch-C and a company name. -- Help (-h)

# Is also allowed.

Shopt-S-O nounset

Declare-rxscript =$ {0 ##*/}

Declare-roptstring = "HC :"

Declare Switch

Declare Company

# Make sure there is atleast one parameter

If [$ #-EQ 0]; then

Printf "% s \ n" "Type -- Help for help ."

Exit 192

Fi

# Examine individualoptions

While getopts "$ optstring" switch; do

Case $ switch in

H) printf "% s \ n" "Usage: $ script [-H]-C companyid"

Exit 0

;;

C) Company = "$ optarg"

;;

\?) Exit 192

;;

*) Printf "$ Script: $ lineno: % s \ n" "Script Error: unhandled argument"

Exit 192

;;

Esac

Done

Printf "$ Script: % s \ n" "processing files for $ company ..."

This script is shorterthan the positional

This script is shorter than the script for locating parameters. If getopts fails, the switch statement does not run.

As a specific case, if the getopts command is provided as an additional parameter, getopts can process these variables rather than Script Parameters, so that specific parameters can be used to test the switch.

Getopt command

Although the getopts Command makes Script Programming a little easier, it does not follow the Linux switch standard. In particular, getopts does not allow double minus signs.

To bypass this restriction, Linux contains its own getopt command (note that it is not the previous getopts command ). The function of getopts is similar to that of getopts, but getopt can use the long switch and has some features that getopts does not have. It is used in a completely different way in the script.

Because getopt is an external command, it cannot save the switch in the variable as you want getopts. It cannot output environment variables back to the script.

Similarly, getopt does not know which switches are available for shell scripts, unless the "$ @" command is used to copy the switch to the getopt command. In the end, getopt does not use loops, but uses all parameters as a separate group for one-time processing.

Like getopts, getopt uses the optstring list option. This list can be guided by -- options (-O) to make the system clear the list of switches. The switch can be separated by commas.

The option table passed to the script must be appended to the getopt command using the double minus sign and "$. Double minus signs indicate the end Of the getopt switch and the start of the script.

The script shown in list 9.5 uses the getopt command to complete the same functions as getopts. Sh. Note: The -- name (or-N) switch is used to pass the script name to the getopt command for any error message.

Listing 9.5 getopt. Sh

#! /Bin/bash

#

# Getopt. Sh-ademonstration of getopt

Declare-rxscript =$ {0 ##*/}

Declare result

Result = 'getopt -- name "$ script" -- Options "-h,-C:" -- "$ @"'

Printf "status code = $? Result = \ "$ Result \" \ n"

The following is the result of running the program:

$ Bash getopt. Sh-H

Status Code = 0 result = "-h --"

$ Bash getopt. Sh-C

Getopt. sh: optionrequires an argument -- C

Status Code = 1 result = "--"

$ Bash getopt. Sh-x

Getopt. sh: invalidoption -- X

Status Code = 1 result = "--"

Status Code indicates whether the running result is successful. The status code is 1, indicating that the error message is displayed in getopt. If the status code is 2, the option for the getopt command is incorrect.

Long switch uses -- longoptions (or-l ). It contains a list of Long Options separated by commas. For example, if -- help is allowed, the following syntax is used:

Result = 'getopt -- name "$ script" -- Options "-h,-C:" -- longoptions "help" -- "$ @"'

Getopt also has an enhancement. To specify an option parameter for a long option, add an equal sign and parameter name.

If the double colon is followed by the switch name, it indicates that the switch is an optional parameter rather than required. If the posixly_compatible variable exists, the option table starts with "+. The switch does not allow parameters and the first parameter is used as the end of the switch project.

If the getopt_compatible shell variable exists, the getopt behavior is updated to getopt in the C standard library. In some earlier versions, getopt uses this row as the default value. If you need to check this behavior, use the -- Test (or-T) switch to test its c-language compatibility mode: if it is not in compatibility mode, status code 4 is returned.

What should I do after the getopt command checks the switch? They use the set command to replace the original parameters.

Evalset-"$ result"

Currently, you can use the location parameter check or the built-in getopts check, as shown in list 9.6:

Listing 9.6 getopt_demo.sh

#! /Bin/bash

#

# Getopt_demo.sh

#

# This script expects the switch-C and A companyName. -- Help (-h)

# Is also allowed.

Shopt-S-O nounset

Declare-Rx script =$ {0 ##*/}

Declare-r optstring = "-h,-C :"

Declare Company

Declare result

# Check getopt Mode

Getopt-T

If [$? -Ne 4]; then

Printf "$ Script: % s \ n" "getopt is in compatibilitymode"> & 2

Exit 192

Fi

# Test parameters

Result = 'getopt -- name "$ script" -- Options "$ optstring "\

-- Longoptions "help" \ -- "$ @"'

If [$? -GT 0]; then

Exit 192

Fi

# Replace the parameters with the results of getopt

Eval set -- "$ result"

# Process the parameters

While [$ #-GT 0]; do

Case "$1" in

-H | -- Help) # Show Help

Printf "% s \ n" "Usage: $ script [-H] [-- help]-ccompanyid"

Exit 0

;;

-C) Shift

If [$ #-EQ 0]; then

Printf "$ Script: $ lineno: % s \ n" "company for-C ismissing"> & 2

Exit 192

Fi

Company = "$1"

;;

Esac

Shift

Done

If [-Z "$ company"]; then

Printf "% s \ n" "company name missing"> & 2

Exit 192

Fi

Printf "$ Script: % s \ n" "processing files for $ company ..."

# <-- Begin work here

Exit 0

It seems to have done a lot of work, but when the script has many complicated switches, getopt makes processing parameters easier.

There are also some special switches. The -- Alternative (or-a) switch allows long options to use a separate minus sign as the leading character. This switch violates the Linux protocol. -- Quiet-output (or-q) can not return the processed list to the standard output device after the check. -- Quiet (or-q) indicates that only the status code is returned and no error information is returned, so that you can define your own error information. -- The shell switch uses quotation marks to protect specific characters. For example, space. It may be a special method for the shell to process these characters (only available in the C mode ).

Subshell)

The group of commands mentioned in "Composite commands" in Chapter 7 can be combined with braces. These commands are like being assigned to a group and only return one status code.

$ {Sleep 5; printf "% s \ n" "slept for 5 seconds ";}

Sleep for 5 seconds.

A sub-shell is a set of commands that contain parentheses. Unlike the command group, if the Sub-shell occupies a single line, the last command does not need to use a semicolon.

$ (Sleep 5; printf "% s \ n" "slept for 5 seconds ")

Sleep for 5 seconds.

The sub-shell is like a mixture of command groups and independent scripts enclosed in parentheses. Like a command group, it returns a separate status code. Like an independent shell script, it has its own environment variable.

$ Declare-Ix COUNT = 15

$ {COUNT = 10; printf "% d \ n" "$ count ";}

10

$ Printf "% d \ n" "$ count"

10

$ (COUNT = 20; printf "% d \ n" "$ count ")

20

$ Printf "% d \ n" "$ count"

10

In this example, the Command Group can change the value of the variable count, but in the sub-shell, the value of count is not changed, because the count in the sub-shell is a copy of count in the parent shell, the change of its value does not affect the value of the parent shell.

The sub-shell is usually used for Pipeline Connection. The results of pipeline commands can be redirected to the sub-shell for processing. The data seems to be the standard input of the sub-shell, as shown in list 9.7:

Listing 9.7 subshell. Sh

#! /Bin/bash

#

# Subshell. Sh

#

# Perform some operation to all the files in adirectory

Shopt-S-O nounset

Declare-Rx script =$ {0 ##*/}

Declare-Rx incoming_directory = "Incoming"

Ls-1 "$ incoming_directory" |

(

While read file; do

Printf "$ Script: Processing % s... \ n" "$ file"

# <-- Do something here

Done

)

Printf "done \ n"

Exit 0

The read command reads a row from the standard input at a time. In this instance, it reads a list of files created by the LS command.

$Bashsubshell. Sh

Subshell. sh: Processing alabama_orders.txt...

Subshell. sh: Processing new_york_orders.txt...

Subshell. sh: Processing ohio_orders.txt...

Done

The sub-shell not only inherits environment variables, but for more details, see chapter 14th "execution of functions and scripts ".

Parameter processing greatly increases the flexibility of script usage. Sub-shell commands are an indispensable tool. However, there is still a lot of basic knowledge to grasp when the script is truly perfect. Scripts without job control and signal processing cannot be perfect.

Command reference

Getopt command switch

-- Longoptions (or-l)-list of expected length options separated by commas.

-- Alternative (or-a)-allow long options to use only one single minus sign guide.

-- Quiet-output (or-q)-The check switch does not return the processing result to the standard output.

-- Quiet (or-q)-No error information is displayed for any errors.

-- Shell (or-u)-use quotation marks to protect specific characters.

-- Test (or-T)-used to test the C language compatibility.

Source: http://blog.csdn.net/fox_lht/article/details/7010962

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.