Shell:结构化语句

编程

本文介绍了Shell常用的结构化语句。

  • ver: 1.0
  • 博客:https://www.cnblogs.com/Rohn
  • 本文介绍了Shell常用的结构化语句。

目录

  • 数组
    • 获取数组所有元素
    • 获取数组元素个数
    • 数组合并
    • 删除数组元素
    • 实例
  • 选择结构
    • if-else语句
      • 基本格式
      • if-else
      • if-elif-else
    • case-in语句
  • 循环结构
    • while语句
      • 死循环
    • until语句
    • for语句
      • C语言风格的 for 循环
      • for-in循环
    • select-in语句
    • break
    • continue
  • 函数
    • 函数定义
    • 函数调用
    • 函数参数

数组

数组(Array)是若干数据的集合,其中的每一份数据都称为元素(Element)。

Bash只支持一维数组(不支持多维数组),初始化时不需要定义数组大小,理论上可以存放无限量的数据。

与大部分编程语言类似,数组元素的下标由0开始。

Shell数组用括号来表示,元素用"空格"符号分割开。格式如下:

array_name=(ele1  ele2  ele3 ... elen)

Tips:赋值号=两边不能有空格,必须紧挨着数组名和数组元素。

获取数组中的元素要使用下标[],下标可以是一个整数,也可以是一个结果为整数的表达式;当然,下标必须大于等于0。格式如下:

${array_name[index]}

Tips:array_name是数组名,index是下标。

Shell是弱类型的,它并不要求所有数组元素的类型必须相同,例如:

arr=(10 24 "ddd" "ab22" 5)

获取数组所有元素

使用@*可以获取数组中的所有元素,格式如下:

${array_name[*]}

${array_name[@]}

获取数组元素个数

使用#来获取数组元素的个数,格式如下:

${#array_name[@]}

${#array_name[*]}

数组合并

数组合并,就是将两个或两个以上的数组合并成一个个数组,格式如下:

array_new=(${array1[@]}  ${array2[@]}...${arrayn[@]})

array_new=(${array1[*]} ${array2[*]}...${arrayn[*]})

删除数组元素

使用unset关键字来删除数组元素,格式如下:

unset array_name[index]

如果不写下标,则代表删除整个数组所有元素,格式如下:

unset array_name

实例

测试ip是否ping通

#!/usr/bin/env bash

# Author: Rohn

# Version: 1.0

# Create Time: 2020/06/13

# Test network connectivity

arr_num=(3 11 25 32 200)

for i in ${arr_num[*]}; do

ip=192.168.110.${i}

ping -c 1 $ip >/dev/null 2>&1

if [ $? -eq 0 ]; then

echo "${ip} is ok."

else

echo "${ip} is unreachable."

fi

done

选择结构

Shell中的选择结构(分支结构)有两种形式,分别是 if-elsecase-in语句,它们都根据命令的退出状态来判断条件是否成立。

if-else语句

基本格式

基本结构格式:

if condition; then

statement(s)

fi

condition是判断条件,如果condition成立(返回True),那么then后边的语句将会被执行;如果 condition不成立(返回False),那么不会执行任何语句。

Tips:最后必须以fi来闭合,fi就是if 倒过来拼写。

if-else

如果有两个分支,就可以使用if-else语句,格式:

if condition; then

statement1

else

statement2

fi

如果condition成立,那么then后边的 statement1语句将会被执行;否则,执行else 后边的statement2语句。

if-elif-else

当分支比较多时,可以使用if-elif-else 结构,格式:

if condition1; then

statement1

elif condition2;then

statement2

...

else

statementn

fi

Tips:ifelif后边都得跟着then

语句的执行逻辑:

  • 如果condition1成立,那么执行statement1,如果不成立,则执行elif语句;
  • 如果elif语句不成立,则执行else语句;

case-in语句

当分支较多,且判断条件比较简单时,推荐使用case-in语句。格式如下:

case expression in

pattern1)

statement1

;;

pattern2)

statement2

;;

...

*)

statementn

esac

  • expression表示表达式,既可以是一个变量、一个数字、一个字符串,还可以是一个数学计算表达式,或者是命令的执行结果,只要能够得到expression的值就可以。
  • pattern表示匹配模式,可以是一个数字、一个字符串,甚至是一个简单的正则表达式。

case会将expression的值与 pattern1pattern2...patternn逐个进行匹配:

  • 如果expression和某个模式(比如 pattern2)匹配成功,就会执行这模式(比如 pattern2)后面对应的所有语句(该语句可以有一条,也可以有多条),直到遇见双分号;;才停止;然后整个case-in语句就执行完了,程序会跳出整个 case-in语句,执行esac后面的其它语句。
  • 如果 expression 没有匹配到任何一个模式,那么就执行*)后面的语句(*表示其它所有值),直到遇见双分号;;或者esac才结束。*)相当于多个if分支语句中最后的else部分。

Tips:分支*)并不是什么语法规定,它只是一个正则表达式,*表示任意字符串,所以不管expression的值是什么,*)总能匹配成功。因此,可以没有*)部分,如果expression没有匹配到任何一个模式,那么就不执行任何操作。

除最后一个分支外(这个分支可以是普通分支,也可以是*)分支),其它的每个分支都必须以;;结尾,;;代表一个分支的结束,不写的话会有语法错误。最后一个分支可以写;;,也可以不写,因为无论如何,执行到esac都会结束整个case-in语句。

case-inpattern部分支持简单的正则表达式,具体来说,可以使用以下几种格式:

格式

说明

*

表示任意字符串。

[abc]

表示 a、b、c 三个字符中的任意一个。比如,[15ZH] 表示 1、5、Z、H 四个字符中的任意一个。

[m-n]

表示从 m 到 n 的任意一个字符。比如,[0-9] 表示任意一个数字,[0-9a-zA-Z] 表示字母或数字。

|

表示多重选择,类似逻辑运算中的或运算。比如,abc | xyz 表示匹配字符串 "abc" 或者 "xyz"。

;;&终止每个条件块,例如:

read -n 1 -p "Type a character > "

echo

case $REPLY in

[[:upper:]]) echo ""$REPLY" is upper case." ;;&

[[:lower:]]) echo ""$REPLY" is lower case." ;;&

[[:alpha:]]) echo ""$REPLY" is alphabetic." ;;&

[[:digit:]]) echo ""$REPLY" is a digit." ;;&

[[:graph:]]) echo ""$REPLY" is a visible character." ;;&

[[:punct:]]) echo ""$REPLY" is a punctuation symbol." ;;&

[[:space:]]) echo ""$REPLY" is a whitespace character." ;;&

[[:xdigit:]]) echo ""$REPLY" is a hexadecimal digit." ;;&

esac

输出结果如下:

Type a character > a

"a" is lower case.

"a" is alphabetic.

"a" is a visible character.

"a" is a hexadecimal digit.

循环结构

循环结构语句大致分为4种:

  • while
  • until
  • for
  • select

while语句

当条件满足时,while重复地执行一组语句,当条件不满足时,就退出while循环。格式如下:

while condition; do

statements

done

执行流程如下:

  • 先对condition进行判断,如果该条件成立,就进入循环,执while循环体中的语句,也就是dodone之间的语句。这样就完成了一次循环。
  • 每一次执行到done的时候都会重新判断condition是否成立,如果成立,就进入下一次循环,继续执行dodone之间的语句,如果不成立,就结束整个while循环,执行done后面的其它Shell代码。
  • 如果一开始condition就不成立,那么程序就不会进入循环体。

死循环

格式一:

while true; do

statements

done

格式二:

while [ 1 ]; do

statements

done

until语句

until循环当判断条件不成立时才进行循环,一旦判断条件成立,就终止循环。

until condition; do

statements

done

until循环的执行流程为:

  • 先对condition进行判断,如果该条件不成立,就进入循环,执行until循环体中的语句(dodone之间的语句),这样就完成了一次循环。
  • 每一次执行到done的时候都会重新判断condition是否成立,如果不成立,就进入下一次循环,继续执行循环体中的语句,如果成立,就结束整个 until循环,执行done后面的其它Shell代码。

for语句

C语言风格的 for 循环

格式如下:

for((exp1; exp2; exp3)); do

statements

done

exp1exp2exp3是三个表达式,其中exp2是判断条件,for循环根据exp2的结果来决定是否继续下一次循环;

它的运行过程为:

  1. 先执行exp1
  2. 再执行exp2,如果它的判断结果是成立的,则执行循环体中的语句,否则结束整个for循环。
  3. 执行完循环体后再执行exp3
  4. 重复执行2、3步骤,直到exp2的判断结果不成立,就结束循环。

for-in循环

格式如下:

for variable in value_list; do

statements

done

variable表示变量,value_list表示取值列表。

每次循环都会从value_list中取出一个值赋给变量 variable,然后进入循环体(dodone之间的部分),执行循环体中的statements。直到取完value_list中的所有值,循环就结束了。

value_list

  • 具体的值,例如:

for i in 1 2 3 "dd";do echo $i;done

  • {start..end},例如:

# 求1到10的和

sum=0

for i in {1..10}; do

sum=$((sum+i))

done

echo $sum

  • 命令的执行结果,例如:

# 求100以内偶数的和

for i in $(seq 2 2 100); do

sum=$((sum+i))

done

echo $sum

  • 通配符,例如:

# 打印当前路径.log结尾的文件

for i in *.log; do echo $i;done

Tips:若当前路径无.log结尾的文件,则会打印*.log

  • 特殊变量,$*$@等,例如:

for i in $@; do

sum=$((sum+i))

done

echo $sum

select-in语句

select-in循环用来增强交互性,它可以显示出带编号的菜单,用户输入不同的编号就可以选择不同的菜单,并执行不同的功能,非常适合终端(Terminal)这样的交互场景。格式如下:

select variable in value_list; do

statements

done

variable表示变量,value_list表示取值列表。

例如:

echo "选择你要学习的科目:"

select i in "Linux" "Python" "Java" "C++" "PHP"; do

echo "你选择了${i}。"

done

结果如下:

选择你要学习的科目:

1) Linux

2) Python

3) Java

4) C++

5) PHP

#? 5

你选择了PHP。

#? 2

你选择了Python。

#? 666

你选择了。

Tips:select是死循环,输入空值或者输入的值无效,都不会结束循环,只有遇到break语句,或者按下Ctrl+D组合键才能结束循环。

例如:

echo "选择你要学习的科目:"

select i in "Linux" "Python" "Java" "C++" "PHP"; do

echo "你选择了${i}。"

break

done

结果如下:

选择你要学习的科目:

1) Linux

2) Python

3) Java

4) C++

5) PHP

#? 5

你选择了PHP。

select-in语句常和case-in语句一起使用。

break

格式如下:

break n

n表示跳出循环的层数,如果省略n,则表示跳出当前。

continue

格式如下:

continue n

n表示循环的层数:

  • 如果省略n,则表示continue只对当前层次的循环语句有效,遇到continue会跳过本次循环,忽略本次循环的剩余代码,直接进入下一次循环。
  • 如果带上n,比如n的值为2,那么continue 对内层和外层循环语句都有效,不但内层会跳过本次循环,外层也会跳过本次循环,其效果相当于内层循环和外层循环同时执行了不带ncontinue

break的区别:

  • break用来结束当前整个循环;
  • continue用来结束本次循环,直接跳到下一次循环,如果循环条件成立,还会继续循环;

函数

函数的本质是一段可以重复使用的脚本代码,这段代码被提前编写好了,放在了指定的位置,使用时直接调取即可。

函数定义

格式如下:

function func_name() {

statements

[return value]

}

Tips:关键词function是可选的,但必须在一个项目中保持一致。

说明:

  • function是Shell中的关键字,专门用来定义函数,可以不写,但要求在整个项目脚本中保持一致,即统一不写或都写;
  • func_name是函数名,按照约定规范,函数名后面必须带上()
  • statements是函数要执行的代码,也就是一组语句;
  • return value表示函数的返回值,其中return 是Shell关键字,专门用在函数中返回一个值;这一部分可以写也可以不写。

函数调用

调用Shell函数时可以给它传递参数,也可以不传递。如果不传递参数,直接给出函数名字即可,格式如下:

func_name

如果传递参数,那么多个参数之间以空格分隔:

func_name param1 param2 param3...

Tips:不管是哪种调用方式,函数名字后面都不需要带()

函数参数

函数参数是Shell位置参数的一种,在函数内部可以使用$n来接收,例如,$1表示第一个参数,$2表示第二个参数,依次类推。

除了$n,还有另外三个比较重要的变量:

  • $#可以获取传递的参数的个数;
  • $@或者$*可以一次性获取所有的参数

原文链接:https://www.cnblogs.com/Rohn/archive/2020/07/04/13234419.html

以上是 Shell:结构化语句 的全部内容, 来源链接: utcz.com/z/518030.html

回到顶部