bash特性及bash脚本编程初步

终端,附着在终端的接口程序:

    GUI:KDE,GNome,xfce

    CLI:/etc/shells

bash的特性:

    命令行展开:~,{}

    命令别名:alias,unalias

    命令历史:history

    文件名通配:glob

    快捷键:

    命令补全:

    路径补全:

    命令hash:

        缓存此前命令的查找结果:key-value

            key:搜索键

            value:值

[root@apenglinux-001 ~]# hash
命中	命令
  16	/usr/bin/grep
   1	/usr/bin/tail
   6	/usr/sbin/useradd
[root@apenglinux-001 ~]# hash -d grep
[root@apenglinux-001 ~]# hash
命中	命令
   1	/usr/bin/tail
   6	/usr/sbin/useradd
[root@apenglinux-001 ~]# hash -r
[root@apenglinux-001 ~]# hash
hash: 哈希表为空

bash的特性:变量

    程序:指令+数据

        指令:由程序文件提供

        数据:IO设备、文件、管道、变量

    程序:算法+数据结构

    变量名+指向的内存空间

    变量赋值:name=value

    变量类型:存储格式、表示数据范围、参与的运算 

        编程语言:

                强类型变量

                弱类型变量:

                        bash把所有变量统统视作字符型

                        bash中的变量无需要事先声明,相当于把声明和赋值过程同时实现

                            声明:类型,变量名

                变量替换:把变量名出现的位置替换为其所指向的内存空间中的数据

                变量引用:${var_name},$var_name

                变量名:变量名只能包含数字、字母和下划线,而且不能以数字开头

                    变量名:见名知义,命名机制遵循某种法则,不能使用程序的保留字

                bash变量类型:

                    本地变量:作用域仅为当前shell进程;

                            变量赋值:name=value;

                            变量引用:${name},$name

                                双引号:变量名会替换为其值

                                单引号:变量名不会替换为其值 

                            查看变量:set

                            撤销变量:unset name(此处非变量引用)

                    环境变量:作用域为当前shell进程及其子进程

                        变量赋值:

                                1.export name=value

                                2.name=value,export name

                                3.declare -x name=value

                                4.name=value,declare -x name

                            变量引用:${name},$name

                            注意:bash内嵌了许多环境变量(变量名大写),用于定义bash的工作环境

                                PATH,HISTSIZE,HISTFILE,HISTFILESIZE,HISTCONTROL,SHELL,HOME,UID,PWD

                            查看环境变量:export,declare -x,printenv,env

                            撤销环境变量:unset name

                    局部变量:作用域仅为某代码片断(函数上下文)

                    位置参数变量:当执行脚本的shell进程传递的参数

                    特殊变量:shell内置的有特性功用的变量

                        如:$?(0:成功;1-255:失败)

                    只读变量:

                        1.readonly name

                        2.declare -r name

                        只读变量无法重新赋值,并且不支持撤销,存活时间为当前shell进程的生命周期,随shell进程终止而终止

    bash特性之多命令执行

[root@apenglinux-001 ~]# command1;command2;command3;...
逻辑运算:
    运算数:真(true,yes,on,1)
            假(false,no,off,0)
     与:
         1 && 1 = 1
         1 && 0 = 0
         0 && 1 = 0
         0 && 0 = 0
     或:
             1 || 1 = 1
             1 || 0 = 1
             0 || 1 = 1
             0 || 0 = 0
     非:
             ! 1 = 0
             ! 0 = 1
     异或:
         相同则为0;不同则为1
   [root@apenglinux-001 ~]# command1 && command2  #command1为假,则command2不会执行;否则,command1为真,则command2必须执行
   [root@apenglinux-001 ~]# command1 || command2 #command1为真,则command2不会执行;否则,command1为假,则command2必须执行

shell脚本编程:

    编程语言的分类:根据运行方式分为两类:

       编译运行:源代码-->编译器(编译)-->程序文件

        解释运行:源代码-->运行时启动解释器,由解释器边解释边运行;

    根据其编程过程中功能的实现是调用还是调用外部的程序文件:

        shell脚本编程:利用系统上的命令及编程组件进行编程

        完整编程:利用库或编程组件进行编程

    编程模型:过程式编程语言,面向对象的编程语言

        程序=指令+数据

            过程式:以指令为中心来组织代码,数据是服务于代码

                顺序执行,选择执行,循环执行

                    代表:c,bash

            对象式:以数据为中心来组织代码,围绕数据来组织指令

                类(class):实例化对象,method

                代表:Java ,c++,Python

shell脚本编程,过程式编程,解释运行,依赖于外部程序文件运行

如何写shell脚本:

    脚本文件的第一行,顶格:给出shebang,解释器路径,用于指明解释执行当前脚本的解释器程序文件

        常用的解释器:

            #!/bin/bash  #!/usr/bin/python #!/usr/bin/perl

        文本编程器:nano

            行编辑器:sed

            全屏幕编辑器:nano,vi,vim

shell脚本是什么?

    命令的堆积;

    但很多命令不具有幂等性,需要用程序逻辑来判断运行条件是否满足,以避免其运行中发生错误;

运行脚本:
    1.赋予执行权限,并直接运行此程序文件
        chmod +x /path/to/script_file
        /path/to/script_file
    2.直接运行解释器,将脚本以命令参数传递给解释器程序
        bash /path/to/script_file
    注意:脚本中的空白行会被解释器忽略
          脚本中,除了shebang,余下所有以#开关的行表示注释

bash的配置文件

    两类:

            profile类:为交互式登录的shell进程提供配置

            bashrc类:为非交互式登录的shell进程提供配置

    登录类型:

            交互式登录shell进程:

                直接通过某终端输入帐号和密码后登录打开的shell进程

                使用su命令:su -username ,或者使用su -l username执行的登录切换

            非交互式登录shell进程:

                su username执行的登录切换

                图形界面下打开的终端

                运行脚本 

        profile类:

            全局:对所有用户都生效:/etx/profile ,/etc/profile.d/*.sh

            用户个人:仅对当前用户有效:~/.bash_profile

            功用:

                    1.用于定义环境变量

                    2.运行命令或脚本

    bashrc类:

            全局: /etc/bashrc

            用户个人:~/.bashrc

            功用:

                    1.定义本地变量

                    2.定义命令别名

            注意:仅管理员可修改全局配置文件

            交互式登录shell进程:

                /etc/profile--->/etc/profile.d/*--->~/.bash_profile--->~/.bashrc--->/etc/bashrc

            非交互式登录shell进程:

                ~/.bashrc--->/etc/bashrc--->/etc/profile.d/*

            命令行中定义的特性,例如变量和别名作用域为当前shell进程的生命周期

            配置文件定义的特性,只对随后新启动的shell进程有效

            让通过配置文件定义的特性立即生效

                1.通过命令行重复定义一次

                2.让shell进程重读配置文件:source /path/from/conf_file, . /path/from/conf_file


文本处理工具

    linux上文本处理三剑客:

        grep,egrep,fgrep: 文本过滤工具(模式: pattern)工具

            grep: 基本正则表达式,grep -E 扩展正则表达式 grep -F 不支持正则表达式

            egrep:扩展正则表达式,egrep -G 基本正则表达式

            fgrep: 不支持正则表达式 -G 基本正则表达式 -E 扩展正则表达式

        sed: stream editor,流编辑器,文本编辑工具

        awk: Linux上实现为gawk,文本报告生成器(格式化文本)

    正则表达式:Regual Expression,REGEXP

        由一类特殊字符及文本字符所编写的模式,其中有些字符不表示其字面意义,而是用于表示控制或通配的功能

            分两类:

                     基本正则表达式:BRE

                     扩展正则表达式:ERE

              元字符:\(hello[[:space:]]\+\)\+

        grep: Global search REgular expression and Print out the line.

        作用:文本搜索工具,根据用户指定的"模式(过滤条件)"对目标文本逐行进行匹配检查;打印匹配的行

        模式:由正则表达式的元字符及文本所编写出的过滤条件

        正则表达式引擎:

         grep [options] pattern [file...]

          grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]

            options:

                    --color=auto #对匹配到的文本着色后高亮显示

                    -i ignorecase #忽略字符的大小写 

                    -o #仅显示匹配到的字符串本身

                    -E #支持使用扩展的正则表达式元字符

                    -q --quiet,--slient #静默模式,即不输出任何信息

                    -A # after ,后#行

                    -B # before,前#行

                    -C # context,前后各#行

             基本正则表达式元字符:

                字符匹配:

                    .  匹配任意单个字符

                    [] 匹配指定范围内的任意单个字符

                    [^] 匹配指定范围外的任意单个字符

                        [:digit:] [:lower:] [:upper:] [:alpha:] [:alnum:] [:punct:] [:space:]

                    匹配次数:用在要指定其出现的次数的字符的后面,用于限制其前面字符出现的次数

                        * : 匹配其前面的字符任意次(0,1多次)

                        .* : 匹配任意长度的任意字符

                        \? : 匹配其前面的字符0次或1次,即前面的字符是可有可无的

                        \+: 匹配其前面的字符1次或多次,即前面的字符要出现至少1次

                        \{m\}: 匹配前面的字符m次

                        \{m,n\}: 匹配其前面的字符至少m次,至多n次

                        \{0,n\}: 至多n次

                        \{m,\} : 至少m次

                    位置锚定

                        ^: 行首锚定,用于模式的最左侧

                        $: 行尾锚定,用于模式的最右侧

                        ^pattern$: 用于pattern来匹配整行

                        ^$: 空白行

                        ^[[:space:]]*$ 空行或包含空白符的行

                        单词: 非特殊字符组成的连续字符(字符串)都称为单词

                            \<或\b: 词首锚定,用于单词模式的左侧

                            \>或\b: 词尾锚定,用于单词模式的右侧

                            \<pattern\>: 匹配完整单词

grep练习

显示/etc/passwd文件中不以/bin/bash结尾的行

[root@apenglinux-001 ~]# grep -v '/bin/bash$' /etc/passwd

找出/etc/passwd文件中的两位数或三位数

[root@apenglinux-001 ~]# grep '\b[[:digit:]]\{2,3\}\b'  /etc/passwd

找出netstat -tan命令的结果中以LISTEN后跟0、1或多个空白字符结尾的行

[root@apenglinux-001 ~]# netstat -tan|grep 'LISTEN[[:space:]]*$'

 找出/etc/grub2.cfg文件中,以至少一个空白符开头,且后面非空白字符的行

[root@apenglinux-001 ~]# grep '^[[:space:]]\+[^[:space:]]' /etc/grub2.cfg

                   分组及引用

                        \(\): 将一个或多个字符捆绑在一起,当作一个整体进行处理(\(xy\)*ab)

                        Note: 分组括号中的模式匹配到的内容会被正则表达式引擎自动记录于内部的变量中,这些变量为 

                            \1: 模式从左侧起,第一个左括号以及与之匹配的右括号之间的模式所匹配到的字符

                             \2: 模式从左侧起,第二个左括号以及与之匹配的右括号之间的模式所匹配到的字符

                                ......

                        后向引用,引用前面的分组括号中的模式所匹配的字符


egrep与grep选项一样

或: C|cat  #表示C或cat

bash脚本编辑之算术运算 + - * / %
算术运算格式: 
(1)let var=算术运算表达式; 如:let var=$num1+$num2,echo $var
(2)var=$[算术运算表达式]; 如:echo $[1+2];
(3)var=$((算术运算表达式));如:echo $((1+2))
(4)var=$(expr $arg1 $op $arg2)
注意:乘法符号在有些场景中需要使用转义符

写一个脚本,实现添加三个用户,求此三个用户的uid之和

#!/bin/bash
#
#添加三个用户;求此三个用户的uid之和
uidsum=0
for i in `seq 1 3` ; do
	useradd user$i
	uidsum=$(($uidsum+$(id -u user$i)))
done
echo $uidsum