ShellBash简单入门

变量

  1. 变量格式

    bash的变量名是区分大小写的,并且变量名首字符不能是数字。看的各种代码也不少了,说实话,我还真没见到谁的代码用数字开头的变量名,我认为即使语言允许,这样做的人也很少,除非你真的很特别。

  2. 变量定义与赋值

    aaa=123
    

    这里需要注意定义变量时等号前后都不能有空格,必须紧靠着写。虽然等号后面有空格的情况,语法可能不会出错,但结果绝对是错误的。

  3. 变量拼接

    bbb=${aaa}123
    

    很多时候,我们可能需要用一些变量、常量字符串等来拼接出一个新的变量,这时需要注意用来拼接的变量可能需要加上{},否则可能会出现变量识别错误从而找不到变量的情况。这种情况,我倾向于所有变量一股脑的全加上{}。

  4. local和export

    变量定义时还有两个常用的关键字——local和export。export在下文再说,定义局部变量的local,我却基本不用,等我使用的时候再来补上总结。

变量的定义也就那么回事,不去咬文嚼字的吭细节的话,懂这么一点点就够用了。如果,你的目标是成为shell高手,那么就需要专业级的学习,linux系统中有不少庞大的shell可以学习。

条件判断

if条件表达中长涉及到的比较有字符串、整数和文件属性比较等。

if语句格式有:

    if [ expr ] ; then
        do something
    fi

    if [ expr ] ; then
        do something
    else
          do something
    fi

    if [ expr ] ; then
         do something
    elif [ expr ] ; then
         do something
    else
         so something
    fi

if语句和其他语言(c,java)相比,是行不同但神似。then关键可以另起一行,那样条件表达式后的分号就可以省略了。
这里最需要注意的是:” [ ” 和 ” ] “前后至少需要一个空格来分割。

    /*example*/
    if(_)[(_)-n $str(_)](_);(_)then
    if [ -n $str ] ; then
  1. 整数比较

    整数大小比较涉及的操作符有—— -lt(little to)、-le(little equal)、-eq(equal)、-gt(great to)、-ge(great equal)和 -ne(non-equal)。

    /*example*/:
    a=1
    b=2
    
    if [ $a -lt $b ] ; then
        echo "a < b"
    else
        echo "a >= b"
    fi
    
    if [ $a -ne 3 ] ; then
        echo "a != 3"
    else
        echo "a == 3"
    fi
    
    
    if [ 1 -gt 3 ] ; then
        echo "1 > 3"
    else
        echo "1 <= 3"
    fi
    

    使用整数大小比较的6个操作符时,涉及到的两个操作数将会作为数值来处理,而不是字符串,即使你使用双引号将比较对象给引起来,也是如此。

  2. 字符串比较

    字符串比较可能用到的操作符有—— =、!=、>、<、-n和-z。

    /*example*/
    s1=aaa
    s2=bbb
    
    if [ $s1 \&amp;lt; $s2 ] ; then
        echo "$s1 < $s2"
    else
        echo "$s1 >= $s2"
    fi
    
    if [[ $s1 < $s2 ]] ; then
        echo "$s1 < $s2"
    else
        echo "$s1 >= $s2"
    fi
    
    if [ $s1 = $s2 ] ; then
        echo "$s1 == $s2"
    else
        echo "$s1 != $s2"
    fi
    
    if [ -n $s1 ] ; then
        echo $s1
    fi
    

    用于字符串大小比较的>和<两个操作符比较特别,在[ ]中书写时需要转义,否则可以使用[[ ]]来替代[ ]。如果不转义,>和<会被解释为IO重定向操作。其次,if语句体不能为空,必须至少做一件事情。操作符-n 用于判断字符串不为空,即长度不为0。-z判断字符串为空,即长度为0。

  3. 文件属性判断

    文件属性判断涉及到的操作符比较多,如下:

    -e、-a:文件存在
    
    -d:是目录
    
    -f:是文件
    
    -r:可读
    
    -w:可写
    
    -x:可执行
    
    f1 -nt f2:f1比f2新
    
    f1 -ot f2:f1比f2老
    

    这些操作符的使用方法和字符串操作符基本一致,在这几个操作符中我最常用的还是-e(exist)和-f(file),其他用得较少。其实,除了这三类常用的判断以外,还应该有执行命令结果的判断也比较常用,本文将不予总结了。

for循环

常用的for循环有两种主要形式

  • 形式一

    for e in [list]
    do
        do something
    done
    

    这种格式的for常用来遍历一个list集合中的所有元素,并加以处理。比如:

    1. 遍历一个目录中的所有文件

      for file in ls dir
      do
      echo $file
      done

    2. 遍历一个给定的集合

      list=”a b c d e f g”
      for e in listdoecho e
      done

    for in格式在遍历集合时,其实是根据空白字符来分隔字符串,取得每个元素的,上例中的ls dir $list得到的都是一个带空白字符的字符串。

    list=fileNmae_1 fileName_2 ...
    
  • 形式二

    for ((i = 0; i < n; i++))
    do
        do something
    done
    

    这一种for的形式和C语言基本一致,只是需要双括号罢了,它更擅长做确定次数的循环计算。比如:

    for ((i = 0; i < 10; i++))
    do
        echo $i
    done
    
    for (( ; ; ))
    do
        echo "aaaa"
    done
    

    没有计数器的for循环就是一个死循环的实现,这和C语言的写法也是一致的,真有亲切感。掌握了这点for循环语句,我们就可以做很多的事情了,基本足够我们玩了。

while循环

这鸟蛋,我平时基本不用,一切需要循环的地方都用for。在这里列举while循环的原因,就是想借它喷一下各种语言里的各种while, do while,还有什么until等。一个循环非得搞出各种不同的表达方式不可,这一点还是Golang做得最到位。语法糖太多,总有一天会腻死你。哈哈。

case语句

case语句相当于绝大多数语言里的switch语句。这玩意除了具备if-elif的功能外,还支持通配符,这个相当有用。我们直接看例子。

  url=www.tmall.com

  case $url in
      www.taobao.com)  echo 1;;
      *.taobao.com)         echo 2;;
      *.tmall.com)             echo 3;;
      www.tmall.com)      echo 4;;
      *)                               echo 5;;
  esac

上例中条件分支不光有常量字符串,还有含通配符的字符串,这一点用来进行模式匹配非常便利。其次,需要注意case语言在匹配的过程中是从第一个开始逐一匹配,所有上例的输出结果是3,而不是精确匹配的4。我认为这算一个小小的遗憾,要是支持精确匹配优先就更好玩了。其次,需要注意的是每个条件分支体的结束必须用双分号。

函数

函数定义

    function hello()
    {
          echo "hello world"
    }

函数定义实用关键字function,函数名后面的括号可有可无

函数调用

无参数的函数调用只需要给出函数名就ok了,上面定义的函数直接用hello调用即可。有参数的函数,只需要将参数依次在函数名后面给出即可,如:func_name arg1 arg2

函数参数

函数调用的时候可以给函数传递参数,那么函数体中又如何获取这些参数呢? 函数参数的获取和脚本程序参数的获取一致,都是通过 1 2等来取得。比如:

    function showTime() {
      hour=$1
      min=$2
      sec=$3
      echo "$hour: $min: $sec"
    } 

   echo `showTime 12 00 00`

在函数中,可以通过$#的值来判断函数调用的时候,传递了几个参数。bash函数里很少使用return这种方式来返回值。不过可以这样调用函数来获取计算结果,比如:

    res=`add 1 2`

变量res的值就是3了。注意上面不是单引号,而是数字1旁边的字符。

字符串处理

字符串处理差不多是整个计算机世界里做得最频繁的一件事情了。玩C语言的人很多事情都是在编写字符串处理程序。玩java的人大多数时候虽然不用自己去编写字符串处理程序,但也基本总是在调用字符串处理方法。linux其实有着非常强大的工具让我们去做字符串处理,不熟悉之前,每个工具貌似长得都非常复杂的样子。这里简单的总结一下自己使用过的字符串相关的东东。

  1. 求子串

    str=abcdefg
    echo ${str:2:3} 
    

    将得到bcd,表达式中的2代表偏移量,3代表长度。

  2. 求字符串长度

    str=123456
    echo ${#str}
    
  3. 字符串替换

    ${val/pattern/xx}   //将val中的第一个匹配替换为xx。
    ${val//pattern/xx}  //将变量中的所有匹配替换为xx。
    
    str=aaabbbccc
    echo ${str/aaa/xxx}
    echo ${str/a/x}
    

    有关字符串的处理,有着很多的工具,比如:你可以使用cut, awk等程序去拆分一个字符串等。

整数运算

整数运算一般使用$(( expr ))来进行。比如:

    echo $((1 + 2))
    a=1
    echo $((a + 2))
    echo $((a++))
    echo $((++a))
    b=2
    echo $(((a + b) / 2))

可以看到只需要将计算表达式塞到 (()) 符号。整数运算涉及到的运算符有:++ 、–、+、-、*、/、%、+=、(幂运算); 还有不常用的:<<、 >>、 ^、 &、 !、 |、 ~,这些在C语言中倒挺常用的,shell用来做这些位运算的需求也太2b了。 除了这些运算还支持逻辑:<、>、<=、>=、==、!=、&&、||。

$(( expr ))表达式只能计算整数,不能用于小数的计算。如果,要做小数的计算,可以使用linux上的命令行计算器bc来完成。

    /*example*/
    echo "1.5 + 1" | bc

getopts的使用

getopts是用来捕捉命令行选选项的,如下例子中的“-l”即命令行选项。getopts 的设计目标是在循环中运行,每次执行循环,getopts 就检查下一个命令行参数,并判断它是否合法。即检查参数是否以 - 开头,后面跟一个包含在 options 中的字母。如果是,就把匹配的选项字母存在指定的变量 variable 中,并返回退出状态0;如果 - 后面的字母没有包含在 options 中,就在 variable 中存入一个 ?,并返回退出状态0;如果命令行中已经没有参数,或者下一个参数不以 - 开头,就返回不为0的退出状态。

    ls -l
  1. getopts的一般格式

    getopts option[:] valiable
    
  2. 使用举例

    /*showTime.sh*/
    while getopts h:m:s: valiable
    do 
        case "$valiable" in
            h)
                hOpt=${OPTARG}
                echo "option:h, value $OPTARG"
                echo "next arg index:$OPTIND";;
            m)
                mOpt=${OPTARG}
                echo "option:m, value $OPTARG"
                echo "next arg index:$OPTIND";;
            s)
                sOpt=${OPTARG}
                echo "option:s, value $OPTARG"
                echo "next arg index:$OPTIND";;
            \?)
                echo "Usage: args [-h n] [-m] [-s]"
                echo "-h means hours"
                echo "-m means minutes"
                echo "-s means seconds"
                exit 1;;
        esac
    done
    
    • 其中 h:m:s: 即为可选择的option,用户输入的命令行选项在每一次循环中会存入到valiable中

    • h: 是一个整体,h 表示一个选项,: 表示该选项后面还有一个参数,参数会存入 OPTARG 中(这是很重要的一个参数之一)

    • 另外一个重要的参数为 OPTIND 用来存放下一个“条目”的下标。如下例中,共有“条目”6个,因此OPTIND= 7

      showTime -h 12 -m 00 -s 00
      

你可能感兴趣的:(bash)