shell是用户与内核进行交互操作的一种接口,目前最流行的shell称为bash shell,bashshell编程以其简洁、高效而著称,多年来成为linux程序员和系统管理员解决实际问题的利器。

bash编程是面向过程的,依靠bash解释器边解释边执行,脚本的编写格式:

第一行:写明解释器; #!/bin/bash

注释行:所有以#开头的行均为注释行;会被解释器忽略

下面来看一个经典的小程序:

#!/bin/bash

echo "hello world"

它的第一行表示这个脚本程序由/bin/bash来解释.第二行在终端上打印出一行”Hello World”

一、给脚本传参数

bash脚本我们还可以给它传递参数,在脚本里通过调用位置变量来实现

#!/bin/bash
echo $*       #$*
表示所有参数列表

echo $@       #$@表示所有参数列表
echo $0       #$0是指脚本名称
echo $1       #$1表示脚本的第1个位置参数
echo $#       #$# 表示当前脚本的位置参数个数

二、条件测试

条件测试: test 表达式

           [表达式 ]

           [[表达式 ]]

测试表达式:

(1) 整数测试:     整数测试:A, B

                   A -gt B: 大于

                   A -ge B: 大于等于

                   A -eq B: 等于

                   A -lt B: 小于

                   A -le B: 小于等于

                   A -ne B: 不等于

(2) 字符串测试:   字符串测试:A, B

                   A > B

                   A < B

                   A >= B

                   A <= B

                   A == B或A =B:等值比较

                   A != B: 不等于

                   -z A: 判断A是否为空;空则为真,不空则假

                   -n A:判断A是否不空;不空则为值,空则为假

(3) 文件测试:     -e$file: 是否存在;存在则为真

                   -f $file: 文件是否存在,且为普通文件

                   -d $file: 是否存在且为目录

                   -h $file: 是否存在且为符号链接文件

                   -L $file:同上

                   -b $file: 是否存在且为块设备文件

                   -c $file: 是否存在且为字符设备文件

                   -S $file: 是否存在且为套接字文件

                   -p $file: 是否存在且为管道文件

-r$file: 当前用户对此文件是否拥有读权限

                   -w $file: 当前用户对此文件是否拥有写权限

                   -x $file: 当前用户对此文件是否拥有执行权限

-u$file: 文件是否拥有suid权限

                   -g $file:文件是否拥有sgid权限

                   -k $file: 文件是否拥有sticky权限

-O$file: 当前用户是否为文件的属主

                   -G $file: 当前用户是否属于文件的属组

-N $file:文件自从上一次被读取之后,是否被修改过

$f1 -nt$f2: 文件f1是否比文件f2新

                   $f1 -ot $f2: 文件f1是否比文件f2旧

                   $f1 -ef $f2:f1和f2是否为同一个文件的硬链接

三、流程控制

1、for循环

for 变量 in列表; do

     循环体

done

如我们要打印1到10,我们可以这样写

#!/bin/bash

for i in {1..10};do

   echo "$i"

done

2、if条件判断

if 条件;then

   条件为真时执行命令

else

   条件为假时执行命令

fi

例如:

#!/bin/bash

if [ 5 -eq 4 ];then

   echo "true"

else

   echo "false"

fi

3、case条件判断,通常用于判断字符串

case 变量 in

值1)

     变量值等于值1执行语句

     ;;

值2)

     变量值等于值2执行语句

     ;;

*)

     变量值等于其他值执行语句

     ;;

esac

例如:

#!/bin/bash

case $1 in 

cpu)

    lscpu ;;

*)

    exit 0 ;;

esac

4、while和until循环

whileCONDITION; do

    循环体

    循环控制变量的修正表达式

done

untilCONDITION; do

    循环体

    循环控制变量修正表达式

done

例如

#!/bin/bash

declare -i i=1

while [ $i -le 10 ];do

   echo $i

   let i++

done

5、循环控制命令break和continue

    break:提前退出循环;

    break [N]: 退出N层循环;N省略时表示退出break语句所在的循环;

    continue: 提前结束本轮循环,而直接进入下轮循环;

    continue [N]:提前第N层的循环的本轮循环,而直接进入下轮循环;

 

四、函数

定义函数的目的:将有特定功能的代码块,定义一个函数名称,在要使用此代码块时,直接调用函数,而不用再写一遍此代码块,也可以给函数传递参数

function_name(){

函数代码块

}

例如

#!/bin/bash

testfuc() {

  echo "test function"

}

testfuc   #调用函数testfuc

函数的返回值:

    函数中使用打印语句:echo, printf

    函数体中OS命令执行结果的输出

函数的退出状态码:

默认取决于函数体执行的最后一个命令的退出状态码;

自定义退出状态码:return [0-255]

注意:函数体运行时,一旦遇到return语句,函数即返回;

五、数组

数组元素:数组名+索引

    索引:从0开始编号

声明数组:declare -a ARRAR_NAME

关联数组:declare -A ARRAY_NAME

数组元素的赋值:

(1) 一次只赋值一个元素

    ARRAY[index]=VALUE

    a[0]="hello"

(2) 一次赋值全部元素

    ARRAY=("mon""tue" "wed")

(3) 指定索引进行赋值

    ARRAY=([0]="sun"[1]="mon" [5]="fri")

(4) read -a ARRAY

引用数组元素:${ARRAY[index]}

数组的长度:  ${#ARRAY[*]}, ${#ARRAY[@]}

例如

#!/bin/bash

declare -a testarry

for i in {0..9};do

   testarry[$i]=$RANDOM

done

echo "${testarry[*]}"

六、字符串操作

字符串切片:${var:offset:lenth}

取字符串最后的几个字符:${var: -lenth}   注意:冒号之后有空格

基于模式取子串:

${var#*word}:其中word可以是指定的任意字符;自左而右,查找var变量所存储字符中,第一次出现的word,删除字符开头直至第一次wrod出现处之间的所有字符

   ${var##*word}: 其中word可以是指定的任意字符;自左而右,查找var变量所存储字符中,最后一次出现的word,删除字符开头直至最后一次wrod出现处之间的所有字符

${var%word*}:自右而左,删除第一次word出现处的字符开始直到尾部的所有字符

${var%%word*}:自右而左,删除最后一次word出现处的字符开始直到尾部的所有字符

例如 :   url=http://www.magedu.com:80

              取端口:${url##*:}

              取协议:${url%%:*}

查找并替换:

    ${var/pattern/substi}:查找var所表示的字串中,第一次被Pattern匹配到的字串,并以substi替换之

    ${var//patten/substi}:查找var所表示的字串中,所有被Pattern匹配到的字串,并以substi替换之

${var/#pattern/substi}:以行首锚定的方式将pattern匹配至var所表示的字串上,如果能匹配,则以substi替换之

    ${var/%pattern/substi}:以行尾锚定的方式将pattern匹配至var所表示的字串上,如果能匹配,则以substi替换之;可使用?, *元字符

查找并删除:

    ${var/pattern}:删除pattern匹配到的第一次出现;

    ${var//pattern}:删除pattern匹配到的所有出现;

    ${var/#pattern}

    ${var/%pattern}

字符串大小写转换:

    ${var^^}:小写-->大写

    ${var,,}:大写-->小写

变量赋值:

    ${var:-word}:如果var为空或未设置,那么返回word;否则,则返回var中的值;

    ${var:=word}:如果var为空或未设置,那么返回word,并且将word赋值给var;否则,返回var中的值;

${var:?err_info}:如果var为空或未设置,那么返回错误信息;否则,则返回var自身的值;

${var:+word}:如果var自身有正常数据,则返回word;