zoukankan      html  css  js  c++  java
  • shell学习之变量、判断、重复动作

    1.1 环境以及变量的定义、赋值、展开、删除

    • export:将一个变量导入到环境中:export PATH=$PATH:/home。
    • readonly 讲一个变量设置为只读模式,在shell脚本中定义字面值常量特别有用:readonly days_per_week=7, readonly -p 打印当前环境只读模式变量。
    • env可以对命令执行时的环境做更细致的控制:env -i PATH=$PATH HOME=$HOME awk '...' file1, 执行awk命令时的环境仅仅为env指定的环境。
    • unset 删除变量:unset [-v] full_name,删除函数:unset -f func。

    1.2 参数展开扩展知识

      在展开参数获取参数值时可以做额外的处理。

    1.2.1 常用替换运算符

    • ${varname:-word} 如果varname存在且非NULL, 则返回其值,否则返回word。例子:par1=${1:-100} && echo $par1。
    • ${varname:=word}如果varname存在且非null,则返回其值;否则,设置varname值为word,并且返回varname的值。
    • ${varname:?message}如果varname存在且非null,则返回它的值;否则显示varname:message信息,并退出当前脚本。
    • ${varname:+word}如果varname存在且非null,则返回word;否则返回null。用于测试变量是否存在。

    1.2.2 模式匹配运算符

      多用于处理路径类型的变量,做路径提取或者文件名提取。

    • ${var#pattern}:如果模式匹配与变量值得开头处,则删除匹配的最短部分,返回剩下的部分;如果不匹配则返回var。
    • ${var##pattern}:如果模式匹配与变量值得开头处,则删除匹配的最长部分,返回剩下的部分;如果不匹配则返回var。
    • ${var%pattern}:如果模式匹配与变量值得结尾处,则删除匹配的最短部分,返回剩下的部分;如果不匹配则返回var。
    • ${var%%pattern}:如果模式匹配与变量值得结尾处,则删除匹配的最长部分,返回剩下的部分;如果不匹配则返回var。

    1.2.3 位置参数

      位置参数即shell脚本的命令行参数,他们的名称用单个的整数来命名,如果整数大于9必须用花括号({})括起来。另外需要注意的:

    • $#:用于获取参数的总数。
    • $*和$@:一次表示所有的命令行参数。
    • "$*":引用所有的参数,但是将所有的命令行参数视为单个字符串,等同于"$1 $2 $3.... "。
    • "$@":引用所有的参数,但将所有的命令行参数视为单独的个体,等同于"$1" "$2"...。
    • set和shift:set 可以重新设置新的参数 set -- hello world ,将1设置为hello,将2设置为world,shift 参数列表左移。

    1.2.4 特殊变量

    • ?:前一个命令的退出状态。
    • $:shell进程的进程编号。
    • 0:shell进程的程序名称。
    • HOME:登陆目录。
    • IFS:内部的字段分隔符。
    • LINENO:刚执行过的行在脚本或者函数内的行编号。
    • PATH:命令查找路径。
    • PWD:当前工作目录。

    1.2.5 算数展开

      shell里面的算数运算都置于((...))中,比如 echo $((i++)) 。注意:POSIX规定,算数运算使用的是C的带有正负号的长整数,不一定支持浮点数。

    1.3 退出状态

      shell中,退出状态为0表示成功,其他的任何退出状态都为失败,可以用exit number来指定脚本退出时的返回值。

    1.4 测试命令

      shell 中的测试命令为test或[ .... ],在分支和循环判断中常用[ ... ]做条件测试。常用的两类测试:测试文件,测试比较表达式。

      字符串测试:

    • [ string ] :string不为null则为真。
    • [ -z string ]:string为null则为真。

      文件测试:

    • [ -f file ]:file为一般文件则返回真,其他的文件测试-b 块设备文件、-c 字符设备文件、-d 目录文件、-e 文件存在、-g 文件有设置setgid、-h 符号链接文件、-p 管道文件、-r 文件可读、-S socket文件、 -s 文件非空、 -t 文件描述符执行终端、 -u 文件有设置setuid、-w 文件可以写、-x 文件可以执行.

      表达式测试:

    • [ s1 = s2 ]:字符串s1与s2是否相同。
    • [ s1 != s2 ]:字符串s1与s2不相同。
    • [ n1 -eq n2 ]:整数n1等于n2。
    • [ n1 -nq n2 ]:整数n1不等于n2。
    • [ n1 -lt n2 ]:整数n1小于n2。
    • [ n1 -gt n2 ]:整数n1大于n2。
    • [ n1 -le n2 ]:整数n1小于等于n2。
    • [ n1 -ge n2 ]:整数n1大于等于n2。

      条件测试的几个注意点:

    • 字符串相关变量的测试,变量展开后加引号。if [ -f "$file" ] 比 if [ -f $file ]更好。
    • 只能做整数数字测试。

    1.5 分支语句if-elif-else-fi

      if分支语句示例:

    if grep "hello" file1 > /dev/null
    then
        echo "file1 has hello"
    elif grep "hello" file2 > /dev/null
    then
        echo "file2 has hello"
    else
        echo "no-file has hello"
    fi

      分支判断的pipeline可以是多条语句的逻辑表达式:!、&&、 ||,比如:

    #!/bin/bash
    
    if grep "hello" file1 > /dev/null || grep "hello" file2 > /dev/null
    then
        echo "file1 or file2 has hello"
    fi

    1.6 分支case语句

      case使用示例:

    #!/bin/bash
    
    my_var=5
    my_str="B"
    
    case $my_var in
    1)
        printf "1
    "
        ;;
    2)
        printf "2
    "
        ;;
    *)
        printf "else
    "
        ;;
    esac
    
    case $my_str in
    "a" | "A")
        printf "a
    "
        ;;
    "b" | "B")
        printf "b
    "
        ;;
    *)
        printf "else
    "
        ;;
    esac

      case的分支可以使用多个模式,多个模式间只要用|隔开即可。

    1.7 循环语句

       for循环用于重复整个对象列表,依次执行每一个独立对象的循环内容,下面的脚本利用for循环依次处理当前目录的文件和目录,sample example如下:

    #!/bin/bash
    for i in `ls`
    do
        echo $i
    done

      while循环和until循环为基于条件condition的循环,不同之处在于:只要condition是成功退出,while会继续循环,只要condition为成功结束,until则执行循环。

    while简单示例如下:

    #!/bin/bash
    
    cat /etc/passwd | awk 'BEGIN{FS=":";OFS=" "};{print $1,$3}'|
    while read user id
    do
        printf "username is $user, and id is $id
    "
    done


    until简单示例如下:

    #!/bin/bash
    #等待特定用户登录
    printf "Enter username: "
    read user
    
    until who | grep "$user" > /dev/null
    do
        printf "$user not login in.
    "
        sleep 2
    done

    1.8 shell中的函数

      

  • 相关阅读:
    HDU1443_Joseph_约瑟环
    HDU1568_求fibonacci的前四位
    HDU3368_翻转棋
    HDU1134_catalan_大数运算
    HDU1032_The 3n+1_数学题
    HDU2674_N!模2009
    HDU2067_小兔的棋盘_catalan_递推
    文件读写操作inputStream转为byte[] , 将InputStream写入本地文件
    JVM堆内存调优
    Java使用 POI 操作Excel
  • 原文地址:https://www.cnblogs.com/VincentXu/p/3355837.html
Copyright © 2011-2022 走看看