Shell programming structure, shell programming structure

Source: Internet
Author: User
Tags case statement define local

Shell programming structure, shell programming structure


1.1 shell functions

1.2 condition structure: if

1.3 condition structure: case

1.4 condition structure: select

1.5 loop structure:

1.6 loop structure: while

1.7 loop structure:

1.8 exit, break, continue, and return

1.1 shell functions

In shell, a function can be executed as a command. It is a combined structure of a command. You can think of a function as a common command or a small script.

First, we will give several conclusions about the function:

(1) When calling a function directly in bash, if the function name is the same as the command name, the function will be executed first unless the command is used. For example, a function named rm is defined. When entering rm in bash for execution, the rm function is executed, rather than the/bin/rm command, unless "command rm ARGS" is used ".

(2) The function defined by the current shell can only be used by the current shell, and the sub-shell cannot inherit the function definition defined by the parent shell. Unless you use "export-f" to export the function as a global function.

(2) After defining a function, you can use unset-f to remove the function defined in the current shell.

(3). Unless a syntax error occurs or a read-only function with the same name already exists, the exit status code of the function is the exit status code of the Last Command executed in the internal structure of the function.

(4) You can use typeset-f [func_name] or declare-f [func_name] to view the defined function names and corresponding statements of the current shell. If typeset-F or declare-F is used, only the defined function names in the current shell are displayed.

(5) functions can be recursive, and recursive layers can be unlimited.

Syntax structure of the function:

[ function ] name () compound-cmd [redirection]

The preceding syntax defines a function named name. The keyword function is optional. If the function keyword is used, the brackets after name can be omitted. Compound-cmd is the function body, usually surrounded by braces {}. for historical reasons, braces are also keywords, so in order not to produce ambiguity, the function body and braces must be separated by spaces, tabs, and line breaks. You can also specify the optional function redirection function, so that when the function is called, the specified redirection will also be executed.

For example, if you define a function named rm, it will move all the files passed "~ The/backup directory is used to replace the rm command to avoid accidental deletion.

[root@xuexi ~]# function rm () { [ -d ~/rmbackup ] || mkdir ~/rmbackup;/bin/mv -f $@ ~/rmbackup; } &>/dev/null

When calling the rm function, you only need to pass parameters to the rm function. For example, delete/tmp/a. log.

[root@xuexi ~]# rm /tmp/a.log

When you execute a function, the information that may be output by the execution will be redirected to/dev/null.

To allow the function to be used in a sub-shell (such as a script), use the "-f" option of export to export it as a global function. To cancel function export, use the "-n" option of export.

export -f rmexport -n rm

There are several things to explain about shell functions:

(6 ). shell functions also accept location variables $0, $1, $2 ..., however, the location parameter of the function is passed to the function when the function is called, rather than the parameter passed to the script. Therefore, the location variable of the script is different from the location variable of the function, but $0 is consistent with the location variable $0 of the script. In addition, the function also accepts the special variable "$ #". Like the script's "$ #", it also indicates the number of location variables.

(7) The return command can be used inside the function body. When the return command is executed in the function structure, the entire function is exited. Return n indicates the exit status code of the function. If the return status code is not specified, the default status code is 0.

(8). You can use the local command to define local variables in the function struct, for example, local I = 3. Local variables are only visible inside the function (including subfunctions), but not outside the function.

1.2 condition structure: if

Syntax structure:

if test-commands1; then


[elif test-commands2; then






If judgment is very simple.If the return status code is 0, the condition is determined. If the exit status code after the test-commands1 is executed is 0 (not its execution result is 0), Execute the commands1 part of the struct, otherwise if the test-commands2 returns 0, execute the commands2 part of the struct, if not satisfied, execute the commands3 struct.

There are several common test-commands types:

(1). A common command. If the exit status code of the command is 0, the statement body after then is executed. For example:

if echo haha &>/dev/null;then echo go;fi

(2). Test statement. For example, test, [], and [[].

if [ $((1+2)) -eq 3 ];then echo go;fiif [[ "$name" =~ "long" ]];then echo go;fi

(3). Use logical operators, including! , & And |. This feature is mainly provided for Common commands, because the test statement itself supports logical operations. Therefore, two methods are provided for test statements. One is to use logical operators as part of test statements, and the other is to use logical operators as part of if Statements. For example:

if ! id "$name" &>/dev/null;then echo "$name" miss;fiif ! [ 3 -eq 3 ];then echo go;fiif [ ! 3 -eq 3 ];then echo go;fiif [ 3 -eq 3 ] && [ 4 -eq 4 ] ;then echo go;fiif [ 3 -eq 3 -a 4 -eq 4 ];then echo go;fiif [[ 3 -eq 3 && 4 -eq 4 ]];then echo go;fi

Note that using () in an if statement does not change the priority. Instead, the statements in the brackets become the command list and enter the sub-shell to run. Therefore, to change the priority, it must be completed in the test statement.

1.3 condition structure: case

Syntax structure:

case word in

    [ [(] pattern [| pattern]…)

        command-list ;;]



The sysV-style service startup script is the most typical case of using case statements in shell scripts. For example:

case "$1" in    start)        start;;    stop)        stop;;    restart)        restart;;    reload | force-reload)        reload;;    status)        status;;    *)        echo $"Usage: $0 {start|stop|status|restart|reload|force-reload}"        exit 2esac

From the above example, we can see some conclusions:

(1) Each sub-sentence in case ends with a double Semicolon ";", but the double semicolon of the last sub-sentence can be omitted. In fact, in addition to using ";", you can also use "; &" and "; &" at the end of a sentence. They only have different meanings and are not used much, however, for the sake of article integrity, I will explain it later.

(2). The pattern section in each sub-sentence is surrounded by brackets "()", except that the left parenthesis "(" is not necessary.

(3). pattern support for each sub-sentenceWildcard pattern matching (not a regular expression matching mode, so there are only three wildcard metacharacters :"*","? "And [...]), where" | "is used to separate multiple wildcard pattern,It must satisfy one of the pattern values. For example, "([yY] | [yY] [eE] [sS])" indicates that y or Y of a single letter can be entered, you can also enter any case-insensitive format of the three letters "yes.

Set -- y; case "$1" in ([yY] | [yY] [eE] [sS]) echo right; (*) echo wrong; esac

The function of "set -- string_list" is to separate the input string_list with IFS and assign values to the location variables $1, $2, $3 ..., therefore, $1 is assigned the character "y ".

(4). The pattern used in the last clause is "*", indicating that the clause will match the clause if it cannot match all the preceding clauses. Generally, "*" is used in the last clause to avoid case statement mismatch. In shell scripts, this clause is generally used to prompt users how to use the script, the Usage of the script.

(5) Add a conclusion: If none of the modes match, the return status of the command is zero; otherwise, the return value of the last executed command is returned.


If a sub-statement does not end with a double Semicolon ";", but ends with "; &" or "; &", the behavior of the case statement changes.

◇ ";" Indicates that the case statement is exited immediately after the sub-statement is executed.

◇ "; &" Indicates continuing to execute the command part of the next sub-sentence without matching, and determines whether to continue to operate the next sub-sentence based on the ending symbol of the sub-sentence.

◇ "; &" Indicates to continue to backward (not only the next but always backward) matching the sub-sentence. If the match is successful, execute the command part in the corresponding sub-sentence, the ending symbol of the sub-sentence determines whether to continue backward matching.


set -- ycase "$1" in    ([yY]|[yY][eE][sS])        echo yes;&    ([nN]|[nN][oO])        echo no;;    (*)        echo wrong;;esacyesno

In this example, $1 can match the first sub-sentence, but the end symbol of the first sub-sentence is ";&", therefore, the "echo no" of the second sub-sentence is executed without judgment, but the end symbol of the second sub-sentence is ";", so the case statement is exited directly. Therefore, even if $1 cannot match the second clause, "yes" and "no" are output in the case statement ".

set -- ycase "$1" in    ([yY]|[yY][eE][sS])        echo yes;;&    ([nN]|[nN][oO])        echo no;;    (*)        echo wrong;;esacyeswrong

In this example, $1 can match the first sub-sentence, but the end symbol of the first sub-sentence is "; &", so continue to match downward, the second clause does not match successfully until the third clause is matched. Therefore, the "echo wrong" in the third clause is executed ", but the ending symbol of the third sub-sentence is ";", so the case statement is exited directly. Therefore, "yes" and "wrong" are output in the result ".

1.4 condition structure: select

Shell provides the conditional judgment structure for menu selection. For example:

[Root @ xuexi ~] # Select fname in cat dog sheep mouse; do echo your choice: \ "$ REPLY \) $ fname \"; break; done1) cat2) dog3) sheep4) mouse #? 3 # Here select number 3 your choice: "3) sheep" # output the content corresponding to number 3

Syntax structure:

select name [ in word ] ; do cmd_list ; done

Its structure is almost the same as that of the for loop. There are several key points:

(1 ). word after the in keyword is divided according to the IFS Variable. Each item after the split is numbered and output as the menu serial number. If in word is omitted, it is equivalent to "in $ @", that is, the content of the location variable is used as a menu item.

(2 ). after selecting the menu sequence number, the content of the sequence number will be saved to the variable name and the entered content (generally the sequence number value, for example, 3 entered in the above example, but it is not required to enter the serial number value, for example, just enter a few characters) and save it to the special variable REPLY.

(3). After each input is selected, the select statement is reset. If the input menu sequence number exists, the cmd_list statement is re-executed and the variable name is reset. If the break command is not provided, the select statement runs continuously. If the break command is run, the select statement is exited.

The above example is still used: But not break

[Root @ xuexi ~] # Select fname in cat dog sheep mouse; do echo your choice: \ "$ REPLY \) $ fname \"; done 1) cat2) dog3) sheep4) mouse #? 2 your choice: "2) dog "#? Habagou # Enter your choice: "habagou)" # The variable fname is reset to null, and the variable REPLY is assigned the input value habagou #? 2 3 your choice: "2 3 )"#? ^ C # it will not end until the select process is killed

1.5 loop structure:

The for loop shell script is widely used. It has two syntax structures:

Structure 1: for name [[in [word...];] do Everything _list; done

Structure 2: for (expr1; expr2; expr3); do multiple _list; done

Structure 1: expands in word, splits word according to the IFS Variable, and assigns the words to the variable name in sequence. Each value is assigned, and the cyclic body pai_list is executed, then, assign the next word to the variable name until all variables are assigned. If in word is omitted, it is equivalent to "in $ @", that is, the position variable is expanded and assigned to the variable name in turn. NOTE: If some words are enclosed by quotation marks in word, the content enclosed by these quotation marks is divided into one word.

For example:

[root@xuexi ~]# for i in 1 2 3 4;do echo $i;done1234
[root@xuexi ~]# for i in 1 2 "3 4";do echo $i;done123 4

Structure 2: the expr part of the structure only supports mathematical calculation and comparison. Calculate expr1 first, and then judge the return status code of expr2. If it is 0, execute cmd_list, calculate the value of expr3, and judge the status code of expr2. Until the return status code of expr2 is not 0, the loop ends.

For example:

[root@xuexi ~]# for ((i=1;i<=3;++i));do echo $i;done123
[root@xuexi ~]# for ((i=1,j=3;i<=3 && j>=2;++i,--j));do echo $i $j;done1 32 2

1.6 loop structure: while

When using the while LOOP, try to run the condition until it can exit the loop. Otherwise, the loop is infinite. Generally, variables are added to the command body to change the behavior.

Syntax structure:

while test_cmd_list; do cmd_list; done

First, run the command in test_cmd_list. When the status code of the last command in test_cmd_list is 0, mongo_list will be executed once, and then test_cmd_list will be executed again at the beginning of the loop. The loop exits only when the status code of the last test command in test_cmd_list is not 0.

For example, calculate the arithmetic sum between 1 and 10.

[root@xuexi ~]# let i=1,sum=0;while [ $i -le 10 ];do let sum=sum+i;let ++i;done;echo $sum         55

In this example, test_cmd_list has only one command [$ I-le 10], so its status directly determines when the entire loop will exit.

The test_cmd_list can contain multiple commands, but you must make sure that the test command that decides to exit the loop is at the end of the list. Otherwise, the test command enters the wireless loop.

[root@xuexi ~]# let i=1,sum=0;while echo $i;[ $i -le 10 ];do let sum=sum+i;let ++i;done;echo $sum 123456789101155

For the while LOOP, there are two other common statements:

(1) Use a colon ":" or "true" in the. test_cmd_list Section to enable the while to enter an infinite loop.

While:; do # Or "while true; do"



(2 ). use the read command to read the value from the standard input by line and save it to the variable line (since it is a read command, it can be saved to multiple variables). Reading a row is a loop.

Standard input can be either from redirection or from pipelines (essentially or redirection), so there are several common approaches:

Method 1: Use pipelines to transfer content, which is the worst way

Echo "abc xyz" | while read field1 field2 # split by IFS and assign two variables




Statement 2:

while read line



done <<< "abc xyz"

Statement 3: Read content from a file

while read line



done </path/filename

Since the standard input is read, several methods can be derived:

Method 4: while read var; do...; done <(using _list) # Replace with Process

Method 5: exec <filename; while read var; do...; done # change the standard input

Although there are many writing methods, note that they are not equivalent. The pipeline symbol is used in method 1, which enables the while statement to be executed in the sub-shell. This means that the variables, arrays, and functions set in the while statement do not take effect outside the loop.For example:

#!/bin/bashecho "abc xyz" | while read linedo    new_var=$linedoneecho the variable new_var is null: $new_var?

$ New_var is null in the script execution result.

You can use any one of the other statements to continue obtaining the while environment outside the while loop. For example, use the here string in statement 2 to replace Statement 1:

#!/bin/bashwhile read linedo    new_var=$linedone <<< "abc xyz"echo the variable new_var is null: $new_var?

As a result, we can find that the most widely used Writing Method in the above five writing methods is actually the worst. If you do not pay attention to the writing method, while is running in the subshell, you may always wonder why the set variables or arrays in the while LOOP become null at the end of the loop.




1.7 loop structure:

The until and while loops are basically the same. The difference is only the meaning of test_cmd_list.

Syntax structure:

until test_cmd_list; do cmd_list; done

First, judge the last command in test_cmd_list. If the status code is not 0, execute cmd_list once, and then run test_cmd_list again at the beginning of the loop, the loop does not exit until the last command status code of test_cmd_list is 0.

Different from while, the last command test_cmd_list exits directly when the exit condition is met, that is, the loop exits at the last command test_cmd_list.

For example:

[root@xuexi ~]# i=5;until echo haha;[ "$i" -eq 0 ];do let --i;echo $i;donehaha4haha3haha2haha1haha0haha

1.8 exit, break, continue, and return

Exit [n]: exit the current shell. If the script is used, the entire script (sub-shell) is exited ). The value n indicates the exit status code.

Break [n]: exits the entire loop, including for, while, until, and select statements. The value n indicates the exit loop level.

Continue [n]: exit the current loop and enter the next loop. N indicates that the nth cycle is continued.

Return [n]: exit the entire function. N indicates the exit status code of the function.


Back to series article outline:

Reprinted please indicate the source: Success!

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: 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.