• Shell编程教程



    Shell编程教程

    一、概述

    1、简介

    • Shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核。
    • Shell还是一个功能相当强大的编程语言,易编写,易调试,灵活性强。
    • 脚本以 #!/bin/bash 开头(指定解析器),第二行进行脚本的编写。

    2、Shell的解释器bash

    • shell的解释器如下,常用的是bash
    szy@szy:~$ cat /etc/shells 
    # /etc/shells: valid login shells
    /bin/sh
    /bin/bash
    /bin/rbash
    /bin/dash
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 查看Shell默认的解析器是bash
    szy@szy:~$ echo $SHELL
    /bin/bash
    
    • 1
    • 2

    二、入门案例

    1、编写shell脚本

    1. 创建目录用于存放shell脚本文件
    szy@szy:~$ mkdir scripts
    szy@szy:~$ cd scripts/
    
    • 1
    • 2
    1. 使用vim命令创建xxx.sh文件
    szy@szy:~/scripts$ vim hello.sh 
    
    • 1
    1. 编写xxx.sh文件内容(第一行#!/bin/bash,第二行开始编写脚本代码)
    #!/bin/bash
    echo "hello,world"
    
    • 1
    • 2

    2、脚本执行方式

    1. bash执行方式
    szy@szy:~/scripts$ bash hello.sh 
    hello,world
    
    • 1
    • 2
    1. sh执行方式
    szy@szy:~/scripts$ sh hello.sh 
    hello,world
    
    • 1
    • 2
    1. 添加权限执行
    szy@szy:~/scripts$ ll
    总用量 12
    drwxrwxr-x  2 szy szy 4096 122 08:26 ./
    drwxr-xr-x 23 szy szy 4096 122 08:26 ../
    -rw-rw-r--  1 szy szy   31 122 08:26 hello.sh
    szy@szy:~/scripts$ chmod +x hello.sh 
    szy@szy:~/scripts$ ll
    总用量 12
    drwxrwxr-x  2 szy szy 4096 122 08:26 ./
    drwxr-xr-x 23 szy szy 4096 122 08:26 ../
    -rwxrwxr-x  1 szy szy   31 122 08:26 hello.sh*
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    # xxx.sh文件添加可执行权限
    chmod +x xxx.sh
    # xxx.sh文件当前用户添加可执行权限
    chmod a+x xxx.sh
    # 最高权限
    chmod 777 xxx.sh
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1. 当前路径(相对路径)执行 ./
    szy@szy:~/scripts$ ./hello.sh 
    hello,world
    
    • 1
    • 2
    1. 绝对路径执行
    szy@szy:~$ scripts/hello.sh 
    hello,world
    
    • 1
    • 2
    1. source执行脚本
    szy@szy:~/scripts$ source hello.sh 
    hello,world
    szy@szy:~$ source scripts/hello.sh 
    hello,world
    szy@szy:~$ type source 
    source 是 shell 内建
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1. . 执行脚本
    szy@szy:~/scripts$ . hello.sh 
    hello,world
    
    • 1
    • 2

    3、实现步骤

    szy@szy:~$ mkdir she
    szy@szy:~$ cd she/
    szy@szy:~/she$ vim test.sh
    szy@szy:~/she$ ll
    总用量 12
    drwxrwxr-x  2 szy szy 4096 12月  2 18:00 ./
    drwxr-xr-x 24 szy szy 4096 12月  2 18:00 ../
    -rw-rw-r--  1 szy szy   33 12月  2 18:00 test.sh
    szy@szy:~/she$ chmod a+x test.sh 
    szy@szy:~/she$ ll
    总用量 12
    drwxrwxr-x  2 szy szy 4096 12月  2 18:00 ./
    drwxr-xr-x 24 szy szy 4096 12月  2 18:00 ../
    -rwxrwxr-x  1 szy szy   33 12月  2 18:00 test.sh*
    szy@szy:~/she$ ./test.sh 
    hello, world
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • test.sh脚本文件内容
    #!/bin/bash
    echo "hello, world"
    
    • 1
    • 2

    三、变量

    1、系统预定义变量

    1. 常用系统变量
      $ HOME、$ PWD、$ SHELL、$ USER等

    2. 环境变量
      export:查看环境变量
      echo $PATH:输出环境变量的值
      help echo:查看echo命令的帮助信息

    • 查看系统变量的值(全局)
    szy@szy:~/scripts$ echo $HOME 
    /home/szy
    
    • 1
    • 2
    • 查看系统全局变量
    szy@szy:~/scripts$ env
    
    • 1
    • 显示当前Shell中的所有变量
    szy@szy:~/scripts$ set
    
    • 1

    2、用户自定义变量

    1. 基本语法
      定义变量(变量赋值):变量名=变量值,注意,=前后不能有空格
      销毁变量:unset 变量
      声明静态变量:readonly 变量,注意:不能销毁unset

    2. 变量定义规则
      变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写。
      等号两侧不能有空格。
      在bash中,变量默认类型都是字符串类型,无法直接进行数值运算。
      局部变量变成全局变量使用export
      子shell更改不会影响父shell
      typeset和declare两个内部命令定义变量
      变量的值如果有空格,需要使用双引号或单引号括起来:
      echo “hello ${x}”:双引号可以正常输出变量值
      echo ‘hello ${x}’:单引号输出字符串

    3. 变量的四种引用方式
      $变量名
      ${变量名}
      “$变量名”
      “${变量名}”

    4. 测试

    • a变量赋值2,并输出a变量的值
    szy@szy:~/scripts$ a=2
    szy@szy:~/scripts$ echo $a
    2
    
    • 1
    • 2
    • 3
    • 没有被赋值的变量返回空
    szy@szy:~/scripts$ echo $my_var
    
    
    • 1
    • 2
    • 修改值再次赋值
    szy@szy:~/scripts$ my_var=hello
    szy@szy:~/scripts$ echo $my_var 
    hello
    szy@szy:~/scripts$ my_var=Hello
    szy@szy:~/scripts$ echo $my_var 
    Hello
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 有空格加单引号或双引号
    szy@szy:~/scripts$ my_var="hello, world"
    szy@szy:~/scripts$ echo $my_var
    hello, world
    szy@szy:~/scripts$ my_var='hello, world'
    szy@szy:~/scripts$ echo $my_var
    hello, world
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 变量加法,由于默认是字符串,所有需要
      • 运算符的表达 $(())
      • 运算符的表达 $[]
    szy@szy:~/scripts$ echo $a
    2
    szy@szy:~/scripts$ a=1+5
    szy@szy:~/scripts$ echo $a
    1+5
    szy@szy:~/scripts$ a=$((1+5))
    szy@szy:~/scripts$ echo $a
    6
    szy@szy:~/scripts$ a=$[8+5]
    szy@szy:~/scripts$ echo $a
    13
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 只读变量
    szy@szy:~/scripts$ readonly b=5
    szy@szy:~/scripts$ b=10
    -bash: b: 只读变量
    szy@szy:~/scripts$ echo $b
    5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 销毁变量,只读变量无法销毁
    szy@szy:~/scripts$ unset a
    szy@szy:~/scripts$ unset b
    -bash: unset: b: 无法取消设定: 只读 variable
    
    • 1
    • 2
    • 3
    • typeset和declare两个内部命令定义变量
      • -i:整数变量
      • -a:数组变量
      • -f:函数变量
      • -r:只读变量
    szy@szy:~/scripts$ declare a
    szy@szy:~/scripts$ declare -i b
    
    • 1
    • 2

    3、read读取控制台输入

    1. 基本语法
    read (选项) 变量名
    
    • 1

    选项:
    -p:指定读取值时的提示符
    -t:指定读取值时等待时间(秒)如果-t不加表示一直等待,时间到则退出
    -n:读取n个字符之后返回,而不是等到读取换行符

    • -n读取3个字符后结束
    szy@szy:~/she$ read -n 3
    323
    szy@szy:~/she$ 
    
    • 1
    • 2
    • 3
    • 读取到o结束,读取到c结束
    # 读取到o结束
    szy@szy:~/scripts$ read -d o x
    dewewoszy
    # 读取到c结束,多个字符时只看第一个
    @szy:~/scripts$ read -d cde x
    dsdc
    szy@szy:~/scripts$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 10秒输入提示信息的内容
    szy@szy:~/scripts$ vim read_test.sh
    szy@szy:~/scripts$ chmod +x read_test.sh 
    szy@szy:~/scripts$ ./read_test.sh 
    请输入您的姓名:sgz
    你好 sgz
    szy@szy:~/scripts$ ./read_test.sh 
    请输入您的姓名:你好 
    szy@szy:~/scripts$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    read_test.sh文件内容

    #!/bin/bash
    
    read -t 10 -p "请输入您的姓名:" name
    echo "你好 $name"
    
    • 1
    • 2
    • 3
    • 4

    4、特殊变量

    4.1、$n 定义位置参数

    n为数字,$0代表该脚本名称,$1-$9代表第一个到第九个参数,十以上的参数需要用大括号包含,如 ${10}

    • hello.sh文件内容
    #!/bin/bash
    echo "hello, world"
    # $1,输入一个参数
    echo "hello, $1"
    
    • 1
    • 2
    • 3
    • 4
    • 执行测试。输入第一个参数
    szy@szy:~/scripts$ ./hello.sh 你好
    hello, world
    hello, 你好
    
    • 1
    • 2
    • 3
    • paramter.sh脚本内容
    #!/bin/bash
    # 双引号会认为值变量
    #echo "=======$n======"
    # 单引号会原样输出
    echo '=======$n======'
    echo script name: $0
    echo 1st paramter: $1
    echo 2nd parameter: $2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 执行测试,输入第一个和第二个参数
    szy@szy:~/scripts$ ./parameter.sh abc def
    =======$n======
    script name: ./parameter.sh
    1st paramter: abc
    2nd parameter: def
    
    • 1
    • 2
    • 3
    • 4
    • 5
    4.2、$# 获取参数个数

    获取所有输入参数个数,常用于循环,判断参数的个数是否正确以及加强脚本的健壮性。

    • paramter.sh脚本内容
    #!/bin/bash
    echo '=======$n======'
    echo script name: $0
    echo 1st paramter: $1
    echo 2nd parameter: $2
    echo parmamter number: $#
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 执行测试,当没有参数是输出0,当输入3个参数是输出3
    szy@szy:~/scripts$ ./parameter.sh
    =======$n======
    script name: ./parameter.sh
    1st paramter:
    2nd parameter:
    parmamter number: 0
    szy@szy:~/scripts$ ./parameter.sh dbd ccc 333
    =======$n======
    script name: ./parameter.sh
    1st paramter: dbd
    2nd parameter: ccc
    parmamter number: 3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    4.3、 $* 获取所有参数 、 $@ 依次遍历所有参数

    $* :这个变量代表命令行中所有的参数, 把所有的参数看成一个整体
    $@:这个变量也代表命令行所有的参数,不过 $@ 把每个参数区分对待,类似一个数组,可以使用for循环遍历里面的参数

    • paramter.sh脚本内容
    #!/bin/bash
    echo '=======$n======'
    echo script name: $0
    echo 1st paramter: $1
    echo 2nd parameter: $2
    echo '=======$#======'
    echo paramter number: $#
    echo '=======$*======'
    echo $*
    echo '=======$@======'
    echo $@
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 执行测试
    szy@szy:~/scripts$ ./parameter.sh dbd ccc 222
    =======$n======
    script name: ./parameter.sh
    1st paramter: dbd
    2nd parameter: ccc
    =======$#======
    paramter number: 3
    =======$*======
    dbd ccc 222
    =======$@======
    dbd ccc 222
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    4.2、$? 获取返回状态0真,非0假

    最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行:如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。

    • 测试 $?
    szy@szy:~/scripts$ echo $?
    0
    szy@szy:~/scripts$ parmeter.sh
    parmeter.sh:未找到命令
    szy@szy:~/scripts$ echo $?
    127
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    四、运算符

    1、运算符号

    运算符可以加空格也可以不加空格

    1. $((运算式))
    2. $[运算式]
    • 使用expr手工命令行计数器
    szy@szy:~/scripts$ a=1+2
    szy@szy:~/scripts$ echo $a
    1+2
    szy@szy:~/scripts$ expr 1+2
    1+2
    szy@szy:~/scripts$ expr 1 + 2
    3
    szy@szy:~/scripts$ expr 5 - 2
    3
    szy@szy:~/scripts$ expr 5 * 2
    expr: 语法错误
    szy@szy:~/scripts$ expr 5 \* 2
    10
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 使用运算符
    szy@szy:~/scripts$ echo $[5*2]
    10
    szy@szy:~/scripts$ echo $((5*2))
    10
    szy@szy:~/scripts$ a=$[6+8]
    szy@szy:~/scripts$ echo $a
    14
    szy@szy:~/scripts$ s=$[(2+3)*4]
    szy@szy:~/scripts$ echo $s
    20
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • add.sh脚本内容
    #!/bin/bash
    # 可以加空格也可以不加空格
    sum=$[$1+$2]
    # sum=$[$1 + $2]
    echo sum=$sum
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 执行add.sh脚本,两个数求和计算
    szy@szy:~/scripts$ ./add.sh 25 89
    sum=114
    
    • 1
    • 2

    2、三目运算符

    1真,0假;1真执行2值;1假执行3值
    注意:三目运算符与条件测试的真假相反

    表达式1?表达式2:表达式3
    
    • 1
    szy@szy:~/scripts$ aa=0
    szy@szy:~/scripts$ bb=1
    szy@szy:~/scripts$ cc=2
    szy@szy:~/scripts$ dd=3
    # aa为假
    szy@szy:~/scripts$ echo $((aa?cc:dd))
    3
    # bb为真
    szy@szy:~/scripts$ echo $((bb?cc:dd))
    2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3、let 计算算术表达式

    • let:计算一个算术表达式
    • let可以代替 $((运算式))、$[运算式]
    szy@szy:~/scripts$ aa=10
    szy@szy:~/scripts$ bb=20
    szy@szy:~/scripts$ let xx=$aa+$bb
    szy@szy:~/scripts$ echo $xx
    30
    szy@szy:~/scripts$ xx=$(($aa+$bb))
    szy@szy:~/scripts$ echo $xx
    30
    szy@szy:~/scripts$ xx=$[$aa+$bb]
    szy@szy:~/scripts$ echo $xx
    30
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    五、条件测试

    1、条件测试

    • 三种条件测试语法
      • test condition:比较时有空格
      • [ condition ]:前后有空格
      • [[ condition ]]:前后有空格

    注意:
    1.条件非空即为true,[ aaa ]返回true,[ ]返回false。
    2. 0真,1假。
    3. 判断时需要空格

    • 测试 test condition
    szy@szy:~/scripts$ a=hello
    szy@szy:~/scripts$ echo $a
    hello
    szy@szy:~/scripts$ test $a = hello
    szy@szy:~/scripts$ echo $?
    0
    szy@szy:~/scripts$ test $a = Hello
    szy@szy:~/scripts$ echo $?
    1
    szy@szy:~/scripts$ a=Hello
    szy@szy:~/scripts$ test $a = Hello
    szy@szy:~/scripts$ echo $?
    0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 测试 [ condition ]
    szy@szy:~/scripts$ [ $a = Hello ]
    szy@szy:~/scripts$ echo $?
    0
    szy@szy:~/scripts$ [ $a = hello ]
    szy@szy:~/scripts$ echo $?
    1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 测试 [[ condition ]]
    szy@szy:~/she$ a=hello
    szy@szy:~/she$ [[ $a = Hello ]]
    szy@szy:~/she$ echo $?
    1
    szy@szy:~/she$ [[ $a = hello ]]
    szy@szy:~/she$ echo $?
    0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 条件是否为空
    szy@szy:~/scripts$ [ sfsfaf ]
    szy@szy:~/scripts$ echo $?
    0
    szy@szy:~/scripts$ [  ]
    szy@szy:~/scripts$ echo $?
    1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • != 和其他编程语言一样
    szy@szy:~/scripts$ [ $a != Hello ]
    szy@szy:~/scripts$ echo $?
    1
    szy@szy:~/scripts$ [ $a != hello ]
    szy@szy:~/scripts$ echo $?
    0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2、整数值测试

    • 两个整数之间比较
      • -eq 等于
      • -ne 不等于
      • -lt 小于
      • -le 小于等于
      • -gt 大于
      • -ge 大于等于

    注意:如果字符串之间的比较,用等号 “=” 判断相等;用“!=”判断不等,如下。

    • 字符串比较
    szy@szy:~/scripts$ [ 2 = 8 ]
    szy@szy:~/scripts$ echo $?
    1
    szy@szy:~/scripts$ [ 2 = 2 ]
    szy@szy:~/scripts$ echo $?
    0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 整数比较
    szy@szy:~/scripts$ [ 2 -lt 8 ]
    szy@szy:~/scripts$ echo $?
    0
    szy@szy:~/scripts$ [ 2 -gt 8 ]
    szy@szy:~/scripts$ echo $?
    1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3、文件测试

    -r 有读的权限
    -w 有写的权限
    -x 有执行的权限
    -b 当前文件存在,其为块文件时测试为真
    -d 当前路径存在,且为目录时测试为真
    -e 文件存在
    -f 文件存在并且是一个常规的文件

    1. 按照文件权限进行判断
    szy@szy:~/scripts$ touch test
    
    szy@szy:~/scripts$ [ -r hello.sh ]
    szy@szy:~/scripts$ echo $?
    0
    szy@szy:~/scripts$ [ -w hello.sh ]
    szy@szy:~/scripts$ echo $?
    0
    szy@szy:~/scripts$ [ -x hello.sh ]
    szy@szy:~/scripts$ echo $?
    0
    szy@szy:~/scripts$ [ -r test ]
    szy@szy:~/scripts$ echo $?
    0
    szy@szy:~/scripts$ [ -w test ]
    szy@szy:~/scripts$ echo $?
    0
    szy@szy:~/scripts$ [ -x test ]
    szy@szy:~/scripts$ echo $?
    1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    1. 按照文件类型进行判断
    szy@szy:~/scripts$ [ -e /home/szy/info ]
    szy@szy:~/scripts$ echo $?
    1
    szy@szy:~/scripts$ [ -e /home/szy/sum.sh ]
    szy@szy:~/scripts$ echo $?
    0
    szy@szy:~/scripts$ [ -f add.sh ]
    szy@szy:~/scripts$ echo $?
    0
    szy@szy:~/scripts$ [ -d add.sh ]
    szy@szy:~/scripts$ echo $?
    1
    szy@szy:~/scripts$ [ -d /home/szy/ ]
    szy@szy:~/scripts$ echo $?
    0
    szy@szy:~/scripts$ ls -l /dev/sda
    brw-rw---- 1 root disk 8, 0 12月  2 08:14 /dev/sda
    szy@szy:~/scripts$ [ -b /dev/sda ];echo $?
    0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    4、字符串测试

    字符串对比:

    • =
    • ==
    • !=
    • >
    • <

    注意:
    使用符号时两侧必须有空格
    [[ ]] 括号左右必须有空格
    这点与赋值时不同,赋值时两侧不能有空格

    • 对比字符串
    szy@szy:~/scripts$ [[ "abc" == "abd" ]];echo $?
    1
    szy@szy:~/scripts$ [[ "abc" == "abc" ]];echo $?
    0
    szy@szy:~/scripts$ [[ "abc" == "abd" ]];echo $?
    1
    szy@szy:~/scripts$ [[ "abc" > "aaa" ]];echo $?
    0
    szy@szy:~/scripts$ [[ "abc" > "abc" ]];echo $?
    1
    szy@szy:~/scripts$ [[ "abc" != "abc" ]];echo $?
    1
    szy@szy:~/scripts$ [[ "abc" != "abd" ]];echo $?
    0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 对比两个字符串类型的变量
    szy@szy:~/scripts$ s1=abc
    szy@szy:~/scripts$ s2=bcd
    szy@szy:~/scripts$ [[ $s1 == $s2 ]];echo $?
    1
    szy@szy:~/scripts$ [[ $s1 > $s2 ]];echo $?
    1
    szy@szy:~/scripts$ [[ $s1 < $s2 ]];echo $?
    0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    六、分支语句

    1、if判断

    注意:
    [ 条件判断式 ],中括号和条件判断式之间必须有空
    if 后要有空格

    1. 单分支语法格式
    if [ 条件判断式 ];then
    	程序
    fi
    
    • 1
    • 2
    • 3

    或者

    if [ 条件判断式 ]
    then
    	程序
    fi
    
    • 1
    • 2
    • 3
    • 4
    1. 多分支语法格式
    if [ 条件判断式 ]
    then
    	程序
    elif [ 条件判断式 ]
    then
    	程序
    else
    	程序
    fi
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • if.sh脚本内容
    #!/bin/bash
    
    if [ "$1"x = "sgz"x ]
    then
    	echo "hello, sgz"
    fi
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 执行测试
    szy@szy:~/scripts$ ./if.sh 
    szy@szy:~/scripts$ ./if.sh 小米
    szy@szy:~/scripts$ ./if.sh sgz
    hello, sgz
    
    • 1
    • 2
    • 3
    • 4

    2、case语句

    • case语法格式
    case $变量名 in
    "值1")
    	如果变量的值等于值1,则执行程序1
    ;;
    "值2")
    	如果变量的值等于值2,则执行程序2
    ;;
    	...省略其它分支...
    *)
    	如果变量的值都不是以上的值,则执行此程序
    ;;
    esac
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    注意:
    (1)case行尾必须为单词 “in”,每一个模式匹配必须以右括号“)”结束。
    (2)双分号“;;”表示命令序列结束,相当于java中的break。
    (3)最后的"*)"表示默认模式,相当于java中的default。

    • case.sh脚本内容
    #!/bin/bash
    
    case $1 in
    1)
    	echo "one"
    ;;
    2)
    	echo "two"
    ;;
    3)
    	echo "three"
    ;;
    *)
    	echo "number else"
    ;;
    esac
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 执行脚本
    szy@szy:~/scripts$ ./case.sh 1
    one
    szy@szy:~/scripts$ ./case.sh 6
    number else
    
    • 1
    • 2
    • 3
    • 4

    七、循环语句

    1、for循环

    1. for语法格式
      (()):可以空格,可不空格
      [ ]:必须空格
    • 格式1
    for (( 初始值;循环控制条件;变量变化 ))
    do
    	程序
    done
    
    • 1
    • 2
    • 3
    • 4
    • 格式2
    # list元素集合,通常是数组变量,循环时将list中相应位置的元素赋给变量,通过变量输出
    for 变量 in list
    do
    	程序
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • (()):可以直接跟数学运算式
    #!/bin/bash
      
    sum=0
    for ((i=1;i<=$1;i++))
    do
            sum=$[$sum+$i]
    done
    echo $sum
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • for循环输出数组中的元素
    #!/bin/bash
      
    array=(1 2 3 4 5)
    for num in ${array[@]} #获取数组索引0-4
    do
            echo $num
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 格式2测试
    szy@szy:~/scripts$ for os in linux windows macos; do echo $os;done
    linux
    windows
    macos
    szy@szy:~/scripts$ for i in {1..100}; do sum=$[$sum+$i]; done; echo $sum
    5050
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 比较 $* 和 $@ 区别
      $ * :整体
      $@:独立
      可以通过加引号区分
      不加引号:正常输出
      加引号:逐个输出 $@

    • 不加引号:正常输出

    #!/bin/bash
    
    echo '=========$*=========='
    for para in $*
    do
    	echo $para
    done
    
    echo '=========$@=========='
    for para in $@
    do      
            echo $para
    done 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    szy@szy:~/scripts$ ./paramter_for.sh a b c d e
    =========$*==========
    a
    b
    c
    d
    e
    =========$@==========
    a
    b
    c
    d
    e
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 加引号:逐个输出$@
    #!/bin/bash
    
    echo '=========$*=========='
    for para in "$*"
    do
    	echo $para
    done
    
    echo '=========$@=========='
    for para in "$@"
    do      
            echo $para
    done 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    szy@szy:~/scripts$ ./paramter_for.sh a b c d e
    =========$*==========
    a b c d e
    =========$@==========
    a
    b
    c
    d
    e
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2、while循环

    1. while语法格式
    while [ 条件判断式 ]
    do
    	程序
    done
    
    • 1
    • 2
    • 3
    • 4
    • for.sh脚本内容
    #!/bin/bash
    
    # for实现
    sum=0
    for ((i=1;i<=$1;i++))
    do
    	sum=$[$sum+$i]
    done
    echo $sum
    
    # while实现
    a=1
    while [ $a -le $1 ]
    do
    # 老写法
    #       sum2=$[ $sum2 + $a ]
    #       a=$[$a + 1]
    # 新写法
            let sum2+=a
            let a++
    done
    echo $sum2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 执行脚本
    szy@szy:~/scripts$ ./for.sh 100
    5050
    5050
    
    • 1
    • 2
    • 3
    • while输出数组中的元素
    #!/bin/bash
      
    array=(1 2 3 4 5)
    length=${#array[@]}		# 获取数组长度
    i=0
    while(($i<$length))
    do
            echo ${array[i]}	# 输出索引i对应的值
            let "i++"
    done  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3、until循环

    until:条件测试为假时执行循环语句

    4、select循环

    select:和用户进行交互,它是死循环,必须使用break,exit或Ctrl+C退出脚本。

    5、continue语句

    continue:终止本次循环

    6、break语句

    break:终止循环

    八、数组

    1、定义数组

    • 使用 ${数组名[索引]} 来获取该索引下标对应的元素
    1. 直接定义数组
    szy@szy:~/scripts$ a1=(1 2 3 4 5)
    szy@szy:~/scripts$ echo ${a1[0]}
    1
    
    • 1
    • 2
    • 3
    1. 先声明再定义数组
    szy@szy:~/scripts$ declare -a a2
    szy@szy:~/scripts$ a2=("a" "b" "c" "d" "e")
    szy@szy:~/scripts$ echo ${a2[1]}
    b
    
    • 1
    • 2
    • 3
    • 4
    1. 每行一个元素定义数组
    szy@szy:~/scripts$ a3=(1
    > 2
    > 3
    > 4
    > 5
    > )
    szy@szy:~/scripts$ echo ${a3[2]}
    3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 将包含空格的字符串直接转换为数组
    szy@szy:~/scripts$ date="t e d u"
    szy@szy:~/scripts$ a4=($date)
    szy@szy:~/scripts$ echo ${a4[3]}
    u
    
    • 1
    • 2
    • 3
    • 4
    1. 通过索引,依次输出元素的值定义数组
    szy@szy:~/scripts$ a5[0]=1
    szy@szy:~/scripts$ a5[1]=2
    szy@szy:~/scripts$ a5[2]=3
    szy@szy:~/scripts$ a5[3]=4
    szy@szy:~/scripts$ a5[4]=5
    szy@szy:~/scripts$ echo ${a5[4]}
    5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. 索引与元素一一对应定义数组
    szy@szy:~/scripts$ a6=([0]=1 [1]=2 [2]=3 [3]=4 [4]=5)
    szy@szy:~/scripts$ echo ${a6[1]}
    2
    
    • 1
    • 2
    • 3

    2、销毁数组

    # 销毁数组中某个索引元素
    unset 数组名[索引]
    # 销毁整个数组
    unset 数组名
    
    • 1
    • 2
    • 3
    • 4
    • 销毁a6下标为2的数组元素,查看发现该元素被销毁,其他元素还在。
    szy@szy:~/scripts$ unset a6[2]
    szy@szy:~/scripts$ echo ${a6[2]}
    
    szy@szy:~/scripts$ echo ${a6[1]}
    2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 销毁a6整个数组,查看发现该数组被销毁
    szy@szy:~/scripts$ unset a6
    szy@szy:~/scripts$ echo ${a6[1]}
    
    
    • 1
    • 2
    • 3

    九、函数

    1、定义函数四种方式

    function funname()
    {
    	函数体
    }
    funname()
    {
    	函数体
    }
    function funname()
    {
    	函数体
    	return n
    }
    funname()
    {
    	函数体
    	return n
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    注意:
    1、必须在调用函数地方之前,先声明函数,shell脚本是逐行运行。不会像其它语言一样先编译。
    2、函数返回值,只能通过$?系统变量获得,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255)。

    • fun_test.sh脚本内容
    #!/bin/bash
    # 声明函数
    function add()
    {
    	s=$[$1 + $2]
    	echo "和:"$s
    }
    
    read -p "请输入第一个整数:" a
    read -p "请输入第二个整数:" b
    
    # 调用函数
    add $a $b
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 执行脚本
    szy@szy:~/scripts$ ./fun_test.sh 
    请输入第一个整数:35
    请输入第二个整数:67
    和:102
    
    • 1
    • 2
    • 3
    • 4
    • add.sh脚本内容
    #!/bin/bash
      
    function add()
    {
            s=$[$1 + $2]
            return $s
    }
    
    read -p "请输入第一个整数:" a
    read -p "请输入第二个整数:" b
    
    add $a $b
    # $? 与 return 结果代码,0-255,当我们计算超出该范围会错误
    echo "和:" $?
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 改进的程序,add.sh脚本内容
    #!/bin/bash
      
    function add()
    {
            s=$[$1 + $2]
            echo $s
    }
    
    read -p "请输入第一个整数:" a
    read -p "请输入第二个整数:" b
    
    sum=$(add $a $b)
    echo "和:" $sum
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 定义函数与调用函数
    #!/bin/bash
      
    function add()
    {
    
            echo first function
    }
    
    add2()
    {
            echo second function
    }
    
    add
    add2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • return与$?配合
    #!/bin/bash
      
    function add()
    {
    
            echo first function
            return 3
    }
    
    add
    echo 值为:$?
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    十、总结

    $变量、${变量名}、“$变量名”、“${变量名}”:取值,输出获取变量的值,使用变量值时使用
    $0:获取脚本文件名
    $1-$9:代表获取第一个到第九个参数,十以上用大括号包含,如:${10}
    $#:获取所有输入参数个数,常用于循环
    $*:这个变量代表命令行中所有的参数,整体
    $@:这个变量也代表命令行所有的参数,依次遍历参数,独立;不加引号正常输出;
    加引号逐个输出
    $?:最后一次执行的命令的返回状态,0真,非0假
    ${数组名[索引]}:来获取该索引下标对应的元素
    ${数组名[@]}:获取数组索引下标
    ${#数组名[@]}:获取数组长度
    双引号和单引号可以输出字符串中的空格,双引号变量值,单引号输出字符串

  • 相关阅读:
    3、MATLAB中矩阵和多维矩阵介绍
    Taro.navigateTo 使用URL传参数和目标页面参数获取
    【第95题】JAVA高级技术-网络编程14(简易聊天室9:使用Socket传递音频)
    【正点原子FPGA连载】第二十四章 双路高速DA实验 摘自【正点原子】DFZU2EG/4EV MPSoC 之FPGA开发指南V1.0
    【Redhat】新系统yum源配置
    【Android抓包】- Stetho
    NoSQL--3.MongoDB配置(Linux版)
    【精读Uboot】异常向量的设置
    软考重点5 程序设计语言
    AtCoder Beginner Contest 279 E.Cheating Amidakuji(思维题 swap)
  • 原文地址:https://blog.csdn.net/s17856147699/article/details/128141678