在study(Shell)专栏中,会深刻学习到shell编程

而作为一个运维人,最基本的能力,也是要学会shell脚本编程
为我们的工作中提高效率!

shell编程:

编译器:也叫解释器
shell给我们提供另外一个功能:方便我们的工作!

编程语言:将人类的语言转变成机器可以理解的语言
机器语言(01代码)
汇编语言(依然很低层,成长周期比较长,学习起来也比较困难)
高级语言(尽管如此,它也不是人类的语言,但是最接近人类的语言)
静态和动态语言

1、静态语言:编译型语言
(有程序开发环境,不需要借助额外的二进制程序,直接写代码,写完之后需要一个编译器,将代码放到编译器就可以交给硬件形成一个独立运行的程序,我们就把他叫做静态语言)
事先转换成可执行的格式;比如说java,c++
静态语言所需要的重要的一个特征:强类型(变量)
关键字:
执行之前就要完全转换,事先转换成可以执行的格式程序。
比如java的刚开始是一个.java文件(也就是源代码),编译成可执行文件即为.class文件(就是编译后的文件,就不是源码了)

2、动态语言:解释型语言on the fly
(一个代码我们程序员写完以后,他不需要转换成二进制格式,而是有一个解释器,解释一条,执行一条,也就是在执行以后在进行转换)
(通常)弱类型:边解释边执行
像PHP,SHELL,Python(非常流行的,面向对象的,很多游戏脚本都是用python),perl(早前流行的:读音:po(破))
像C,C++,JAVA,C#(不需要任何解释器,自我就能运行)

bash:最易学,最容易上手的就是SHELL
如果能学好python就是如虎添翼,添加了很多翼。
perl面向过程的,虽然perl6加上了对象,但是现在由于各种原因也流行不起来
事实上很多脚本是python研发的,在学习学了多年的计算机,都没有学过python,所以学校学的是脱节的

面向过程:相对开发小型的应用程序:shell,c
把编程着眼点主要在于问题解决的过程本身
面向对象:相对开发大型的应用程序:JAVA(纯面向对象语言),Python(纯面向对象语言),perl,c++
面向对象的含义:把整个我们要实现的项目抽象一个个对象,并定义对象之间的动作,就是可发出的操作来完成的,所以这个更适合开发大型程序
不过任何工具都是双刃剑(菜刀可以杀人也可以切菜)

要想理解编程,必须要理解变量
变量(不断变化的量):是内存空间,命名的内容空间(就是不断变化的量,存储在某一个内存的存储空间,根据地址就可以找到这个)
内存是存址的存储单元
我们通过变量和内存地址相对应,所以我们看到的是变量,比如a,其实它对应的是一个内存的地址空间。

实例:
10:字符存储的话,需要16位bit
10:存储为数值的话,就是1010,就只需要4位就足够了,当然计算机最小的存储是字节,所以这里也是需要8位的。
通过上述就知道,我们的变量需要有类型的

1、字符类型
2、数值类型,而数值类型又分:
1、整型
2、浮点型:11.23(存储举例:小数点之前存一个地方,小数点后面存在一个地方,小数点存在一个位置),就可能存储到这种格式1.12310^1,0.112310^2(可能只存1123和2)
如果我们要存储年份的话,比如:2013/10/10和99999,存储的格式和大小都不一样的
所以我们确定变量的类型:就是事先确定数据的存储格式和长度
内存:编址的存储单元

什么是溢出?
如下实例
·整型,8bit:256
·0-255,满了,流出去了,溢出
如果溢出的数据占据别人进程的空间了,就把其他的覆盖掉了,而如果这种精心设计的缓冲区溢出,一些***就是利用这种溢出的。
简单防止溢出的:看给的数据和我的程序变量类型是否合适,不合适就返回错误,不让其写入。因此说变量是需要类型的。
所以好的代码还会去检查变量,检查异常(举例:印度的外包业要比中国的要强很多就是这个原因)

布尔类型:真假
逻辑: 1+1>2
逻辑运算:与、或、非、异或(操作数相同为假,操作数不同为真)
!真=假
!假=真
其实我们计算机的电逻辑就是这样的
其实我们整个数字电路的电路就是这种运算,我们还可以自己设计加法器
在这种基础上不断的加,变成一个复杂的功能。
对于与来讲,只要有一个为假,结果一定为假
对于或来讲,只要有一个为真,结果一定为真

下图是一个电磁感应的原理(这就是计算机专业名称说的:非门)
1、shell编程(shell脚本)_理解编程和变量_第1张图片

整个计算机就是一大堆的这种门来运算的

强类型编程:
变量在使用前,必须事先声明,甚至还需要初始化值的:
NULL:
弱类型编程:
变量用时才声明(拿来直接用就行了),甚至不区分类型(如果不区分类型,默认为字符串):
我们的shell编程是弱类型的编程语言

变量赋值VAR_NAME=VALUE(把这个值保存在变量空间里面去了)如:ShenGao=175

编程能力:
bash脚本编程
bash变量类型:
环境变量
本地变量(局部变量(局部变量不一定都是本地变量))
位置变量
特殊变量(bash内置的,用来保存bash特殊数据的,也有人把他称作系统变量)

本地变量:(变量一定是进程的变量)
[root@www ~]# NAME=jerry
[root@www ~]# echo $NAME
jerry
我们引用变量用:${VARNAME} (通常{}可以省略),如上
但是有时候会引起变量混淆的,我们就要加上花括号,如下
[root@www ~]# echo $NAME
jerry
[root@www ~]# echo "my name is $NAME"
my name is jerry
[root@www ~]# echo "my name is $NAMEs"
my name is
[root@www ~]# echo "my name is ${NAME}s"
my name is jerrys
[root@www ~]# echo "my name is ${NAME}:s+w"
my name is tom:s+w 可以看出有一些字符是不会被识别的,比如:,+...
子bash:在一个shell中再打开一个shell

变量的学习以及变量的类型
本地变量:
VARNAME=VALUE:作用域为整个bash进程:
局部变量:
local VARNAME=VALUE:作用域为当前代码段
export定义一个环境变量,环境的作用域如下(export意为:“导出”)
1、shell编程(shell脚本)_理解编程和变量_第2张图片

VARNAME=VALUE
export VARNAME
1、shell编程(shell脚本)_理解编程和变量_第3张图片

1、shell编程(shell脚本)_理解编程和变量_第4张图片

当然,环境变量如果重新打开一个shell,就会没有作用;但是子shell是有作用的

位置变量(是用来引用脚本的参数的):
$1,$2,...
比如下面的例子
#!/bin/bash
let sum=$[$1+$2]
echo -e "the sum is $sum"
然后输出结果就可以这样
[root@zabbix ~]# ./myshell.sh 15 96
the sum is 111
[root@zabbix ~]# ./myshell.sh 5 9
the sum is 14

特殊变量:
$?:上一个命令的执行状态的返回值,我们看到的输出是执行结果,那问如果是正确还是错误的话,就是状态结果,也叫做状态返回值
程序执行,可能有两类返回值,一种是正确的,一种是错误的
$?:上一个命令的执行状态返回值:如果不是0(执行状态返回代码),就是执行状态是错误的,如果是1-255就是错误的,不是正确的执行状态。
1-255中系统预留的有三个1,2,127,其他的可以自己定义的
[root@www ~]# ifconfig &> /dev/null
[root@www ~]# echo $?
0
&>错误还是正确都输出到/dev/null(软件模拟的设备,也叫做bit bucket(数据黑洞)放什么进去都会消失)下去,而/dev/null就是垃圾站一样,什么都可以接收,我们用上面的命令,就是为了查证上一个命令是否正确输出,echo $?,这样放进去null就不用显示屏幕了。
1、shell编程(shell脚本)_理解编程和变量_第5张图片

变量用完以后,就没用了,我们就还可以撤销变量
本来我们定义变量是有一个set的,但是其实它默认就有了,所以我们没有用set,而撤销的话就是用unset VARNAME
1、shell编程(shell脚本)_理解编程和变量_第6张图片

set
查看shell中的所有变量就直接用set就可以了,,这里包括了所有变量(包括环境变量)
如果只查看环境变量用printenv或者env或者export
用:在环境变量基础上可以再加东西(是不会识别成变量名的,所以不需要{})

1、shell编程(shell脚本)_理解编程和变量

1、shell编程(shell脚本)_理解编程和变量

跟window差不多,用:隔开去添加一个新的变量
记住:这个符号——变量默认不能做算术运算的

什么是脚本?

如何去写脚本:其实就是命令的堆砌,是按照实际需要,结合命令流程控制机制实现的源程序的脚本。
Linux只能识别ELF格式去执行的(也就是脚本的第一行必须是#!/bin/bash,bash是解释器,/bin/bash 是解释器路径),这样才能然一个ASCII格式的文本可以被执行
我们的文件几乎都是是ACISS格式的
所以我们想运行脚本文件,必须是在文件的第一行用
#!/bin/bash (而后再出现的#就是注释的#(也就是当做有效的组成部分))
所以一执行这个文件,就会读到第一行,就会用bash的编辑器去运行
并且要知道shell脚本的文件要用.sh后缀,就像是本地仓库要用.repo一样
如下的一个shell脚本,用来进入网络配置文件
[root@www tmp]# vim 1.sh
#!/bin/bash
cd /etc/sysconfig/network-scripts/
vim ifcfg-eno16777736
[root@www tmp]# ./1.sh ./表示运行当前目录脚本
如果没有x执行权限,而是作为别人的参数来进行的,就不用执行权限
可以直接 bash 1.sh(而且这一种方式,开头也不需要#!/bin/bash去调用编译器,因为已经是通过bash这个程序去执行了

练习
1、shell编程(shell脚本)_理解编程和变量_第7张图片

useradd user001
useradd user002
echo "112233" | passwd --stdin user001 &> /dev/null
echo "112233" | passwd --stdin user002 &> /dev/null
echo user001 passwd shezhi successful
echo user002 passwd shezhi successful

Chinaname=user001 (不能在脚本中用set Chinaname=user001,测试发现不成功)
userdel -r $Chinaname
echo "the user already delete"