关于shell脚本

 shell
// 内容大量来源于黑马程序员

1.  脚本第一行 ,魔法字符  #!  指定解释器【 必写 】
    #!/bin/bash`  表示以下内容使用bash解释器解析
    注1
        
    
2.  脚本增加可执行权限 (意思就是如果你的文件是灰色,仅仅代表个普通文件,使用之后,将变成了绿色,代表可执行文件。 在linux里不同的颜色代表不同的文件)
    [root@MissHou shell01]# chmod +x mytest.sh
----------------------------------
3. 标准方式执行脚本
    [root@MissHou shell01]# /shell01/mytest.sh
    或者
    [root@MissHou shell01]# ./mytest.sh

4. 非标准的执行方法(不建议)
 4.1 直接在命令行指定解释器执行
     [root@MissHou shell01]# bash mytest.sh
     [root@MissHou shell01]# sh mytest.sh
     [root@MissHou shell01]# bash -x mytest.sh
     
        -x:一般用于排错,查看脚本的执行过程
        -n:用来查看脚本的语法是否有问题
        
 4.2 使用`source`命令读取脚本文件,执行文件里的代码
    [root@MissHou shell01]# source mytest.sh 

------------------------------------    
5. 定义变量(区分大小写; 不能有特殊符号; 不能以数字开头; 对于有空格的字符串给变量赋值时,要用引号引起来)
    [root@MissHou ~]# A=hello            定义变量A
    [root@MissHou ~]# echo $A            调用变量A,要给钱的,不是人民币是美元"$"
    hello
    [root@MissHou ~]# echo ${A}        还可以这样调用,不管你的姿势多优雅,总之要给钱
    hello
    [root@MissHou ~]# A=world            因为是变量所以可以变,移情别恋是常事
    [root@MissHou ~]# echo $A            不管你是谁,只要调用就要给钱
    world
    [root@MissHou ~]# unset A            不跟你玩了,取消变量
    [root@MissHou ~]# echo $A            从此,我单身了,你可以给我介绍任何人    
    
6.     [root@MissHou ~]# A=1234567
    [root@MissHou ~]# echo $A
    1234567
    [root@MissHou ~]# echo ${A:2:4}        表示从A变量中第3个字符开始截取,截取4个字符
    3456

    说明:
    $变量名 和 ${变量名}的异同
    相同点:都可以调用变量
    不同点:${变量名}可以只截取变量的一部分,而$变量名不可以
    
7.     交互式定义变量(read)
    | -p   | 定义提示用户的信息                                         |
    | -n   | 定义字符数(限制变量值的长度)                             |
    | -s   | 不显示(不显示用户输入的内容)                             |
    | -t   | 定义超时时间,默认单位为秒(限制用户输入变量值的超时时间) |
    
    用法1:用户自己定义变量值
    [root@MissHou ~]# read name
    harry
    [root@MissHou ~]# echo $name
    harry
    [root@MissHou ~]# read -p "Input your name:" name
    Input your name:tom
    [root@MissHou ~]# echo $name
    tom

    用法2:变量值来自文件
    [root@MissHou ~]# cat 1.txt 
    10.1.1.1 255.255.255.0

    [root@MissHou ~]# read ip mask < 1.txt 
    [root@MissHou ~]# echo $ip
    10.1.1.1
    [root@MissHou ~]# echo $mask
    255.255.255.0
        
8.    定义有限制的变量(declare)    
    | -i | 将变量看成整数             | declare -i A=123                             |
    | -r | 定义只读变量               | declare -r B=hello                           |
    | -a | 定义普通数组;查看普通数组 |                                              |
    | -A | 定义关联数组;查看关联数组 |                                              |
    | -x | 将变量通过环境导出         | declare -x AAA=123456 等于 export AAA=123456 |
    
    [root@MissHou ~]# declare -i A=123
    [root@MissHou ~]# echo $A
    123
    [root@MissHou ~]# A=hello
    [root@MissHou ~]# echo $A
    0

    [root@MissHou ~]# declare -r B=hello
    [root@MissHou ~]# echo $B
    hello
    [root@MissHou ~]# B=world
    -bash: B: readonly variable
    [root@MissHou ~]# unset B
    -bash: unset: B: cannot unset: readonly variable
    
    
 9. 变量的分类

 ㈠ 本地变量 :当前用户自定义的变量。当前进程中有效,其他进程及当前进程的子进程无效。

 ㈡ 环境变量 :当前进程有效,并且能够被 子进程 调用。
     env查看当前用户的环境变量
     set查询当前用户的所有变量(临时变量与环境变量) 
     export 变量名=变量值    或者  变量名=变量值;export 变量名

 ㈢ 全局变量 :全局所有的用户和程序都能调用,且继承,新建的用户也默认能调用.
 
  解读相关配置文件 

    | 文件名               | 说明                                   | 备注                                                       |
    | -------------------- | -------------------------------------- | ---------------------------------------------------------- |
    | $HOME/.bashrc        | 当前用户的bash信息,用户 登录 时读取    | 定义别名、umask、函数等                                    |
    | $HOME/.bash_profile  | 当前用户的环境变量,用户 登录 时读取   |                                                            |
    | $HOME/.bash_logout   | 当前用户 退出 当前shell时最后读取      | 定义用户退出时执行的程序等                                 |
    | /etc/bashrc          | 全局的bash信息,所有用户都生效         |                                                            |
    | /etc/profile         | 全局环境变量信息                       | 系统和所有用户都生效                                       |
    | \$HOME/.bash_history | 用户的历史命令                         | history -w   保存历史记录         history -c  清空历史记录 |


     说明: 以上文件修改后,都需要重新 source 让其生效或者退出重新登录。

      用户登录 系统 读取 相关 文件的顺序 
      1. /etc/profile 
      2. $HOME/.bash_profile 
      3. $HOME/.bashrc 
      4. /etc/bashrc 
      5. $HOME/.bash_logout
      
   ㈣ 系统变量 (内置bash中变量)  : shell本身已经固定好了它的名字和作用.

    | 内置变量     | 含义                                                                        |
    | ------------ | ------------------------------------------------------------                 |
    | $?           | 上一条命令执行后返回的状态;状态值为0表示执行正常,非0表示执行异常或错误     |
    | $0           | 当前执行的程序或脚本名                                                      |
    | $#              | 脚本后面接的参数的个数                                                       |
    | $*             | 脚本后面所有参数,参数当成一个整体输出,每一个变量参数之间以空格隔开         |
    | $@           | 脚本后面所有参数,参数是独立的,也是全部输出                               |
    | $1~$9        | 脚本后面的位置参数,$1表示第1个位置参数,依次类推                          |
    | ${10}~${n}   | 扩展位置参数,第10个位置变量必须用{}大括号括起来(2位数字以上扩起来)         |
    | $$           | 当前所在进程的进程号,如`echo $$`                                          |
    | $!          | 后台运行的最后一个进程号 (当前终端)                                       |
    | !$           | 调用最后一条命令历史中的参数                                               |    

10.  $* :表示将变量看成一个整体
     $@ :表示变量是独立的    
      
        #!/bin/bash
        for i in "$@"
        do
        echo $i
        done

        echo "======我是分割线======="

        for i in "$*"
        do
        echo $i
        done

        [root@MissHou ~]# bash 3.sh a b c
        a
        b
        c
        ======我是分割线=======
        a b c
 
 
------------------------------------------------------------------------------
11. 定义数组
    ㈠ 数组分类

    - 普通数组:只能使用整数作为数组索引(元素的下标)
    - 关联数组:可以使用字符串作为数组索引(元素的下标)
    
    ㈡ 普通数组定义
       一次赋予一个值 
            数组名[索引下标]=值
            array[0]=v1
            array[1]=v2
            array[2]=v3
            array[3]=v4
 

        一次赋予多个值
        数组名=(值1 值2 值3 ...)
        array=(var1 var2 var3 var4)

        array1=(`cat /etc/passwd`) 将文件中每一行赋值给array1数组, 注意,语句中的顿号不要少, 比如cat前面
        array2=(`ls /root`)
        array3=(harry amy jack "Miss Hou")
        array4=(1 2 3 4 "hello world" [10]=linux)
        ```

    ㈢ 数组的读取
        declare -a                查看所有的数组
        echo ${array[0]}            获取数组里第一个元素
        echo ${array[*]}            获取数组里的所有元素
        echo ${#array[*]}            获取数组里所有元素个数
        echo ${!array[@]}        获取数组元素的索引下标
        echo ${array[@]:1:2}    访问指定的元素;1代表从下标为1的元素开始获取;2代表获取后面几个元素
    
    ㈣ 关联数组定义
     ①首先声明关联数组 declare -A asso_array1
     ② 数组赋值
       一次赋一个值 
            asso_array1[linux]=one
            asso_array1[java]=two
       一次赋多个值
            asso_array2=([name1]=harry [name2]=jack [name3]=amy [name4]="Miss Hou")        
            
    ③获取关联数组值
    echo ${asso_array1[linux]}

    
-------------------------------------------------------------------------------------------------------------------------------
12. 操作变量
     变量"内容"的删除和替换
     一个“%”代表从右往左去掉一个/key/
    两个“%%”代表从右往左最大去掉/key/
    一个“#”代表从左往右去掉一个/key/
    两个“##”代表从左往右最大去掉/key/

    举例说明:
    # url=www.taobao.com
    # echo ${#url}             获取变量的长度
    # echo ${url#*.}
    # echo ${url##*.}
    # echo ${url%.*}
    # echo ${url%%.*}
    
13. 替代: - 和 :-  +和:+ 等

    内容过多,参考
    https://www.cnblogs.com/zhaosunwei/p/6831529.html
    
    
------------------------------------------------------------------
14.  条件判断语法结构
  
         格式1: test  条件表达式
         格式2:  [  条件表达式 ]   注意两边都有空格,下面格式一样
         格式3:  [[  条件表达式 ]]  支持正则 =~    
            
         ㈠ 判断文件类型

        | 判断参数 | 含义                                         |
        | -------- | -------------------------------------------- |
        | -e       | 判断文件是否存在(任何类型文件)             |
        | -f       | 判断文件是否存在并且是一个普通文件           |
        | -d       | 判断文件是否存在并且是一个目录               |
        | -L       | 判断文件是否存在并且是一个软连接文件         |
        | -b       | 判断文件是否存在并且是一个块设备文件         |
        | -S       | 判断文件是否存在并且是一个套接字文件         |
        | -c       | 判断文件是否存在并且是一个字符设备文件       |
        | -p       | 判断文件是否存在并且是一个命名管道文件       |
        | -s       | 判断文件是否存在并且是一个非空文件(有内容) |
        
         
            test -e file                    只要文件存在条件为真
            [ -d /shell01/dir1 ]             判断目录是否存在,存在条件为真
            [ ! -d /shell01/dir1 ]        判断目录是否存在,不存在条件为真
            [[ -f /shell01/1.sh ]]        判断文件是否存在,并且是一个普通的文件    
    
         ㈡ 判断文件权限

        | 判断参数 | 含义                       |
        | -------- | -------------------------- |
        | -r       | 当前用户对其是否可读       |
        | -w       | 当前用户对其是否可写       |
        | -x       | 当前用户对其是否可执行     |
        | -u       | 是否有suid,高级权限冒险位 |
        | -g       | 是否sgid,高级权限强制位   |
        | -k       | 是否有t位,高级权限粘滞位  |
        
        
          ㈢ 判断文件新旧

            说明:这里的新旧指的是 文件的修改时间。

            | 判断参数         | 含义                                                         |
            | ---------------- | ------------------------------------------------------------ |
            | file1 -nt  file2 | 比较file1是否比file2新                                       |
            | file1 -ot  file2 | 比较file1是否比file2旧                                       |
            | file1 -ef  file2 | 比较是否为同一个文件,或者用于判断硬连接,是否指向同一个inode |
            
            
          ㈣ 判断整数

            | 判断参数 | 含义     |
            | -------- | -------- |
            | -eq      | 相等     |
            | -ne      | 不等     |
            | -gt      | 大于     |
            | -lt      | 小于     |
            | -ge      | 大于等于 |
            | -le      | 小于等于 |
            
           ㈤  判断字符串 

            | 判断参数           | 含义                                            |
            | ------------------ | ----------------------------------------------- |
            | -z                 | 判断是否为==空==字符串,字符串长度为0则成立     |
            | -n                 | 判断是否为==非空==字符串,字符串长度不为0则成立 |
            | string1 = string2  | 判断字符串是否相等                              |
            | string1 != string2 | 判断字符串是否相不等                            |


           ㈥ ==多重条件判断==

            | 判断符号   | 含义   | 举例                                                  |
            | ---------- | ------ | ----------------------------------------------------- |
            | -a 和 &&   | 逻辑与 | [ 1 -eq 1 -a 1 -ne 0 ]     [ 1 -eq 1 ] && [ 1 -ne 0 ] |
            | -o 和 \|\| | 逻辑或 | [ 1 -eq 1 -o 1 -ne 1 ]                                |        
            
    
15.    其他: 
    注意:在(( ))中,=表示赋值;==表示判断
        [root@server ~]# ((1==2));echo $?
    注意:双引号引起来,看作一个整体;= 和 == 在 [ 字符串 ] 比较中都表示判断
        [root@server ~]# a='hello world';b=world
        [root@server ~]# [ $a = $b ];echo $?
        [root@server ~]# [ "$a" = "$b" ];echo $?
        [root@server ~]# [ "$a" != "$b" ];echo $?
        [root@server ~]# [ "$a" == "$b" ];echo $?
        
-------------------------------------------------------------------------------------------------

17. 流程控制语句
    if [ condition ];then
            command
            command
    fi
    ---------
    if [ condition ];then
            command1
        else
            command2
    fi
    -----------
    if [ condition1 ];then
        command1      结束
    elif [ condition2 ];then
        command2       结束
    else
        command3
    fi
    -----------------
    
18. 查找进程
        pgrep命令:以名称为依据从运行进程队列中查找进程,并显示查找到的进程id
        选项
        -o:仅显示找到的最小(起始)进程号;
        -n:仅显示找到的最大(结束)进程号;
        -l:显示进程名称;
        -P:指定父进程号;pgrep -p 4764  查看父进程下的子进程id
        -g:指定进程组;
        -t:指定开启进程的终端;
        -u:指定进程的有效用户ID。    
        
19. 其他
 id $id &> /dev/null , 中  &> /dev/null 这条命令的意思是将标准输出和错误输出全部重定向到/dev/null中,也就是将产生的所有信息丢弃.  
 read -p "aaa" id

------------------------------------------------------------------------    

20. for循环语句

   ---------------
    20.1 for variable in {list}
             do
                  command 
                  command
                  …
             done
        ----------
        for variable in a b c
             do
                 command
                 command
             done
    --------------
    
    # for var in {1..10};do echo $var;done
    
    
    ----------
    20.2 for variable
            do
                command 
                command
                …
           done
   
    -----------
    20.3 for(( expr1;expr2;expr3 ))
        do
            command
            command
            …
        done
        ----------------
        # for (( i=1;i<=5;i++))
            do
                echo $i
            done
        
-----------------
21. while 表达式
    do
        command...
    done
        
    while  [ 1 -eq 1 ] 或者 (( 1 > 2 ))
      do
         command
         command
         ...
     done
    -------
   while循环打印:
        i=1
        while [ $i -le 5 ]
        do
            echo $i
            let i++
        done    
        
--------------

22. until循环

   until expression   [ 1 -eq 1 ]  (( 1 >= 1 ))
    do
        command
        command
        ...
    done
    
    ------
    i=1
    until [ $i -gt 5 ]
    do
        echo $i
        let i++
    done
    -------------------------
23. case语句
   说明:pattern表示需要匹配的模式

        case var in             定义变量;var代表是变量名
        pattern 1)              模式1;用 | 分割多个模式,相当于or
            command1            需要执行的语句
            ;;                  两个分号代表命令结束
        pattern 2)
            command2
            ;;
        pattern 3)
            command3
            ;;
                  *)              default,不满足以上模式,默认执行*)下面的语句
            command4
            ;;
        esac                            esac表示case语句结束    
        
    ---------------------
        例如:
            #!/bin/env bash
            case $1 in
                    start|S)
                    service apache start &>/dev/null && echo "apache 启动成功"
                    ;;
                    stop|T)
                    service apache stop &>/dev/null && echo "apache 停止成功"
                    ;;
                    restart|R)
                    service apache restart &>/dev/null && echo "apache 重启完毕"
                    ;;
                    *)
                    echo "请输入要做的事情..."
                    ;;
            esac
--------------- 

25. 其他
        exit            退出整个程序
        break           结束当前循环,或跳出本层循环
        continue     忽略本次循环剩余的代码,直接进行下一次循环
        shift            使位置参数向左移动,默认移动1位,可以使用shift 2

        :
        true
        false

----------------------------------------------------------------------------------    
26. 随机数RANDOM
    默认会产生0~32767的随机整数
     例;    产生0~100内的随机数 echo $[$RANDOM%101]
     
--------------------------------------------------------------------    
27. 函数

    函数名()
    {
      函数体(一堆命令的集合,来实现某个功能)   
    }    
    
    ----------
    或者
    function 函数名()
    {
       函数体(一堆命令的集合,来实现某个功能)
       echo hello
       echo world
    }
    
    ----------------
28. 函数中return说明:    
     1. return可以==结束一个函数==。类似于循环控制语句break(结束当前循环,执行循环体后面的代码)。
     2. return默认返回函数中最后一个命令状态值,也可以给定参数值,范围是0-256之间。
     3. 如果没有return命令,函数将返回最后一个指令的退出状态值。    
    ----------- 
29.  函数调用
    1.  写个函数,叫fun1.sh
        #!/bin/bash
        hello(){
        echo "hello lilei $1"
        }
    2. 当前命令行调用
      source命令用法:source FileName 作用:在当前bash环境下读取并执行FileName中的命令。 该命令通常用命令".”来替代
     [root@MissHou shell04]# source fun1.sh (或者 . fun1.sh )
     [root@MissHou shell04]# 
     [root@MissHou shell04]# hello 888
        hello lilei 888    
    ---------
         
30. 定义到用户的环境变量中(当用户打开bash的时候会读取该文件)
    [root@MissHou shell05]# vim ~/.bashrc 
    文件中增加如下内容:
    hello(){
    echo "hello lilei $1" 
    }        
    -----------
    
31.  脚本中调用
        #!/bin/bash
        hello(){
        echo "hello lilei $1"
        }
        hello      // 直接这样写就调用了
-------------------------------------

32.         
        
        
        
 
        
        
        
        
        
        
        
********************************************
*****************************************
    
注意:
1.
    如果直接将解释器路径写死在脚本里,可能在某些系统就会存在找不到解释器的兼容性问题,所以可以使用:`#!/bin/env 解释器`
    #!/bin/env bash        
        
        
        
        
        
        
        
        
        
        
        
        
        
        

    
        


        
    
    
    
    
    
    
    
    
    
    

猜你喜欢

转载自blog.csdn.net/qq_34085100/article/details/116921634