• Linux Shell编程


    一、什么是Shell
    在Linux中,系统会为每个用户运行一个shell(外壳)程序。
    shell程序是一个命令行解释器,交互式地解释和执行用户输入的命令。
    shell还是一种解释性的程序设计语言,定义了变量和函数,数组,程序控制结构等很多高级语言支持的特性。

    二、shell编程用在什么地方
    shell一般用于批量命令执行,用来管理,监控系统等。

    三、shell语法详解
    1.程序示例,输出"hello world"
    firstshell

    #!/bin/bash
    echo "hello world"

    改变文件的访问权限,使其具有可执行属性
    chmod +x firstshell

    输出结果:

    程序的第一行必须是 #!/bin/bash
    指定系统用#!后的命令/bin/bash来运行此文件。

    2.变量
    varname=值
    需要注意的是:
    1)"="前后不能有空格
    2)变量默认都是字符串格式的
    3)使用变量,必须加上"$"符号,否则取到的是变量名本身
    4)若变量名和其他字符串混淆在一起时,需要加上{}来区分变量名
    如下例所示:
    myshell

    #!/bin/bash
    var1=1
    var2=2
    var3=$var1+$var2 #变量默认是字符串,所以输出为1+2
    var4 =4 #等号前后有空格,报错
    echo $var1
    echo $var2
    echo $var3
    echo $var4
    echo "var1 is the ${var1}st"

    输出结果:

    那么,我们如何将var1,var2作为数值类型来相加呢?
    方法一:使用C风格表示式,((表示式))
    ((var3=$var1+$var2))
    或((var3=var1+var2))

    方法二:使用shell中的let命令
    let 'var3=var1+var2' #注意不能加'$'符号,否则报错

    方法三:调用expr外部程序,效率较低,尽量少用
    var3=$(expr $var1 + $var2) #expr函数需要三个参数,$var1,+,$var2

    3.流程控制
    1)if语句
    结构如下:

    if
    then
    elif
    then
    else
    fi

    或者(then写在if的后面,但是要加分号;)

    if ...;then
    elif...;then
    else
    fi

    示例如下:
    myshell

    #!/bin/bash
    var1=1
    var2=2
    if ((var1==var2))
    then
        echo "var1=var2"
    elif ((var1>var2))
    then
        echo "var1>var2"
    else
        echo "var1<var2"
    fi

    输出结果:

    bash中有一些常用的条件判断表达式,使用方法:[ 条件判断表达式 ]
    -f "filename":判断是否是文件
    -x "/bin/ls":判断/bin/ls是否存在并有可执行权限
    -n "$var":判断$var变量是否有值
    "$a"=="$b":判断$a和$b是否相等

    2)&&和||操作符
    &&:逻辑与操作符
    ||: 逻辑或操作符

    3)case语句
    case表达式用来匹配给定的字符串,和C中的switch...case匹配的是数字不同。

    case ... in
    ...) 
        do something;;
    ...)
        do something;;
    esac

    下例中,我们写了一个程序,用来解压bzip2,gzip,zip类型的压缩文件。
    代码如下:

    #!/bin/bash
    ftype=$(file $1)
    echo "$ftype"
    case "$ftype" in
    "$1: Zip archive"*)
        unzip "$1";;
    "$1: gzip compressed"*)
        gunzip "$1";;
    "$1: bzip2 compressed"*)
        bunzip2 "$1";;
    *)
        echo "File $1 can not be unconpressed";;
    esac

    输出结果:

    其中$1表示输入的第一个参数

    4)select循环语句
    select循环适合交互式的场合,格式如下:

    select var in ...;do
    ...
    done

    示例代码如下:

    #!/bin/bash
    echo "what is your favourite OS?"
    select var in "RedHat" "Ubuntu" "Free BSD" "Other";do
        echo "hello $var"
        break;
    done
    echo "you have selected $var"

    输出结果:

    5)while/for循环
    while循环

    while...;do
        ...
    done

    for循环

    for var in ...;do
        ...
    done

    示例代码如下:

    #!/bin/bash
    for var in A B C;do
        echo "var is $var"
    done

    输出结果:

    4.shell里的一些特殊符号
    1)*:表示通配符
    双引号可以防止通配符但允许变量扩展
    单引号(或转义字符)的限制更严格,可防止任何变量扩展;
    示例代码如下:

    #!/bin/bash
    echo *.c
    echo "*.c"
    echo '*.c'
    echo *.c
    
    echo $SHELL
    echo "$SHELL"
    echo '$SHELL'
    echo $SHELL

    输出结果:

    2)命令行参数
    $1:命令行的第一个参数
    $#:命令行参数的个数
    $@:命令行的所有参数
    $*:所有命令行参数作为一个参数
    shift n:去掉前面的n个参数

    示例如下:

    #!/bin/bash
    help()
    {
    cat << HELP
       本例程序用来获取命令行参数
       使用了命令:myshell -l hello -f -- -somefile1 somefile2
    HELP
       exit 0
    }
    while [ -n "$1" ]; do
    case "$1" in
       -h) help;shift 1;; 
       -f) opt_f=1;shift 1;; 
       -l) opt_l=$2;shift 2;; 
       --) shift;break;; 
       -*) echo "error: no such option $1. -h for help";exit 1;;
       *) break;;
    esac
    done
    echo "opt_f is $opt_f"
    echo "opt_l is $opt_l"
    echo "first arg is $1"
    echo "2nd arg is $2"

    输出结果:

    3)输出段落
    echo一次只能输出一行
    如果是一段文字,该如何输出呢?
    我们可以使用cat <<,后接一个字符串,段落的末尾再加上这个字符串来输出段落。

    cat << HELP
    ...
    ...
    HELP

    下例中,程序用来替换文件名,
    有三个输入参数,第一个参数是待替换字符
    第二个参数是替换字符
    第三个参数是文件名。

    #!/bin/bash
    if [ $# -lt 3 ];then
    cat << HELP
    本例中,程序用来替换文件名,
    有三个输入参数,第一个参数是待替换字符
    第二个参数是替换字符
    第三个参数是文件名。
    HELP
       exit 0
    fi
    OLD="$1"
    NEW="$2"
    # The shift command removes one argument from the list of
    # command line arguments.
    shift
    shift
    # $@ contains now all the files:
    for file in "$@"; do
       if [ -f "$file" ]; then
          newfile=`echo "$file" | sed "s/${OLD}/${NEW}/g"`
          if [ -f "$newfile" ]; then
           echo "ERROR: $newfile exists already"
          else
             echo "renaming $file to $newfile ..."
             mv "$file" "$newfile"
          fi
       fi
    done

    输出结果:

    5.函数
    格式如下:

    函数名(){
        #函数中$1,$2对应接收到的第一第二个参数
    }

    示例代码如下:

    #!/bin/bash
    add()
    {
        
        echo $(($1+$2))
    }
    var1=1
    var2=2
    add $var1 $var2

    输出结果:

    四、脚本调试
    最简单的方式是使用echo输出值。

    五、Shell编程示例
    我们有一个日志文件,保存了系统的操作记录。过了一段时间后,这个文件可能会变得很大。
    我们采取的做法是重命名该文件,然后生成一个新的文件供再次使用。
    重命名的规则是,当前文件log.txt重名为log1.txt,在此之前,如果已经有log1.txt时,将log。txt命名为log2.txt,依次类推。
    代码如下:

    #!/bin/bash
    help()
    {
       cat << HELP
    重命名该文件,然后生成一个新的文件供再次使用。
    重命名的规则是,当前文件log.txt重名为log1.txt,在此之前,如果已经有log1.txt时,将log。txt命名为log2.txt,依次类推。
    HELP
       exit 0
    }
    
    if [[ $1 == '-h' || $1 == '' ]]; then
      help
    fi
    
    filename=$1
    
    # 我们先找到最大的数字再说。
    max=0
    while [ -f "$filename.$((++max))" ]; do
      : # 什么都不用做,我们已经顺手用 ++max 自增了 max 了。
    done
    
    # 然后从最大的一路重命名下来。
    for ((i=max; i>0; i--)); do
      # 数字加个 1,好给前一个让位子。
      if [ -f $filename.$i ];then 
          mv "$filename.$i" "$filename.$((i+1))"
      fi
    done
     
    # 最后我们点名要重命名的:
    if [ -f "$filename" ]; then
       mv "$filename" "$filename.1"
    fi
    
    # 重新创建一下。
    : > "$filename"

    运行程序,./myshell log.txt


    我们会发现log.txt的日志文件的名称会加1,同时当前的log.txt文件会变成log.txt.1,
    生成一个全新的log.txt文件,供程序再次使用。

  • 相关阅读:
    Git
    vue
    vue
    echarts,dojo和兼容问题
    js数组对象以某一对象排序
    滚动条与图片移动
    vue
    vue
    vue页面组件化-父子组件传值
    phpquery笔记
  • 原文地址:https://www.cnblogs.com/shijingjing07/p/5627054.html
Copyright © 2020-2023  润新知