shell 编程


shell编程

  1. 什么是Shell

    • 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
    • Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
  2. shell 脚本:

    • Shell 脚本(shell script),是一种为 shell 编写的脚本程序
  3. 变量:变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:

    • 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
    • 中间不能有空格,可以使用下划线(_)。
    • 不能使用标点符号。
    • 不能使用bash里的关键字
    正常命名:
    your_name="runoob.com"
    无效命名:
    ?var=123
    user*name=runoob
    
    for file in `ls /etc`
    for file in $(ls /etc)
    
    使用一个定义过的变量,只要在变量名前面加美元符号即可
    your_name="qinjx"
    echo $your_name
    echo ${your_name}
    变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界
    
    for skill in Ada Coffe Action Java; do
        echo "I am good at ${skill}Script"
    done
    
    如果不给skill变量加花括号,写成echo "I am good at $skillScript",解释器就会把$skillScript当成一个变量(其值为空),代码执行结果就不是我们期望的样子了。
    
    只读变量
    myUrl="https://www.google.com"
    readonly myUrl
    myUrl="https://www.runoob.com"
    删除变量
    #变量被删除后不能再次使用。unset 命令不能删除只读变量。
    myUrl2="https://www.runoob.com"
    unset myUrl2
    echo $myUrl2  # 被删除的变量不会打印
    
  4. Shell 字符串

    • 字符串是shell编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了),字符串可以用单引号,也可以用双引号,也可以不用引号。单双引号的区别跟PHP类似。

    • 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;

    • 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。

    • 双引号里可以有变量

    • 引号里可以出现转义字符

      str='this is a string'
      str=this is a string
      str="this is a string"
      
      # 双引号里面可以有变量,单引号里面变量必须用单引号继续引
      your_name='runoob'
      str="Hello, I know you are $your_name! \n"
      echo -e $str
      
      str='Hello, I know you are '$your_name'! \n'
      echo -e $str
      
      
  5. 字符串操纵

    # 获取长度
    string="abcd"
    echo ${#string} #输出 4
    # 切片
    string="runoob is a great site"
    echo ${string:1:4} # 输出 unoo
    
    #查找子字符串(未验证)
    string="runoob is a great site"
    echo `expr index "$string" io`  # 输出 4
    
    
  6. Shell 数组:

    • 在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开
    • ash支持一维数组(不支持多维数组),并且没有限定数组的大小。
    数组名=(值1 值2 ... 值n)
    a=(1 2 3 4 5)
    echo $a 
    ${数组名[下标]}
    a=(1 2 3 4 5)
    #echo $a
    echo ${a[0]} 
    #echo ${a[@]}
    
    my_array=(A B "C" D)
    
    echo "第一个元素为: ${my_array[0]}"
    echo "第二个元素为: ${my_array[1]}"
    echo "第三个元素为: ${my_array[2]}"
    echo "第四个元素为: ${my_array[3]}"
    
    
    echo "数组的元素为: ${my_array[*]}"
    echo "数组的元素为: ${my_array[@]}"
    
  7. Shell 注释

    通过每一行加一个 # 
    :<
  8. Shell 传递参数

    echo "Shell 传递参数实例!";
    echo "执行的文件名:$0"; # 文件名
    echo "第一个参数为:$1"; # 1
    echo "第二个参数为:$2"; # 2
    echo "第三个参数为:$3"; # 3
    
     ./test.sh 1 2 3
     
    for i in "$@"; do
       echo $i
    done
     
    
  9. Shell 基本运算符

    • 原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
    • 表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。
    • 完整的表达式要被 包含,注意这个字符不是常用的单引号,在 Esc 键下边。
    • 乘号(*)前边必须加反斜杠()才能实现乘法运算;
    • 在 MAC 中 shell 的 expr 语法是:$((表达式)),此处表达式中的 "*" 不需要转义符号 "" 。
    val=`expr 2 + 2`
    echo "两数之和为 : $val"
    
    a=10
    b=20
    if [ $a == $b ]
    then
       echo "a 等于 b"
    fi
    
    # 关系运算符:
    -eq
    -ne
    -gt
    -lt
    -ge
    -le
    # 布尔运算符
    !非
    -o 或
    -a 与
    [ ! false ] 返回 true。
    [ $a -lt 20 -o $b -gt 100 ] 返回 true。
    
    #逻辑运算符
    &&
    ||
    [[ $a -lt 100 && $b -gt 100 ]] 返回 false
    [[ $a -lt 100 || $b -gt 100 ]] 返回 true
    
    #字符串运算符
    =
    !=
    -z 检测字符串长度是否为0,为0返回 true。[ -z $a ] 
    -n 检测字符串长度是否不为 0,不为 0 返回 true。[ -n "$a" ] 返回 true。
    $ 检测字符串是否为空,不为空返回 true。[ $a ] 返回 true。
    
    #文件测试运算符
    -e file  检测文件(包括目录)是否存在,如果是,则返回 true。
    -s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。
    -x file  是否可执行
    
    
  10. echo命令

    #!/bin/sh
    echo -e "OK! \c" # -e 开启转义 \c 不换行
    echo "It is a test"
    #显示结果定向至文件
    echo "It is a test" > myfile
    #显示日期
    echo `date`
    
  11. printf

    printf  format-string  [arguments...]
    $ printf "Hello, Shell\n"
    Hello, Shell
    
    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 
    
    姓名     性别   体重kg
    郭靖     男      66.12
    杨过     男      48.65
    郭芙     女      47.99
    
    %s %c %d %f都是格式替代符
    %-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
    %-4.2f 指格式化为小数,其中.2指保留2位小数。
    
    
    
  12. Shell test 命令

    • Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
    1.数值测试
    num1=100
    num2=100
    if test $[num1] -eq $[num2]
    then
        echo '两个数相等!'
    else
        echo '两个数不相等!'
    fi
    
    代码中的 [] 执行基本的算数运算,如
    a=5
    b=6
    result=$[a+b] # 注意等号两边不能有空格
    echo "result 为: $result"
    
    2.字符串测试(=,!=,-n,-z)
    num1="ru1noob"
    num2="runoob"
    if test $num1 = $num2
    then
        echo '两个字符串相等!'
    else
        echo '两个字符串不相等!'
    fi
    
    3.文件测试(xxx,-e,-s)
    cd /bin
    if test -e ./bash
    then
        echo '文件已存在!'
    else
        echo '文件不存在!'
    fi
    
    cd /bin
    if test -e ./notFile -o -e ./bash
    then
        echo '至少有一个文件存在!'
    else
        echo '两个文件都不存在'
    fi
    
  13. 流程控制

    if condition
    then
        command1 
        command2
        ...
        commandN 
    fi
    
    if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then 
    echo "true"; 
    fi
    
    if condition
    then
        command1 
        command2
        ...
        commandN
    else
        command
    fi
    
    if condition1
    then
        command1
    elif condition2 
    then 
        command2
    else
        commandN
    fi
    
    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
    
    num1=$[2*3]
    num2=$[1+5]
    if test $[num1] -eq $[num2]
    then
        echo '两个数字相等!'
    else
        echo '两个数字不相等!'
    fi
    
    for loop in 1 2 3 4 5
    do
        echo "The value is: $loop"
    done
    
    int=1
    while(( $int<=5 ))
    do
        echo $int
        let "int++"
    done
    
    #以上实例使用了 Bash let 命令,它用于执行一个或多个表达式
    
    a=0
    
    until [ ! $a -lt 10 ]
    do
       echo $a
       a=`expr $a + 1`
    done
    
    case 值 in
    模式1)
        command1
        command2
        ...
        commandN
        ;;
    模式2)
        command1
        command2
        ...
        commandN
        ;;
    esac
    
    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 跳出循环
    #!/bin/bash
    while :
    do
        echo -n "输入 1 到 5 之间的数字:"
        read aNum
        case $aNum in
            1|2|3|4|5) echo "你输入的数字为 $aNum!"
            ;;
            *) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
                break
            ;;
        esac
    done
    
    
    
  14. shell 函数

    [ function ] funname [()]
    
    {
    
        action;
    
        [return int;]
    
    }
    
    
    demoFun(){
        echo "这是我的第一个 shell 函数!"
    }
    echo "-----函数开始执行-----"
    demoFun
    echo "-----函数执行完毕-----"
    
    
    
  15. Shell 输入/输出重定向

    command >file  输出重定向到文件
    command > file 将输出以追加的方式重定向到 file。
    n > file 将文件描述符为 n 的文件重定向到 file。
    n >> file  将文件描述符为 n 的文件以追加的方式重定向到 file。
    n >& m 将输出文件 m 和 n 合并。
    << tag  将开始标记 tag 和结束标记 tag 之间的内容作为输入。
    
    # 同时替换输入和输出,执行command1,从文件infile读取内容,然后将输出写入到outfile中。
    command1 < infile > outfile
    # 错误重定向
    command 2 >> file
    # 如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写:
    command >> file 2>&1
    
    # here Document 是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。
    它的基本的形式如下:
    command << delimiter
        document
    delimiter
    
    它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。
    $ wc -l << EOF
        欢迎来到
        菜鸟教程
        www.runoob.com
    EOF
    3          # 输出结果为 3 行
    
    #!/bin/bash
    # author:菜鸟教程
    # url:www.runoob.com
    
    cat << EOF
    欢迎来到
    菜鸟教程
    www.runoob.com
    EOF
    
    #如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:
    command > /dev/null
    
    
  16. 文件包含:

    . filename   # 注意点号(.)和文件名中间有一空格
    或
    source filename
    
    test1.sh:
    
    #!/bin/bash
    url="http://www.runoob.com"
    
    test2.sh:
    
    #!/bin/bash
    . ./test1.sh  # source ./test1.sh
    echo "菜鸟教程官网地址:$url"
    

相关