Linux运维工作中,我们为了提高工作效率通常会用bash编写脚本来完成某工作。

 

今天就来为大家介绍bash的一些常见的基本语法。

 

在讲解bash语法之前首先介绍一下bash

 

bash环境主要是由解释器来完成的。

【解释器】:解释命令:词法分析、语法分析、语义分析

            条件判断:选择分支

            循环

注:bash是一种过程是编程语言:顺序执行、选择执行、循环执行

解释器:提供了编程环境

【脚本】:使用bash提供控制机制,将期望执行的命令罗列于文本文件中,当我们需要执行脚本中的命令时我们可以只用执行该脚本即可。

注:bash没有库,整个程序几乎都要依赖于系统命令来完成

 

 

编译型语言:源程序转换成二进制源(文本文件)--> 预处理 --> 编译 --> 汇编 --> 链接 

注:编译型语言是静态语言(需要声明变量)

 

解释型语言:源程序(文本文件)--> 解析器去读取并执行

注:解释型语言是动态语言(变量无需声明,随拿随用)

 

 

bash的重要特性:变量

bash变量类别:

本地变量:只对当前shell进程有效的变量;对其它shell进程无效,包当前shell进程的子进程;

环境变量:对当前shell进程及其子shell有效,对其它的shell进程无效;

局部变量shell脚本中某代码片断有效;通常用于函数本地;

位置变量:$1,表示引用第一个参数;

        特殊变量:$?,表示返回上一条命令执行状态的返回值。

 

变量的赋值:变量名=变量值   如我们给变量abc赋值为123abc=123

注:变量赋值是向变量存储空间保存数据

变量的引用:${变量名}     如我们想引用变量abc${abc}

            “”表示弱引用,如果里面是变量的话将会被替换成变量的值 如我们用“”引用abc:“abc” 显示的结果为123

            ‘’表示强引用,如果里面是变量的话将会直接输出不做替换 如我们用‘’引用abc:‘abc’显示结果为:abc

定义环境变量:export 变量名=变量值  如定义一个环境变量chioceexport chioce=1213

导出环境变量:export 变量名  如导出变量chioce:export chioce

撤销环境变量:unset 变量名  如我们撤销变量chioceunset chioce

定义为只读变量:readonly 变量名 如我们把chioce定义为只读变量:readonly chioce

定义局部变量:local 变量名=变量值  如我们定义一个局部变量sumlocal sum=123

 

查看本地变量:set

查看环境变量:exportprintenvenv

 

注:我们在定义变量时变量名的命名要遵循以下要求:

                                     1、不能使用程序中的关键字  如:ifcasefor等;

                                     2、只能使用数字、字母和下划线,且不能以数字开头;

                                     3、要见名知义(看见变量名就知道这个变量是用来干什么的)。

 

bash脚本格式】:

        开头一行必须为:#!/bin/bash(只有这样程序才能识别这是一个bash脚本)

 

bash编写完脚本后我们可用:bash -n 脚本名 (对脚本进行语法测试)

                          bash -x 脚本名 (单步模拟执行该脚本)

                          bash 脚本名    (运行该脚本)

                          注:脚本运行前是没有可执行权限的,我们需要给脚本执行权限后才能执行:chomd +x 脚本名  

既然说了脚本的简单用法接下来我们做一个实例给大家演示一下:


【实例1

       写一个脚本,能接受一个参数作为用户名,此脚本可创建此用户,并且其密码同用户名;

Linux之bash编程基本语法_编程

Linux之bash编程基本语法_Linux_02

Linux之bash编程基本语法_编程_03



具体操作我们就演示这一次,之后的实例只做模拟不再具体操作。

 

这样是方便了我们处理一些事情,但是对于有些大量的重复的操作怎么办?难道我们还要这样手动一条一条的写进脚本吗?是不是有点麻烦?

所以我们的循环语句就出现了

 

bashfor循环】

For循环的语法格式:for 变量 in 列表(列表中包含1个或多个元素)

                   do 

                     循环体

                   done 

注:每次循环都会把列表中的元素赋值给变量执行循环体。

for循环的退出条件是遍历列表结束,(也就是说所有列表中的元素都执行一遍后就结束)

 

【实例2】:写一个脚本,创建10个用户,分别为user301..user310

Linux之bash编程基本语法_Linux_04

Linux之bash编程基本语法_bash_05

Linux之bash编程基本语法_bash_06


【实例3】:写一个脚本

1、创建用户tuser1-tuser9; 

2、创建目录/tmp/dir-当前日期时间;

3、在/tmp/dir-当前日期时间 目录中创建9个空文件file101-file109

4、将file101的属主改为tuser1,依次类推,一直将file109的属主改为tuser9;

Linux之bash编程基本语法_bash_07

Linux之bash编程基本语法_bash_08

Linux之bash编程基本语法_编程_09



for循环列表的生成方法】:

实例2中我们用到了{301..310} 意思为:从301开始一次加1,一直到310

如果我们需要的偶数呢,或者是每隔3个取一个数呢?

${seq 301 2 310}表示从301开始每隔一个数取一个,到310为止。

【列表生成方式】:1、手动添加  如:for i in 1 2 3 4 5 

                 2、数值列表  如:{起始值..结束值}  $seq 起始值 递进值 结束值)

                 3、通过位置参数传递  如:$*,$@

                 4、命令生成列表   如:ls /etc/

【实例4】:写一个脚本计算100以内所有偶数之和

Linux之bash编程基本语法_bash_10

Linux之bash编程基本语法_Linux_11

Linux之bash编程基本语法_bash_12


bash的运算方式】:

        算数运算:let 变量=a+b  如实例4中的let sum=$sum+$i或者let sum+=$i

                    Bash中支持的算术运算符:+-*/%(取余)、**(次方)、+=、—=/=%=*=、变量++++变量、变量----变量

        逻辑运算:&&(与运算)、||(或运算)、!(非运算)

        比较运算:<><=>===!=

bash的测试类型】

      整型测试:-gt 大于 如:[ $a -gt $b ] 判断$a是否大于$b

                -lt 小于

                -ge 大于等于

                -le 小于等于

                -eq 相等

                -ne 不等

     字符串测试: <

                  >

                  <=

                  >=

                  == :等值

                  != :不等值

                  -n ‘字串’:是否为不空  如: [ -n $a ] 判断$a是否为不空

                  -z ‘字串’:是否为空    如:[ -z $a ] 判断$a是否为空

                  =~ :模式匹配    如:[[ $a =~ yes ]]判断$a的内容是否为yes

 

 

bashif语句】:

语法格式:1、(单分支ifif 测试条件

                        then 

                             选择分支

                        fi

          2、(双分支ifif 测试条件

                        then

                             选择分支1

                        else

                             选择分支2

                        fi

          3、(多分支ifif 测试条件1

                       then

                            选择分支1

                        elif 测试条件2

                        then

                            选择分支2

                                 .

                                 .

                                 .

                       else

                           选择分支n

                       fi

 

【实例5】:写一个脚本,给定一个用户,如果其shell/bin/bash且其ID号大于等于500,则说这是一个可登录普通用户;否则,则显示其为非登录用户或管理员。

Linux之bash编程基本语法_编程_13

Linux之bash编程基本语法_Linux_14



【实例6】:写一个脚本,1、添加10个用户:tuser501-tuser510

如果用户不存在,才添加;如果存在,则显示已经有此用户

2、显示一共添加了多少个用户;

Linux之bash编程基本语法_Linux_15


bash条件测试之文件测试】:

      使用格式:条件 文件 ]

                条件:-a 文件是否存在(也可以判断目录)

                      -e -a相同

                      -f 文件存在并且为普通文件

                      -d 存在,且为目录

                      -h 存在,且为符号链接文件   同-L

                      -b 块设备

                      -c 字符设备

                      -S 套接字文件

                      -p 管道文件

                      -s 存在且为非空文件

                      -r 存在且可读

                      -w 存在且可写

                      -x 存在且可执行

                     File1 -nt file2 文件1mtime时间比文件2mtime时间新

                     File1 -ot file2 文件1mtime时间比文件2mtime时间老

 

【实例7】:写一个脚本,  给定一个文件路径

1、判断此文件是否存在;不存在,则说明文件不存,并直接结束脚本;

2、如果文件是否普通文件,则显示为“regular file”;

   如果文件是目录,则显示为“directory”;

   如果文件是链接文件,则显示为“Symbolic file";

   否则,则显示为“unknown type.

Linux之bash编程基本语法_Linux_16


bash编程之交互式编程】:

  格式:read -p 输入提示内容. 变量名

 

【实例8】:写一个脚本,输入用户名,可返回其shell

Linux之bash编程基本语法_Linux_17


【实例9】写一个脚本,显示一个如下菜单给用户:

cpu) show cpu infomation

mem) show memory infomation

*) quit

 

1、如果用户选择了cpu,则显示/proc/cpuinfo文件的内容;

2、如果用户选择了mem,则显示/proc/meminfo文件的内容;

3、退出

Linux之bash编程基本语法_编程_18


bash编程循环之whileuntil】:whileuntil用于循环次数未知的情况下

     语法格式:while 测试条件

               do

                  循环体

               done

    如果测试结果为真则进入循环,退出条件:测试条件为假

    语法格式:until 测试条件

              do

                 循环体

              done

   如果测试结果为假则进入循环,退出条件:测试条件为真

 

【实例10】写一个脚本,求100以内所有正整数之和

Linux之bash编程基本语法_编程_19

Linux之bash编程基本语法_Linux_20



【实例11】:写一个脚本,:写一个脚本

1、提示输入一个对其执行分区的新硬件设备文件;

2、提醒用户接下来的操作销毁所有的数据,你继续吗?

yyes: 继续

nno:退出

其它字符:提醒输错了,再来一次;

3、对磁盘新建分区:

主分区1:大小512M

主分区2:大小2G

4、创建完成后显示创建的结果;

 

 Linux之bash编程基本语法_bash_21


bash编程之for循环的其他用法】:

   语法格式:for ((初始条件;测试条件;修改表达式))

             do

                循环体

             done

 

【实例12】写一个脚本,求100以内所有正整数之和

Linux之bash编程基本语法_编程_22


bash编程之while遍历文本文件】:

   语法格式:while read 变量

            do

                  循环体

                 done

 

【实例13】:写一个脚本,显示其ID号为偶数的用户的用户名、ID号和SHELL

Linux之bash编程基本语法_编程_23


bash编程之case语句】

   case语句:有多个测试条件时,case语句会使得语法结构更加明晰

   语法格式:case 变量引用 in

               条件1

                     分支1

                     ;;

               条件2

                     分支2

                     ;;

                   .

                   .

                   .

               条件n

                     分支n

                     ;;

             esac

 

【实例14】写一个脚本,用户键入字符后判断其所属的类别


Linux之bash编程基本语法_Linux_24


bash编程之函数】:

   将代码模块化,代码可重复使用

   语法格式:function 名 

             {

                函数体

                return ##表示数字)

             }

   可调用,使用函数名调用,函数名出现的地方,会自动替换成函数体。

   结果返回值打印语句:echoprint

 

【实例15】:写一个脚本,完成如下功能(使用函数)

1、提示用户输入一个可执行命令;

2、获取这个命令所依赖的所有库文件(使用ldd命令)

3、复制命令至/mnt/sysroot/对应的目录中

解释:假设,如果复制的是cat命令,其可执行程序的路径是/bin/cat,那么就要将/bin/cat复制到/mnt/sysroot/bin/目录中,如果复制的是useradd命令,而useradd的可执行文件路径为/usr/sbin/useradd,那么就要将其复制到/mnt/sysroot/usr/sbin/目录中;

4、复制各库文件至/mnt/sysroot/对应的目录中;

Linux之bash编程基本语法_Linux_25

Linux之bash编程基本语法_bash_26



bash编程之循环控制】:

 

      continue :提前进入下一轮循环(用于条件语句,仅在某个特殊场景提前进入)

      break    :跳出当前循环(用于条件语句,仅在某个特殊场景跳出循环)

bash编程之数组】:

      数组:数组名+索引 来标记数组元素

            索引表示方式:数字索引   如:a[0]a[1]...

      引用数组:${a[0]}

      declare  -a 数组   定义数组

             -A 关联数组

     

      支持稀疏数组: a[0] a[7] a[9]...(仅支持一维数组,数组补课再次划分)

   数组的赋值:一次对一个元素赋值:a[0]=$RADOM   $RADOMbash内置的一个生成随机数的变量)

               一次对全部元素赋值:a=(red blue yellow green)

               按索引进行赋值:a=([0]=green [3]=red [2]=blue [6]=yellow)

               命令替换:a=(/var/log/*.log)

               用户输入:read -a +数组名

  

   显示数组的长度${#数组名[*]} ${#数组名[@]}

                   ${#数组名默认显示数组中的第一个元素

 

   从数组中挑选某元素${数组名[@]:偏移元素个数:取出的元素个数}

                       ${数组名[*]}    取出所有元素

   数组复制${数组名[@或者*]}

             $@:把所有参数都当成字符串,一个参数一个串

             $*:所有参数都是一个串

   删除数组中的一个元素unset 数组名[下标]

   字符串切片${字串名:##}  取字串中偏移#个的#个字符

               ${字串名: -#}   取尾部指定个数的字符

               ${字串名#*Word} 在字串上,自左而右,查找第一次出现word,删除字符开始至此word处的所有内容

               ${字串名##*Word} 在字串上,自左而右,查找最后一次出现word,删除字符开始至此word处的所有内容

               ${字串名%Word*} 在字串上,自右而左,查找第一次出现word,删除此word处至字串尾部的所有内容

               ${字串名%%Word*} 在字串上,自右而左,查找最后一次出现word,删除此word处至字串尾部的所有内容

   查找替换${变量名/查找内容/替换内容}    只替换第一个

             ${变量名//查找内容/替换内容}    替换全部

             ${变量名/#查找内容/替换内容}   替换行首的指定字串

             ${变量名/%查找内容/替换内容}   替换行尾的指定字串

   查找删除${变量名/删除内容}  删除第一次出现的指定内容

             ${变量名//删除内容}  删除指定的全部内容

             ${变量名/#删除内容删除行首出现的指定内容

             ${变量名/%删除内容删除行尾出现的指定内容

   大小写替换${变量名^^x}  把指定的x字符替换成大写

               ${变量名,,x} 把指定的x字符替换成小写

   变量赋值: ${变量名:-Word} 如果变量为空,则显示结果为Word,(不给变量赋值,仅是显示结果改变)如果不空,则显示原值。

              ${变量名:=Word} 如果为空,则赋值并输出Word,如果不空,则显示原值。

              ${变量名:+Word} 如果不空则显示Word,如果为空则不显示。

              ${变量名:?Word} 如果为空则显示错误信息Word

 

 

【实例16】写一个脚本,生成10个随机数,升序排序

Linux之bash编程基本语法_bash_27


【实例17】写一个脚本,打印九九乘法表。

Linux之bash编程基本语法_编程_28


好了以上就是bash的基本语法内容了。