• Linux bash总结(一) 基础部分(适合初学者学习和非初学者参考)


    早上起来,外面的雨下的稀里哗啦……本来事先约定好的朋友聚餐也因此取消了。
    心想,闲着也是闲着,不如将自己所学的bash脚本知识梳理一遍。一来,可以给bash初学者提供一个学习平台;再者,非初学者书写脚本时,也能以此为参考。若您在阅读时,文章能给您一点点启发,那我的目的就达到了。

    花了3天功夫,终于整理完毕了。可能还有许多需要完善的地方,希望读者能给出宝贵的意见!鉴于文章内容比较多,下面先介绍一下主要内容。

    第一部分 bash简介
        —— 对bash进行简要介绍
    第二部分 bash示例和书写流程
        —— 以一个简单的bash为例,说明书写、执行bash的流程
    第三部分 bash基础语法
       —— 本章内容比较多,主要介绍if...else...条件判断,for循环等等。对于有编程基础的朋友来说应该很容易,没有编程基础也没关系;参考文章中的实例,应该很容易就能掌握本章知识。
    第四部分 bash数组
       —— 介绍bash数组的定义和相关操作
    第五部分 函数
       —— 介绍bash函数的定义及调用方法
    第六部分 数值运算
       —— 介绍+、-、*、/等操作
    第七部分 字符运算
       —— 介绍字符串操作
    第八部分 bash自带参数
       —— 说明bash中自带的参数,它们在编写bash脚本时中经常会被用到。
    第九部分 bash调试
       —— 说明bash常用的调试方法
    第十部分 bash注释
       —— 说明bash中添加单行注释以及区域注释的常用方法
    第十一部分 bash内建指令
       —— 介绍bash中常用的内建命令
    第十二部分 bash实例
       —— 以一个实例来总结基础部分

    第一部分 bash简介

    在介绍bash之前,需要先介绍它的起源——shell。shell俗称壳,它是指UNIX系统下的一个命令解析器;主要用于用户和系统的交互。UNIX系统上有很多种Shell。首个shell,即Bourne Shell,于1978年在V7(AT&T的第7版)UNIX上推出。后来,又演变出C shell、bash等不同版本的shell。
    bash,全称为Bourne-Again Shell。它是一个为GNU项目编写的Unix shell。bash脚本功能非常强大,尤其是在处理自动循环或大的任务方面可节省大量的时间。bash是许多Linux平台的内定Shell,这也是我们介绍它主要的原因。

    第二部分 bash示例和书写流程

    1 新建文件test.sh

    $ touch test.sh

    2 添加可执行权限

    $ chmod +x test.sh

    3 编辑test.sh,test.sh内容如下:

    #!/bin/bash
    
    echo "hello bash"
    
    exit 0

    说明:
    #!/bin/bash : 它是bash文件声明语句,表示是以/bin/bash程序执行该文件。它必须写在文件的第一行!
    echo "hello bash" : 表示在终端输出“hello bash”
    exit 0 : 表示返回0。在bash中,0表示执行成功,其他表示失败。
    4 执行bash脚本

    $ ./bash

    在终端输出“bash hello”

    第三部分 bash基础语法

    1 条件判断

    条件判断有2中格式,分别是“test EXPRESSION”和“[ EXPRESSION ]”。
    “test”判断语句,在实际中应用的比较少;相反的,“[]”判断语句应用很广。下面分别对它们进行介绍

    1.1 test判断语句

    基本格式

    test EXPRESSION

    格式说明

    test是关键字,表示判断;
    EXPRESSION是被判断的语句。
    关于EXPRESSION的说明,参考如下:

    应用实例

    一、判断文件/home/skywang/123.txt是不是文件

    $ test -f /home/skywang/123.txt

    其他说明

    在linux系统下,可以通过以下命令去测试上面的实例
    # 切换到执行目录(如切换到/home/skywang)

    $ cd /home/skywang

    # 判断123.txt是不是文件

    $ test -f 123.txt

    # 输出判断结果,0表示成功,其他表示失败。
    # 其中,echo表示输出文本到当前终端,$?表示上一命令的执行结果(在linux中bash中,命令成功返回0,失败返回其他)。

    $ echo $?


    1.2 []条件判断

    基本格式

    [ EXPRESSION ]

    格式说明
    中括号的左右扩弧和EXPRESSION之间都必须有空格!
    关于EXPRESSION的说明,参考如下:

    应用实例
    一、判断文件/home/skywang/123.txt是否存在

    $ [ -f /home/skywang/123.txt ]

    二、判断变量val是否等于字符串“skywang”

    $ [ "$val" = "skywang" ]

    三,判断变量num是否等于数字100

    $ [ "$num" -eq "100" ]


    1.3 测试逻辑表达式

    基本格式
    -a : 逻辑与,操作符两边均为真,结果为真,否则为假。
    -o : 逻辑或,操作符两边一边为真,结果为真,否则为假。
    ! : 逻辑否,条件为假,结果为真。
    应用实例
    一、判断文件123.txt是不是可读写

    $ [ -r 123.txt -a -w 123.txt ]

    等价于

    $ [ -r 123.txt ] && [ -w 123.txt ]

    二、判断变量num是不是等于数字101或102

    $ [ "$num" -eq "101" -o "$num" -eq "102" ]

    等价于

    $ [ -r 123.txt ] || [ -w 123.txt ]

    三、判断文件123.txt是不是不可读

    $ [ ! -r 123.txt ]

    2 if then else语句

    基本格式
    if 条件1
    then 命令1
    elif 条件2
    then 命令2
    else 命令3
    if
    格式说明
    if 语句必须以单词 fi 终止。elif 和 else 为可选项,如果语句中没有否则部分,那么就不需要 elif 和 else 部分。if 语句可以有许多 elif 部分。最常用的 if 语句是 if then fi 结构。
    应用实例
    一、判断文件文件123.txt是否存在,存在则输出“file exist”;没有则输出“file not exist”。bash文件内容如下:

    #!/bin/bash
    
    if [ -f 123.txt ];then
    echo "file exist"
    else
    echo "file not exist"
    fi
    
    exit 0

    二、提示用户输入值。若输入的值小于0,则输出“negtive number”;若等于0,则输出“number zero”,否则,输出“positive number”。bash文件内容如下:

    #!/bin/bash 
    
    # 提示用户输入一个值 
    echo -n "please input a number:"
    
    # 保存用户输入的值到num中 
    read num 
    
    if [ "$num" -lt "0" ];then 
    # 小于0,则输出“negtive number” 
    echo "negtive number" 
    elif [ "$num" -gt "0" ];then 
    # 大于0,则输出“positive number” 
    echo "positive number" 
    else
    # 大于0,则输出"number zero" 
    echo "number zero"
    fi
    
    exit 0

    3 case语句

    case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。
    基本格式
    case 值 in
    模式1}
    命令1
    ...
    ;;
    模式2)
    命令2
    ...
    ;;
    esac
    格式说明
    “模式”部分可能包括元字符,即:
    * 任意字符。
    ? 任意单字符。
    [..] 类或范围中任意字符
    应用实例
    一、提示用户输入Y/y或N/n。若输入Y/y,则输出“yes”;若输入N/n,则输出“no”;否则,“incorrect input”。bash文件内容如下:

    #!/bin/bash
    
    # 提示用户输入一个值
    echo -n "are you femail(Y/N):"
    
    # 保存用户输入的值到val中
    read val
    
    case $val in
    Y|y) 
    # 用户输入Y或y 
    echo "yes"
    ;;
    N|n)
    # 用户输入N或n
    "no"
    ;; 
    *)
    # 其它输入
    echo "incorrect input"
    ;; 
    esac 
    
    exit 0

    4 for循环

    基本格式
    for 变量名in列表
    do
    命令1
    命令2...
    done
    格式说明
    当变量值在列表里, for循环即执行一次所有命令,使用变量名访问列表中取值。命令可为任何有效的 shell命令和语句。变量名为任何单词。 in列表用法是可选的,如果不用它, for循环使用命
    令行的位置参数。
    应用实例
    一、输入当前文件夹的一级子目录中文件名字。bash脚本内容如下:

    #!/bin/bash
    
    # 将ls的结果保存到变量CUR_DIR中
    CUR_DIR=`ls`
    
    # 显示ls的结果
    echo $CUR_DIR
    
    for val in $CUR_DIR
    do
    # 若val是文件,则输出该文件名
    if [ -f $val ];then
    echo "FILE: $val"
    fi 
    done
    
    exit 0

     

    二、输出1-10之间数字的总和。bash脚本内容如下:

    #!/bin/bash
    
    sum=0
    for ((i=1;i<10;i++)) 
    do 
    ((sum=$sum+$i))
    done 
    
    echo "sum=$sum" 
    
    exit 0

      

    5 until循环

    until循环执行一系列命令直至条件为真时停止。until循环与 while循环在处理方式上刚好相反。一般 while循环优于until循环,但在某些时候 — 也只是极少数情况下, until循环更加有用。
    基本格式
    until 条件
    命令1
    ...
    done
    格式说明
    条件可为任意测试条件,测试发生在循环末尾,因此循环至少执行一次 — 请注意这一点。
    应用实例
    一、从0开始逐步递增,当数值等于5时,停止递增。Bash脚本内容如下:

    #!/bin/bash 
    
    # 设置起始值为0
    val=0
    
    until [ "$val" -eq "5" ]
    do
    # 输出数值
    echo "val=$val"
    # 将数值加1
    ((val++))
    done
    
    exit 0

    6 while循环

    基本格式
    while 命令
    do
    命令1
    命令2
    ...
    done
    应用实例
    一、从0开始逐步递增,当数值等于5时,停止递增。Bash脚本内容如下:

    #!/bin/bash 
    
    # 设置起始值为0
    val=0
    
    while [ "$val" -lt "5" ]
    do
    # 输出数值
    echo "val=$val"
    # 将数值加1
    ((val++))
    done
    
    exit 0


    7 使用break和continue控制循环

    基本格式
    break命令允许跳出循环。
    continue命令类似于 break命令,只有一点重要差别,它不会跳出循环,只是跳过这个循环步。
    应用实例
    一、[break应用]从0开始逐步递增,当数值等于5时,停止递增。Bash脚本内容如下:

    #!/bin/bash
    
    # 设置起始值为0
    val=0
    
    while true
    do
    if [ "$val" -eq "5" ];then
    # 如果val=5,则跳出循环
    break;
    else
    # 输出数值
    echo "val=$val"
    # 将数值加1
    ((val++))
    fi 
    done
    
    exit 0

     

    二、[continue应用]从0开始逐步递增到10:当数值为5时,将数值递增2;否则,输出数值。Bash脚本内容如下:

    #!/bin/bash
    
    # 设置起始值为0
    val=0
    
    while [ "$val" -le "10" ]
    do
    if [ "$val" -eq "5" ];then
    # 如果val=5,则将数值加2
    ((val=$val+2))
    continue;
    else
    # 输出数值
    echo "val=$val"
    # 将数值加1
    ((val++))
    fi 
    done
    
    exit 0

    第四部分 bash数组

    1 数组定义

    1. array=(10 20 30 40 50)
    一对括号表示是数组,数组元素用“空格”符号分割开。引用数组时从序号0开始。

    2. 除了上面的定义方式外,也可以单独定义数组:
    array[0]=10
    array[1]=20
    array[2]=30
    array[3]=40
    array[4]=50

    3. var="10 20 30 40 50"; array=($var)


    2 数组操作

    (01) 显示数组中第2项

    $ echo ${array[i]}
    说明:数组是从序号0开始计算(即第1项为array[0])。

    (02) 显示数组中的所有元素

    $ echo ${array[@]}
    或者
    $ echo ${array[*]}

    (03) 显示数组长度

    $ echo ${#array[@]}
    或者
    $ echo ${#array[*]}

    (04) 删除数组第2项元素

    $ unset array[1]
    说明:
    unset仅仅只清除array[1]的值,并没有将array[1]删除掉

    (05) 删除整个数组

    $ unset array

    (06) 输出数组的第1-3项

    $ echo ${array[@]:0:3}
    说明:
    参考“${数组名[@或*]:起始位置:长度}”

    (07) 将数组中的0替换成1

    $ echo ${a[@]/0/1}
    说明:
    ${数组名[@或*]/查找字符/替换字符

    第五部分 函数

    1 函数定义

    基本格式
    function 函数名()
    {
    ...
    }

    格式说明
    function可有可无。但建议保留,因为保留的话看起来更加直观。

    应用实例

    function foo()
    {
        # 定义局部变量i
        local i=0 
        # 定义局部变量total=传入foo的参数总数
        local total=$#
        # 输出参数总数
        echo "total param =$total"
        # 输出传入foo的每一个参数
        for val in $@
        do  
            ((i++))
            echo "$i -- val=$val"
        done
    
        # 返回参数总数
        return $total
    }

    2 函数调用和传参

    调用方法

    直接通过函数名去调用。

    应用实例

    foo param1 param2 param3

    说明:

    调用函数foo,并传入param1 param2 param3三个参数

    3 函数返回值

    使用方法

    return 返回值

    方法说明

    例如,foo param1 param2 param3之后,再调用$?就是上次调用的返回值

    4 应用实例

    编辑一个函数foo:打印foo的输入参数的总数,并输入每个参数和参数对应的序号。

    #!/bin/bash
    
    function foo()
    {
        # 定义局部变量i
        local i=0 
        # 定义局部变量total=传入foo的参数总数
        local total=$#
        # 输出参数总数
        echo "total param =$total"
        # 输出传入foo的每一个参数
        for val in $@
        do  
            ((i++))
            echo "$i -- val=$val"
        done
    
        # 返回参数总数
        return $total
    }
    
    foo
    foo param1 param2 param3
    # 输出foo param1 param2 param3的返回值
    echo "return value=$?"
    
    exit 0

     

    输出结果:

    total param =0
    total param =3
    1 -- val=param1
    2 -- val=param2
    3 -- val=param3
    return value=3

    第六部分 数值运算

    数值比较请参考"第三部分"的1.2节,本部分只介绍数值运算。

    常用的4种数值运算说明
    数值元算主要有4种实现方式:(())、let、expr、bc。
    工作效率:
    (()) == let > expr > bc
    (01), (())和let是bash内建命令,执行效率高;而expr和bc是系统命令,会消耗内存,执行效率低。
    (02), (())、let和expr只支持整数运算,不支持浮点运算;而bc支持浮点运算。

    下面分别介绍这4种实现方式的使用方法。
    应用实例一:分别用上面四种方式实现"3*(5+2)"。

    #!/bin/bash
    
    # 数值i=3*(5+2) (方法一:$(())实现)
    val=$((3*(5+2)))
    echo "val=$val"
    
    # 数值i=3*(5+2) (方法二:let实现)
    let "val=3*(5+2)"
    echo "val=$val"
    
    # 数值i=3*(5+2) (方法三:expr实现)
    val=`expr 3 \* \( 5 + 2 \)`
    echo "val=$val"
    
    # 数值i=3*(5+2) (方法四:bc实现)
    val=`echo "3*(5+2)"|bc`
    echo "val=$val"
    
    exit 0

    应用实例二:分别勇上面四种方式实现“数值+1”。

    #!/bin/bash
    
    val=0
    # 数值加1 (方法一)
    ((val++))
    echo "val=$val"
    
    val=0
    # 数值加1 (方法二)
    let val++
    echo "val=$val"
    
    val=0
    # 数值加1 (方法三)
    val=`expr $val + 1`
    echo "val=$val"
    
    val=0
    # 数值加1(方法四)
    val=`echo "$val+1"|bc`
    echo "val=$val"
    
    exit 0

    应用实例三:计算1/3,保留3位小数。

    #!/bin/bash
    
    # 数值i=3*(5+2) (方法四:bc实现)
    val=`echo "scale=3; 1/3"|bc`
    echo "val=$val"
    
    exit 0

    第七部分 字符运算

    1 字符串定义

     

    2 字符串操作

    2.1 string操作公式表

    2.2 应用实例

    首先,我们定义个str字符串变量,然后再对此变量进行字符串操作。

    $ str="hello world"

    (01) 显示字符串长度

    $ echo ${#str}

    (02) 提取world

    $ echo ${str:6}

    (03) 提取or

    $ echo ${str:7:2}

    (04) 删除hello

    $ echo ${str#hello}
    或
    $ echo ${str#*lo}

    (05) 删除world

    $ echo ${str%world}$ echo ${str%wo*}

    (06) 将所有的字符“l”替换为“m”

    $ echo ${str//l/m}

     

    第八部分 bash自带参数

    第九部分 bash调试

    1 bash命令调试

    bash [-nvx] scripts.sh
    选项与参数:
    -n :不要执行 script,仅查询语法的问题;
    -v :再执行 sccript 前,先将 scripts 的内容输出到屏幕上;
    -x :将使用到的 script 内容显示到屏幕上,这是很有用的参数!
    例如,想要执行bash脚本,并查看bash的调用流程,可以通过以下命令:

    $ bash -x test.sh

    2 echo调试
    echo [OPTION] STRING
    -n : 输出内容之后,不换行。默认是输入内容之后,换行。
    -e : 开启反斜线“\”转义功能
    -E : 开启反斜线“\”转义功能(默认)。
    例如,输出“please input a number:”之后不换行。

    $ echo -n "please input a number:"

    3 printf
    和echo一样,printf也能用于输出。语法格式和C语言中printf一样。
    例如,输出“hello printf”之后换行。

    $ printf "hello printf\n"

    第十部分 bash注释

    1 单行注释

    # echo "single line"
    说明:#放在文件开头,表示注释掉本行。

    2 多行注释

    可以通过以下两种方法实现多行注释:

    :||{
    ....被注释的多行内容
    }

    或者

    if false ; then
    ....被注释的多行内容
    fi

    第十一部分 bash内建指令

    1 内建命令查看方法

    基本格式
    type cmd
    格式说明
    type是命令关键字,cmd表示查看的命令;若输出builtin,则该命令是bash的内建命令。
    例如:

    $ type echo

    除此之外,用户也可以通过man bash或者man builtins查看bash的全部内置命令.

    2 常用内建命令说明

    (01)echo
    命令:echo arg
    功能:在屏幕上显示出由arg指定的字串
    (02)read
    命令格式:read变量名表
    功能:从标准输入设备读入一行,分解成若干字,赋值给bash程序内部定义的变量
    (03)shift
    命令:shift [N] (N为大于0的整数;当N省略时,等价与于“shift 1”)
    功能:所有的参数依次向左移动N个位置,并使用$#减少N,直到$#=0为止。
    (04)alias
    命令:alias name='value'
    功能:别名。用name替换value,value要用单引号括住。
    (05)export
    命令:export变量名[=变量值]
    功能:export可以把bash的变量向下带入子bash(即子bash中可以使用父bash的变量),从而让子进程继承父进程中的环境变量。但子bash不能用export把它的变量向上带入父bash。
    (06)readonly
    命令:readonly 变量名
    功能:定义只读变量。不带任何参数的readonly命令将显示出所有只读变量。
    (07)exec
    命令:exec 命令参数
    功能:当bash执行到exec语句时,不会去创建新的子进程,而是转去执行指定的命令,当指定的命令执行完时,该进程(也就是最初的bash)就终止了,所以bash程序中exec后面的语句将不再
    被执行。
    (08)"."(点)
    命令:. bash程序文件名
    功能:使bash读入指定的bash程序文件并依次执行文件中的所有语句。
    (09)exit
    命令:exit N
    功能:退出Shell程序。在exit之后可有选择地指定一个数位作为返回状态。

    第十二部分 bash实例

    实例一:备份/更新文件的脚本
    01, 编写一个脚本文件backup.sh,备份android、kernel或uboot中的文件,备份的时候要保留文件在备份文件夹(即保留文件的相对路径)。
    (01) 新建list_file.txt,并在list_file.txt中记录要备份的文件的路径。
    (02) 当执行“./backup.sh bb”命令时:backup.sh会新建bb目录,然后读取list_file.txt中记录的文件路径,并将记录的文件路径对应的文件备份到bb目录下。
    (03) 当执行“./backup.sh tt”命令时,backup.sh会判断是否存在tt目录,若存在tt目录的话,则tt中的文件更新到list_file.txt所记录的文件路径;否则的话,不更新文件。

    脚本内容如下:

    #!/bin/bash
    
    ##############################NOTE############################
    #
    # AUTHOR      : skyWang
    # DATE        : 2012-07-16
    # DESCRIPTION : 用于备份文件 or 更新文件
    #
    #               1. 备份文件
    #               (1) 备份命令        :  ./run.sh bb
    #               (2) 备份文件所在目录:  bb
    #                   这个是在步骤(1)之后,在当前目录下自动建立bb目录
    #              
    #               2. 更新文件
    #               (1) 更新命令        :  ./run.sh tt
    #               (2) 更新文件所在目录:  tt
    #                   这个是必须在步骤(1)之前已经存在的目录。因为,就是为了用tt目录中的文件去替换到目标文件。
    #
    # OTHER       : 1. list_file.txt 文件说明(即,list_file.txt中的文件必须满足一下条件):
    #               “变量COMMPATH_PATH的值”和“list_file.txt中的每一行内容”组合起来得到的完整路径所对应的文件,必须存在!
    #
    #               例如: COMMON_PATH=/root/
    #                      list_file.txt中有以下1行内容:
    #                      android/build/core/Makefile
    #               这样,“变量COMMPATH_PATH的值”和“list_file.txt中的行”组合起来得到的完整路径就是:
    #                      /root/android/build/core/Makefile
    #
    #                “/root/android/build/core/Makefile”这个文件必须存在于电脑中。
    #
    #               (1)若list_file.txt满足以上条件,运行“./run.sh bb”就可以备份“/root/android/build/core/Makefile”。
    #                    备份时,会自动(在当前目录下)建立目录“bb”,并将文件备份到“bb”目录下
    #               (2)若将bb目录重命名成tt,运行“./run.sh tt”就可以将“tt”中的文件更新到“/root/android/build/core/Makefile”。
    #               
    #
    ##############################NOTE############################
    
    
    #########TODO...START#########
    # 假设android、kernel、uboot在同一级目录;
    # 则,COMMON_PATH是它们所在目录的路径。
    COMMON_PATH=/home/skywang/a8/gingerbread/code/
    #########TODO...END###########
    
    
    #########CONSTANT...START#########
    LIST_FILE="list_file.txt"
    B_FOLDER="bb/"
    T_FOLDER="tt/"
    # android工程的文件夹名字
    ANDROID_FOLDER="android"
    # kernel工程的文件夹名字
    KERNEL_FOLDER="kernel"
    # uboot工程的文件夹名字
    UBOOT_FOLDER="uboot"
    # android长度
    ANDROID_FOLDER_LEN=`expr length "$ANDROID_FOLDER"`
    # kernel长度
    KERNEL_FOLDER_LEN=`expr length "$KERNEL_FOLDER"`
    # uboot长度
    UBOOT_FOLDER_LEN=`expr length "$UBOOT_FOLDER"`
    #########CONSTANT...END###########
    
    
    # 功能说明:根据源文件和目标文件所在完整路径,将源文件更新到目标文件
    #           更新成功的话,输出更新的起止路径;否则,打印错误信息
    # 输入参数:src_full_path    —— 源文件所在完整路径。
    #           dst_full_path    —— 目标文件所在完整路径。
    #           例如:src_full_path="tt/android/hardware/libsensor/sensors.cpp"
    #                 dst_full_path="/home/skywang/mnt/sda6/a8/a72/3g/iceCreamSandwish/code/android/hardware/libsensor/sensors.cpp"
    function func_update_file_by_path()
    {
        local src_full_path=$1
        local dst_full_path=$2
        local dst_full_dir=`dirname $dst_full_path`
    
        if [ -f "$src_full_path" ];then
            if [ -e "$dst_full_path" ] || [ -d "$dst_full_dir" ];then
                cp -v $src_full_path $dst_full_path
            else
                mkdir -p $dst_full_dir
                cp -v $src_full_path $dst_full_path
            fi
        else
            echo copy file ERROR:
            echo file $src_full_path not existes!!!
        fi
    }
    
    
    # 功能说明:将“输入文件”中全部文件全部更新到代码中
    #           更新成功的话,输出更新的起止路径;否则,打印错误信息
    # 输入参数:input_file    ——    “输入文件”所在的完整路径
    #           例如:input_file="/home/skywang/mnt/sda6/a8/a72/3g/iceCreamSandwish/backup/exmaple/list_file.txt"
    function func_push_files()
    {
        local input_file=$1
        local full_path
        local backup_path
        local count=0
    
        while read -r line
        do
            let count=`expr $count + 1`
            if [ `expr match $line $ANDROID_FOLDER` == "$ANDROID_FOLDER_LEN" ] || 
               [ `expr match $line $KERNEL_FOLDER` == "$KERNEL_FOLDER_LEN" ] || 
               [ `expr match $line $UBOOT_FOLDER` == "$UBOOT_FOLDER_LEN" ];then
                echo "$count : right push path"
                src_path=${T_FOLDER}${line}
                dst_path=${COMMON_PATH}${line}
                func_update_file_by_path $src_path $dst_path
            else
                echo "$count : push file $line is invalidate!"
            fi
        done < $input_file
    
    }
    
    
    # 功能说明:根据源文件所在完整路径,将源文件拷贝到另一个目录下
    #           备份成功的话,输出备份的起止路径;否则,打印错误信息
    # 输入参数:src_full_path    —— 源文件所在完整路径。
    #           dst_full_dir    —— 目标路径
    #           例如:src_full_path="/home/skywang/mnt/sda6/a8/a72/3g/iceCreamSandwish/code/android/hardware/libsensor/sensors.cpp"
    #                 dst_full_dir="bb/android/hardware/libsensor/"
    function func_backup_file_by_path()
    {
        local src_full_path=$1
        local dst_full_dir=$2"/"
    
        if [ -f "$src_full_path" ];then
            if [ -d "$dst_full_dir" ];then
                cp -v $src_full_path $dst_full_dir
            else
                mkdir -p $dst_full_dir
                cp -v $src_full_path $dst_full_dir
            fi
        else
            echo backup file ERROR:
            echo file $src_full_path not existes!!!
        fi
    }
    
    # 功能说明:将“输入文件”中全部文件全部做备份。
    #           备份成功的话,输出备份的起止路径;否则,打印错误信息
    # 输入参数:input_file    ——    “输入文件”所在的完整路径
    #           例如:input_file="/home/skywang/mnt/sda6/a8/a72/3g/iceCreamSandwish/backup/exmaple/list_file.txt"
    function func_pull_files()
    {
        local input_file=$1
        local full_path
        local backup_path
        local count=0
    
        while read -r line
        do
            let count=`expr $count + 1`
            if [ `expr match $line $ANDROID_FOLDER` == "$ANDROID_FOLDER_LEN" ] || 
               [ `expr match $line $KERNEL_FOLDER` == "$KERNEL_FOLDER_LEN" ] || 
               [ `expr match $line $UBOOT_FOLDER` == "$UBOOT_FOLDER_LEN" ];then
                echo "$count : right pull path"
                full_path=${COMMON_PATH}${line}
                backup_path=${B_FOLDER}`dirname $line`
                func_backup_file_by_path $full_path $backup_path
            else
                echo "$count : pull file $line is invalidate!"
            fi
        done < $input_file
    
    }
    
    func_copy_all_files()
    {
        if [ ! -e "$LIST_FILE" ];then
            echo ERROR: the file $LIST_FILE not existes!!!
            exit 1
        fi
    
    
        case $1 in
            BB|bb)
                echo -e "\n\n==============backup files=============="
                func_pull_files $LIST_FILE && exit 0
                ;;
            TT|tt)
                echo -e "\n\n==============syn    files=============="
                func_push_files $LIST_FILE && exit 0
                ;;
            *)
                echo ERROR parameter: please input parameter \"bb\" to backup, or \"tt\" to update!!!
                ;;
    
        esac
    }
    
    func_copy_all_files $1
    
    exit 0

    点击下载:bash实例

        

  • 相关阅读:
    vim内外部鼠标复制 粘贴
    nginx 问题解决nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
    Installation of the latest version of netease-cloud-music on Fedora 30 linux platform
    Linux就该这么学11学习笔记
    Linux就该这么学10学习笔记
    css day2
    Linux就该这么学09学习笔记
    Linux就该这么学08学习笔记
    css day1
    Linux就该这么学07学习笔记
  • 原文地址:https://www.cnblogs.com/skywang12345/p/3106570.html
Copyright © 2020-2023  润新知