5. bash基础以及shell编程初步

一. bash特性以及bash脚本编程初步

bash的特性:

        命令行展开:~,{}

        命令别名: alias ,unalias

        命令历史:history

        文件名通配:glob

        快捷键:Ctrl + a,e,k,l

        命令补全:tab

bash的特性之:命令bash

        缓存此前命令的查找结果,命令hash:当执行一个命令的时候开始不是先在path环境变量中找相应的命令,而是先在缓存中查找。

[root@myEcs etc]# hash              //命令hash
hits    command
   1    /usr/bin/file
   1    /usr/bin/cat
   4    /usr/bin/ls                 //命令查找了两次
[root@myEcs etc]# 

     选项:

           -d:忘记一个命令的缓存

[root@myEcs etc]# hash
hits    command
   1    /usr/bin/file
   1    /usr/bin/head
   1    /usr/bin/cat
   4    /usr/bin/ls
[root@myEcs etc]# hash -d file
[root@myEcs etc]# hash
hits    command
   1    /usr/bin/head
   1    /usr/bin/cat
   4    /usr/bin/ls
[root@myEcs etc]# 

           -r:清空缓存

[root@myEcs etc]# hash
hits    command
   1    /usr/bin/head
   1    /usr/bin/cat
   4    /usr/bin/ls
[root@myEcs etc]# hash -r
[root@myEcs etc]# hash
hash: hash table empty
[root@myEcs etc]# 

 bash特性之:变量

         程序:数据+指令

                指令:由程序文件提供

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

        程序:算法+数据结构

        变量赋值:name=value

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

                    编程语言:

                           强类型变量

                           弱类型变量:bash吧所有变量统统视为字符串;bash不支持浮点类型

                                                 bash中的变量无须事先声明

 

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

       变量引用:$(var_name),$var_name

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

                变量名:见名知义,驼峰法则。

        bash的变量类型:

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

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

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

 

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

               特殊变量:shell内置的有特殊用处的变量。

                            $?:保存执行命令的执行状态结果。

                                   0:成功

                                   1-255:失败

 

              本地变量:

                         变量赋值:name=value

                         变量引用:$(name),$name

                                  " ":变量会替换为其值

                                  ' ' :变量名不会替换为其值

                         查看变量:set 

                         撤销变量:uset name

[root@myEcs etc]# name=huangxiaojun
[root@myEcs etc]# unset name
[root@myEcs etc]# echo $name

[root@myEcs etc]# 

 

              环境变量:

                       变量赋值:

                          (1)export name=value

                          (2)name=value

                                   export name

                          (3)declare -x name=value                                // 内嵌命令,声明环境变量

                          (4)name=value

                                   declare -x

                      变量引用:$(name),$name

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

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

                      撤销环境变量:unset name

               只读变量:

                     (1) declare  -r                      

                     (2)readonly name

[root@myEcs etc]# name=huangxiaojun                    // 定义一个变量
[root@myEcs etc]# declare -r name                      // 将这个变量设置成只读变量
[root@myEcs etc]# name=wangwu                          // 变量不能修改
-bash: name: readonly variable                         // 变量不能撤销
[root@myEcs etc]# unset name
-bash: unset: name: cannot unset: readonly variable
[root@myEcs etc]# 

 

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

bash特性之多命令执行:

        ~]# COMMAND; 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

 

            短路机制:

                     ~]# COMMAND1 && COMMAND2 

                           如果COMMAND1为“假”,则COMMAND2不执行;如果COMMAND1为“真”,则COMMAND2必须执行。

[root@myEcs tmp]# touch a.txt && touch b.txt    // 与运算中,命令1执行成功,那么命令2就执行
[root@myEcs tmp]# ls
a.txt  b.txt
[root@myEcs tmp]# 

 

[root@myEcs tmp]# ls /tmp/c.txt && touch c.txt  // 与运算中,第一个命令结果为假 ,则后面命令不执行
ls: cannot access /tmp/c.txt: No such file or directory
[root@myEcs tmp]# ls
[root@myEcs tmp]#     
        

                      ~]#  COMMAND1 || COMMAND2

                          如果COMMAND1为“真”,则COMMAND2不执行;如果COMMAND1为“假”,则COMMAND2必须执行。

[root@myEcs tmp]# id user1 || useradd user1                 // 或运算中,如果第一个结果为假,则执行第二个
id: user1: no such user
[root@myEcs tmp]# id user1
uid=1007(user1) gid=1008(user1) groups=1008(user1)

 

[root@myEcs tmp]# id user1 || userdel user1                  // 或运算中,第一个执行为真,后面就不执行
uid=1007(user1) gid=1008(user1) groups=1008(user1)
[root@myEcs tmp]# id user1
uid=1007(user1) gid=1008(user1) groups=1008(user1)
[root@myEcs tmp]# 

 

 

shell标本编程的实现:

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

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

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

               编程模型:面向过程,面向对象

               

               如何写shell脚本:

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

                                     常见的解释器:

                                            #!/bin/bash

                                            #!/usr/bin/python

                                            #!/usr/bin/perl

                     运行脚本:

                            (1)  赋予执行权限,直接运行此程序文件。

                                  chmod +x myfirst.sh

                            (2)  直接运行解释器,将脚本命令行参数传递给解释器程序。

                                  bash myfirst.sh

练习1:写一个脚本,实现如下功能。

           (1)显示/etc目录下所有以大写p或小写p开头的文件或目录本身

           (2)显示/var目录下的所有文件或目录本身,并将显示结果中的小写字母转换成大写后显示

           (3)创建临时文件/tmp/myfile.XXXXXX。

#!/bin/bash
ls /etc/[pP]*
ls /var/* | tr 'a-z' 'A-Z'
mktemp /tmp/myfile.XXXXXX

 

 bash的配置文件:

          两类:

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

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

          登录类型:

                 交互式登录shell进程:

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

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

                非交互式登录shell进程:

                        su USERNAME执行的用户登录切换。

                        图形界面下打开的终端。

                        运行脚本的时候

          frofile类:

                 全局配置:对所有用户都生效

                                 /etc/frofile

                                 /etc/profile.d/*.sh

                用户个人:仅仅对当前用户有效

                              /home/.bash_profile

                公用:

                       1. 用于定义环境变量

                       2. 运行命令或脚本

         bashrc类:

              全局:

                   /etc/bashrc

              用户个人:

                   /home/.bashrc

 

              公用:

                      1. 定义本地变量

                      2. 定义命令别名

                           

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

       启动时要运行的命令或脚本:/etc/profile.d/*.sh

 

bash脚本编程之算数运算

      +  -  *  /  **   % 

      算数运算格式:

            (1)let name=算数运算表达式                         

[root@myEcs tmp]# declare -i num1=3
[root@myEcs tmp]# declare -i num2=5
[root@myEcs tmp]# echo "$num1 + $num2" 
3 + 5
[root@myEcs tmp]# let sum=$num1+$num2    // 方法一
[root@myEcs tmp]# echo $sum
8
[root@myEcs tmp]# 

            (2)$[算数运算表达式]               

[root@myEcs tmp]# echo "$[$num1+$num2]"   //方法二
8
[root@myEcs tmp]# 

            (3)$((算数运算表达式))

[root@myEcs tmp]# echo "$(($num1+$num2))"  //方法三
8
[root@myEcs tmp]# 

        (4)expr $num1 + num2     必须要有空格

                    变量引用:sum=$(expr $num1 + $num2)

[root@myEcs tmp]# expr $num1 + $num2       //方法四
8
[root@myEcs tmp]# sum=$(expr $num1 + $num2)
[root@myEcs tmp]# echo "$sum"
8
[root@myEcs tmp]# 

             注意:乘法符号在有些场景中需要使用转义符。

  

练习:

    1. 添加三个用户求此三个用户的uid之和

#!/bin/bash
userName1=hxjuser1
userName2=hxjuser2
userName3=hxjuser3

id $userName1 > /dev/null || useradd $userName1 > /dev/null
id $userName2 > /dev/null || useradd $userName2 > /dev/null
id $userName3 > /dev/null || useradd $userName3 > /dev/null

uidNum1=`id $userName1 | egrep  -o  "uid=[[:digit:]]{4,}" |cut -d "=" -f 2`
uidNum2=`id $userName2 | egrep  -o  "uid=[[:digit:]]{4,}" |cut -d "=" -f 2`
uidNum3=`id $userName3 | egrep  -o  "uid=[[:digit:]]{4,}" |cut -d "=" -f 2`

echo "sum_uuid=$[$uidNum1+$uidNum2+$uidNum3]"

~                                                            

 

二. bash 脚本编程进阶

  脚本文件格式:

    第一行,定格:#!bin/bash

    注释信息:#

    代码注释:

    缩进,适度添加空白行;

 

    

    

 

 

     

 

 

 

 

 

 

 

 

 

               

 

posted @ 2020-04-19 14:56  附庸风雅  阅读(105)  评论(0)    收藏  举报