victory的博客

长安一片月,万户捣衣声

0%

Linux | shell脚本

shell脚本

  • shell脚本可将环境变量添加、依赖安装、二进制文件执行等命令包含在一个后缀为.sh的文本文件中,从而便于对应用的自动化运维

  • 常见的shell脚本语法

    1. 向窗口输出文本
    1
    echo "hello world"
    1. for loop
    1
    2
    3
    for file in `ls /etc`;do
    echo $file
    done
    1. 变量定义以及使用

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      # 输出变量内容
      word="this is a string!"
      echo $word
      echo "word变量的内容是${word}。"

      # 只读变量
      my_name="liao sheng li"
      readonly my_name
      echo $my_name
      my_name="sheng li" # ./test.sh:行20: my_name:只读变量

      # 删除变量
      username="zhang san"
      echo $username
      unset username
      echo $suername # 不会输出内容
    2. shell字符串

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      # 输出字符串
      echo "hello" # 双引号方式表示字符串
      echo 'hello' # 单引号方式表示字符串
      echo hello # 不使用引号方式

      # 拼接字符串
      echo "hello,"world"!"
      echo 'hello,'world'!'

      # 获取字符串长度
      string="hello"
      echo "字符串的长度为:${#string}"
      echo "字符串的长度为:${#string[0]}"

      # 提取子字符串
      string1="the sky is blue!"
      echo ${string1:4:3}

      # 查找子字符串
      string2="this is a long string!"
      echo `expr index "$string2" is`
  1. shell数组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    # 定义数组
    arr1=(1 2 3 4 5 6 7 8 9 10)

    # 读取数组
    echo ${arr1}
    elem1=${arr1[0]} # 输出下表为0时的数组元素
    echo $elem1
    echo ${arr1[@]} #输出数组所有元素

    # 获取数组的长度
    echo ${#arr1[@]} # 输出数组长度
    echo ${#arr1[*]} # 输出数组长度
    echo ${#arr1[0]} #输出下表为0的数组元素的长度

    # 关联数组
    declare -A site1=(["google"]="www.google.com" ["runoob"]="www.runoob.com" ["taobao"]="www.taobao.com")
    echo ${site1["google"]}
    echo ${site1[@]}
    declare -A site2
    site2["google"]="www.google.com"
    site2["runoob"]="www.runoob.com"
    site2["taobao"]="www.taobao.com"
    echo ${site2["taobao"]}
    echo ${site2[*]}
    1. shell注释
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # 这是一个单行注释

    : <<COMMENT
    这是
    一个
    多行注释!
    COMMENT

    : '
    这是一个
    多行注释
    '
  2. shell传递参数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    echo "此处执行shell脚本的命令为./test.sh 1 2 3"
    echo "执行的文件名:$0"
    echo "执行的文件名:$1"
    echo "执行的文件名:$2"
    echo "执行的文件名:$3"
    : '
    执行结果:
    执行的文件名:./test.sh
    执行的文件名:1
    执行的文件名:2
    执行的文件名:3
    '
    # 处理参数的集中特殊字符
    echo $# # 输出传递给脚本的参数个数,执行脚本./test.sh 1 2 3输出3
    echo $* # 以单个字符串显示所有传递个脚本的参数就,执行脚本./test.sh 1 2 3输出1 2 3
    echo $$ # 输出脚本运行的当前进行ID号
    echo $@ # 与$*相同
    echo $-
    echo $? #显示最后命令的退出状态,0表示没有错误,其他任何值表明有错误

    # $*与$@的区别
    # $*
    for i in "$*"; do
    echo $i
    done
    # $@
    for i in "$@"; do
    echo $i
    done
  3. shell运算符

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    # 算数运算符
    a=10
    b=20
    val=`expr $a + $b`
    echo "a + b : $val"
    val=`expr $a - $b`
    echo "a - b : $val"
    val=`expr $a \* $b`
    echo "a * b : $val"
    val=`expr $b / $a`
    echo "b / a : $val"
    val=`expr $b % $a`
    echo "b % a : $val"
    if [ $a == $b ]
    then
    echo "a 等于 b"
    fi
    if [ $a != $b ]
    then
    echo "a 不等于 b"
    fi

    # 关系运算符
    a=10
    b=20
    if [ $a -eq $b ] # 判断两个数字的值是否相等
    then
    echo "$a -eq $b : a 等于 b"
    else
    echo "$a -eq $b: a 不等于 b"
    fi
    if [ $a -ne $b ] # 判断两个数字的值是否不相等
    then
    echo "$a -ne $b: a 不等于 b"
    else
    echo "$a -ne $b : a 等于 b"
    fi
    if [ $a -gt $b ] # 判断一个数字是否大于另一个数字
    then
    echo "$a -gt $b: a 大于 b"
    else
    echo "$a -gt $b: a 不大于 b"
    fi
    if [ $a -lt $b ] # 判断一个数字是否小于另一个数字
    then
    echo "$a -lt $b: a 小于 b"
    else
    echo "$a -lt $b: a 不小于 b"
    fi
    if [ $a -ge $b ] # 判断一个数字是否大于小于另一个数字
    then
    echo "$a -ge $b: a 大于或等于 b"
    else
    echo "$a -ge $b: a 小于 b"
    fi
    if [ $a -le $b ] # 判断一个数字是否小于等于另一个数字
    then
    echo "$a -le $b: a 小于或等于 b"
    else
    echo "$a -le $b: a 大于 b"
    fi

    # 布尔运算符
    a=10
    b=20
    if [ $a != $b ] # 非
    then
    echo "$a != $b : a 不等于 b"
    else
    echo "$a == $b: a 等于 b"
    fi
    if [ $a -lt 100 -a $b -gt 15 ] # 与
    then
    echo "$a 小于 100 且 $b 大于 15 : 返回 true"
    else
    echo "$a 小于 100 且 $b 大于 15 : 返回 false"
    fi
    if [ $a -lt 100 -o $b -gt 100 ] # 或
    then
    echo "$a 小于 100 或 $b 大于 100 : 返回 true"
    else
    echo "$a 小于 100 或 $b 大于 100 : 返回 false"
    fi
    if [ $a -lt 5 -o $b -gt 100 ]
    then
    echo "$a 小于 5 或 $b 大于 100 : 返回 true"
    else
    echo "$a 小于 5 或 $b 大于 100 : 返回 false"
    fi

    # 逻辑运算符
    a=10
    b=20
    if [[ $a -lt 100 && $b -gt 100 ]] # 逻辑与
    then
    echo "返回 true"
    else
    echo "返回 false"
    fi
    if [[ $a -lt 100 || $b -gt 100 ]] # 逻辑或
    then
    echo "返回 true"
    else
    echo "返回 false"
    fi

    # 字符串运算符
    a="abc"
    b="efg"
    if [ $a = $b ] # 判断字符串是否相等
    then
    echo "$a = $b : a 等于 b"
    else
    echo "$a = $b: a 不等于 b"
    fi
    if [ $a != $b ] # 判断字符串是否不相等
    then
    echo "$a != $b : a 不等于 b"
    else
    echo "$a != $b: a 等于 b"
    fi
    if [ -z $a ] # 判断字符串长度是否为0
    then
    echo "-z $a : 字符串长度为 0"
    else
    echo "-z $a : 字符串长度不为 0"
    fi
    if [ -n "$a" ] # 判断字符串长度是否不为0
    then
    echo "-n $a : 字符串长度不为 0"
    else
    echo "-n $a : 字符串长度为 0"
    fi
    if [ $a ] # 判断字符串是否为空
    then
    echo "$a : 字符串不为空"
    else
    echo "$a : 字符串为空"
    fi
    echo ""

    # 文件测试运算符
    file="./test.sh"
    if [ -r $file ] # 判断文件是否可读
    then
    echo "文件可读"
    else
    echo "文件不可读"
    fi
    if [ -w $file ] # 判断文件是否可写
    then
    echo "文件可写"
    else
    echo "文件不可写"
    fi
    if [ -x $file ] # 判断文件是否可执行
    then
    echo "文件可执行"
    else
    echo "文件不可执行"
    fi
    if [ -f $file ] # 判断文件是普通文件还是特殊文件
    then
    echo "文件为普通文件"
    else
    echo "文件为特殊文件"
    fi
    if [ -d $file ] # 判断文件是不是一个目录
    then
    echo "文件是个目录"
    else
    echo "文件不是个目录"
    fi
    if [ -s $file ] # 判断文件是否为空
    then
    echo "文件不为空"
    else
    echo "文件为空"
    fi
    if [ -e $file ] # 判断文件是否存在
    then
    echo "文件存在"
    else
    echo "文件不存在"
    fi
  4. shell echo命令

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    # 显示普通字符串
    echo "\"显示转义字符\""

    # 显示变量
    read name # read 命令从标准输入中读取一行并赋值给name变量
    echo "$name is one kind of color"

    # 显示换行
    echo -e "hello\n" # -e开启转义
    echo "world"

    # 显示不换行
    echo -e "OK! \c" # \c不换行
    echo "It is a test"

    # 原样输出字符串
    echo '$name\"'

    # 显示命令执行结果
    echo `date`
  5. shell printf命令

    1
    2
    3
    4
    5
    6
    7
    echo "hello"
    printf "hello\n"

    printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg
    printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
    printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543
    printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876
  6. test 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试
# 数值测试
num1=100
num2=100
if test $[num1] -eq $[num2] # 代码中的 [] 执行基本的算数运算
then
echo '两个数相等!'
else
echo '两个数不相等!'
fi

# 字符串测试
num1="ru1noob"
num2="runoob"
if test $num1 = $num2
then
echo '两个字符串相等!'
else
echo '两个字符串不相等!'
fi

# 文件测试
if test -e ./test.sh
then
echo '文件已存在!'
else
echo '文件不存在!'
fi
  1. shell 流程控制

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    # 条件
    # 使用[...] 作为判断语句
    a=10
    b=20
    if [ $a == $b ]
    then
    echo "a 等于 b"
    elif [ $a -gt $b ]
    then
    echo "a 大于 b"
    elif [ $a -lt $b ]
    then
    echo "a 小于 b"
    else
    echo "没有符合的条件"
    fi
    # 使用 ((...)) 作为判断语句,大于和小于可以直接使用 > 和 <
    a=10
    b=20
    if (( $a == $b ))
    then
    echo "a 等于 b"
    elif (( $a > $b ))
    then
    echo "a 大于 b"
    elif (( $a < $b ))
    then
    echo "a 小于 b"
    else
    echo "没有符合的条件"
    fi

    # 循环
    # for循环
    for loop in 1 2 3 4 5
    do
    echo "The value is: $loop"
    done

    # while循环
    int=1
    while(( $int<=5 ))
    do
    echo $int
    let "int++" # Bash let 命令,它用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量
    done
    : '
    无限循环
    while :
    do
    command
    done

    while true
    do
    command
    done

    for (( ; ; ))
    '

    # until循环
    a=0
    until [ ! $a -lt 10 ]
    do
    echo $a
    a=`expr $a + 1`
    done

    # case多选择语句
    echo '输入 1 到 4 之间的数字:'
    echo '你输入的数字为:'
    read aNum
    case $aNum in
    1) echo '你选择了 1'
    ;;
    2) echo '你选择了 2'
    ;;
    3) echo '你选择了 3'
    ;;
    4) echo '你选择了 4'
    ;;
    *) echo '你没有输入 1 到 4 之间的数字'
    ;;
    esac

    # 跳出循环
    # break
    while :
    do
    echo -n "输入 1 到 5 之间的数字:"
    read aNum
    case $aNum in
    1|2|3|4|5) echo "你输入的数字为 $aNum!"
    ;;
    *) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
    break
    ;;
    esac
    done

    # continue
    : '
    while :
    do
    echo -n "输入 1 到 5 之间的数字: "
    read aNum
    case $aNum in
    1|2|3|4|5) echo "你输入的数字为 $aNum!"
    ;;
    *) echo "你输入的数字不是 1 到 5 之间的!"
    continue
    echo "游戏结束"
    ;;
    esac
    done
    '
  2. shell 函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    # 无返回值函数
    demoFun(){
    echo "这是我的第一个 shell 函数!"
    }
    echo "-----函数开始执行-----"
    demoFun
    echo "-----函数执行完毕-----"

    # 有返回值函数
    funWithReturn(){
    echo "这个函数会对输入的两个数字进行相加运算..."
    echo "输入第一个数字: "
    read aNum
    echo "输入第二个数字: "
    read anotherNum
    echo "两个数字分别为 $aNum 和 $anotherNum !"
    return $(($aNum+$anotherNum))
    }
    funWithReturn
    echo "输入的两个数字之和为 $? !"

    # 函数参数
    funWithParam(){
    echo "第一个参数为 $1 !"
    echo "第二个参数为 $2 !"
    echo "第十个参数为 $10 !"
    echo "第十个参数为 ${10} !"
    echo "第十一个参数为 ${11} !"
    echo "参数总数有 $# 个!"
    echo "作为一个字符串输出所有参数 $* !"
    }
    funWithParam 1 2 3 4 5 6 7 8 9 34 73
  3. 输入/输出重定向

    1
    echo 'print("hello")' > hello.py
  4. shell文件包含

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    : '
    shell 脚本中可以包含外部脚本

    语法格式:
    . filename # 注意点号(.)和文件名中间有一空格



    source filename
    '