一:相关概念理解
编译型语言:c,c++
源程序(文本文件) 预处理 编译 汇编 链接
静态语言
解释型语言:python,bash由解释器全程参与运行过程,每次读取一行,运行一行
源程序(文本文件) 解析器读取并执行
动态语言
Python:有编程库,程序控制结构,调用编程库完成程序编写
库文件:功能模块,在编程中可通过其API调用
编译器:gcc
解释器:bash 提供编程环境
解释:
词法分析
语法分析
语义分析
程序:指令+数据
算法+数据结构
对象式编程:以数据为中心,设计数据结构(类),程序服务于数据结构
过程式编程:以指令为中心,设计算法,数据服务于算法
bash是过程式编程:
顺序执行:逐个执行
选择执行:只执行其中一个分支
循环执行:一段代码执行多次
bash没有库,整个程序几乎都要依赖于命令
脚本:使用bash提供控制机智,将期望执行的命令罗列于文本文件中
二、变量
什么是变量?
变量本质是一段内存空间的名字。可以赋值,可以重复赋值
1、bash变量类别:
本地变量:只对当前shell进程有效,对其它shell进程无效,包括当前shell的子进程
变量赋值:向变量的存储空间保存数据 VAR_NAME=VALUE
变量引用:${VAR_NAME}
“”:弱引用,里面的变量会被替换
'':强引用,里面的所有字符都是字面量,直接输出。所见即所得,不会变咯
[root@xxj shell]# name=xxj [root@xxj shell]# echo "$name" xxj [root@xxj shell]# echo '$name' $name [root@xxj ~]# pstree #显示当前系统的进程树 init─┬─atd ├─auditd───{auditd} ├─crond ├─dbus-daemon ├─master─┬─pickup │ └─qmgr ├─6*[mingetty] ├─rsyslogd───3*[{rsyslogd}] ├─sshd───sshd───bash───pstree └─udevd───udevd [root@xxj ~]# bash #进入当前shell的子shell [root@xxj ~]# pstree init─┬─atd ├─auditd───{auditd} ├─crond ├─dbus-daemon ├─master─┬─pickup │ └─qmgr ├─6*[mingetty] ├─rsyslogd───3*[{rsyslogd}] ├─sshd───sshd─┬─bash───bash───pstree │ └─bash └─udevd───udevd [root@xxj ~]# echo "$name" [root@xxj ~]#
环境变量:对当前shell进程有效及其子shell有效,对其他shell无效
定义:export VAR_NAME=VALUE
导出:export VAR_NAME
撤销变量: unset VAR_NAME
只读变量: readonly VAR_NAME 不能重复赋值
[root@xxj ~]# name=xj [root@xxj ~]# echo $name xj [root@xxj ~]# export name [root@xxj ~]# pstree init─┬─atd ├─auditd───{auditd} ├─crond ├─dbus-daemon ├─master───qmgr ├─6*[mingetty] ├─rsyslogd───3*[{rsyslogd}] ├─sshd─┬─sshd───bash │ └─sshd───bash───pstree └─udevd───udevd [root@xxj ~]# bash You have entered the system: 168.100.20 your username is: root WARNING:Proceed with caution! Have any questions please contact the system administrator [root@xxj ~]# pstree init─┬─atd ├─auditd───{auditd} ├─crond ├─dbus-daemon ├─master───qmgr ├─6*[mingetty] ├─rsyslogd───3*[{rsyslogd}] ├─sshd─┬─sshd───bash │ └─sshd───bash───bash───pstree └─udevd───udevd [root@xxj ~]# echo "$name" xj [root@xxj ~]# readonly name [root@xxj ~]# name=xiexie bash: name: readonly variable
用户可自定义,bash许多内置的环境变量
[root@xxj ~]# echo $PATH /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
export PATH=$PATH:/usr/local/apache/bin
[root@xxj ~]# echo $PS1 [\u@\h \W]\$
\u:显示当前用户名
\h:显示简写的主机名
\W:显示当前所在目录的最后一个目录
\H:显示完整的主机名
\w:显示当前所在目录的完整目录
\$:提示符
局部变量:对shell脚本中某代码片段有效,通常用于函数本地:
定义: local VAR_NAME=VALUE
位置参数变量:$1,$2,$3、、、${10}
特殊变量:
$0:脚本名称自身
$*脚本所有的参数,$*把所有的参数看成一个整体
$@:脚本所有的参数,把所有的参数区分对待
$#:脚本所有参数的个数
$?:命令执行状态返回值,上一条命令的执行状态,状态用数字来表示0-255,0表示成功,非0表示失败
[root@xxj shell]# cat 16.sh #!/bin/bash cat<<EOF \$1 is $1 \$2 is $2 \$0 is $0 \$@ is $@ \$* is $* \$# is $# EOF [root@xxj shell]# bash 16.sh 1 2 $1 is 1 $2 is 2 $0 is 16.sh $@ is 1 2 $* is 1 2 $# is 2 [root@xxj shell]# echo $? 0
查看当前shell进程中的所有变量:set
查看当前shell进程中的所有环境变量:export,printenv,env
变量命名:
1、不能使用程序中的关键字(保留字)如,if,case,for
2、只能使用数字,字母和下划线,且不能以数字开头
3、建议要见名知义
2、变量类型
变量类型:
数值型:
精确数值:整数
近似数值:浮点型
单精度浮点
双精度浮点
字符型:(ASCII)
char
string
布尔型:true,false 1,0
定义变量类型的作用:
1、数据存储格式
2、数据的有效存储范围
3、比较机制不同
4、参与的运算类型不同
(二进制)数字的存储, 18:00010010 8个字节
文本的存储, ASCII:128常用字符 18:1,8 1:8bits 8:8bits 18:16bits 16个字节
类型转换:显示转换,隐式转换
bash是弱类型语言,一切皆字符,可以隐式转换
弱类型语言:
1、不强制区分变量的类型
2、无需事先声明,直接使用,直接赋值
bash变量的生命周期:
始于创建,终于销毁(shell进程终止或手动:unset NAME)
三、变量运算
bash中变量如何运算?
[root@xxj ~]# num1=4 [root@xxj ~]# num2=8 [root@xxj ~]# num=$num1+$num2 [root@xxj ~]# echo $num 4+8
为什么会这样?
因为bash中所有变量都默认是字符类型。
应该怎样进行运算呢?
1、在bash中使用变量运算可以事先申明变量的类型为数值型如下:
[root@xxj ~]# declare -i num1=4 [root@xxj ~]# declare -i num2=8 [root@xxj ~]# num=$num1+$num2 [root@xxj ~]# echo $num 12 [root@xxj ~]# declare -i num=$num1+$num2 [root@xxj ~]# echo $num 12 [root@xxj ~]# num3=3 [root@xxj ~]# num4=4 [root@xxj ~]# declare -i num=$num3+$num4 [root@xxj ~]# echo $num #发现“=”两边只要有一边定义了数值型就可以 7
2、也可以使用一些特定的格式:
[root@xxj ~]# let num=$num3+$num4 [root@xxj ~]# echo $num 7 [root@xxj ~]# echo $[$num3+$num4] 7 [root@xxj ~]# echo $(($num3+$num4)) 7 [root@xxj ~]# expr $num3 + $num4 7
变量运算总结如下:
let VARNAME=算数表达式 圆整:如果计算结果中存在小数,将会被圆整
$[$num1+$num2]
$(($num1+$num2))
expr $num1 + $num2 #注意,符号前后要有空格,可直接得到结果,
declare -i sum=$a+$b echo $sum
declare:
-i:整型变量
-x:环境变量,类似export
运算符:+,-,*,/,%(取余)
增强型赋值:+=,-=,*=,/=,%=
x=40
x=$[$x+2]
let x+=2
let x++ 相当于 let x+=1
[root@xxj ~]# x=40 [root@xxj ~]# x=$[$x+2] [root@xxj ~]# echo $x 42 [root@xxj ~]# x+=2 [root@xxj ~]# echo $x 422 [root@xxj ~]# let x+=2 [root@xxj ~]# echo $x 424 [root@xxj ~]# declare -i x+=2 [root@xxj ~]# echo $x 426 [root@xxj ~]#
四、条件测试
界定程序执行环境
1、根据运行的命令的状态结果
2、测试表达式
test 测试表达式
[ EXPRESSION ] 命令
[[ EXPRESSION ]] 关键字, 通用性更好
整数测试:做数值大小比较,所有不要给变量引用加引用
$A -gt $B:是否大于,是则为真,不是则为假
$A -ge $B:是否大于等于
A -lt B:是否小于
A -le B:是否小于等于
A -eq B:是否等于
A -ne B:是否不等于
[root@xxj shell]# num1=1 [root@xxj shell]# num2=2 [root@xxj shell]# [ $num1 -lt $num2 ] [root@xxj shell]# echo $? 0 [root@xxj shell]# [[ $num1 -lt $num2 ]] [root@xxj shell]# echo $? 0 [root@xxj shell]# [ $sum1-lt$sum2 ] [root@xxj shell]# echo $? 0 [root@xxj shell]# test $num1 -lt $num2 [root@xxj shell]# echo $? 0 [root@xxj shell]# test $num1 -gt $num2 [root@xxj shell]# echo $? 1
字符串测试:
"$A">"$B":是否大于 ASII数值越大,字符比较越大 注意使用[[ EXPRESSION ]]
"$A"<"$B":是否小于
"$A" == "$B":是否等于;
"$A" != "$B":是否不等于;
-z "$A":是否为空;空则为“真”,否则为“假”
-n "$A":是否不空;不空则“真”,空则为“假”
=~:字符串测试 模式匹配测试:[[ "string" =~ PATTERN ]] #经测试不[[]]不能使用-a,-o,只支持扩展正则表达式
[root@xxj shell]# a=hello [root@xxj shell]# b=name [root@xxj shell]# [ $a -gt $b ] -bash: [: hello: integer expression expected [root@xxj shell]# ^C [root@xxj shell]# [[ $a -gt $b ]] [root@xxj shell]# echo $? 1 [root@xxj shell]# [[ $a -lt $b ]] [root@xxj shell]# echo $? #发现字符串测试并不能用整数测试的表达式 1 [root@xxj shell]# [ $a < $b ] -bash: name: No such file or directory [root@xxj shell]# [[ $a < $b ]] #字符串测试一定要用“[[ EXPRESSION ]]” [root@xxj shell]# echo $? 0 [root@xxj shell]# [[ $a > $b ]] [root@xxj shell]# echo $? 1 [root@xxj shell]# [[ $a<$b ]] [root@xxj shell]# echo $? 0 [root@xxj shell]# aa=nihao [root@xxj shell]# bb=nihao [root@xxj shell]# [ $a == $b ] [root@xxj shell]# echo $? 1 [root@xxj shell]# [[ $a == $b ]] [root@xxj shell]# echo $? 1 [root@xxj shell]# [ $aa == $bb ] [root@xxj shell]# echo $? 0 [root@xxj shell]# [ $aa = $bb ] # “=”和“==”有区别吗??? [root@xxj shell]# echo $? 0 [root@xxj shell]# [[ $aa = $bb ]] [root@xxj shell]# echo $? 0 [root@xxj shell]# [[ -z $aa ]] [root@xxj shell]# echo $? 1 [root@xxj shell]# [ -z $aa ] [root@xxj shell]# echo $? 1 [root@xxj shell]# [ -n $aa ] [root@xxj shell]# [[ -z $aa ]] [root@xxj shell]# echo $? 1 [root@xxj shell]# [ -z $aa ] #发现字符比较中除了奇葩的比较大小外“[]”和“[[]]”是通用的 [root@xxj shell]# echo $? 1
文件测试:测试文件是否存在性以及属性
-e $file:文件是否存在,存在为真
-a $file:文件是否存在
-f $file:是否存在且为普通文件
-d $file:是否存在且为目录
-L $file:是否存在且为链接文件
-h $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:属组
双目操作符:
$file1 -nt $file2: file1是否新于file2, file1的最近一次的修改时间戳是否晚于file2的;
经测试比较的mtime即文件内容修改的时间也就是ls显示的时间
$file1 -ot $file2: file1是否旧于file2,
$file1 -ef $file2:file1与file2是否指向了同一个inode;测试二者是否为同一个文件的硬链接;
[root@BAIYU_207 ~]# [ -f /etc/fstab ] [root@BAIYU_207 ~]# echo $? 0 [root@BAIYU_207 ~]# [ -c /dev/null ] [root@BAIYU_207 ~]# echo $? 0 [root@BAIYU_207 ~]# [ -b /dev/cdrom ] [root@BAIYU_207 ~]# echo $? 0
组合测试条件:
条件间逻辑运算:与,或,非
表达式组合:
与:[ CONDITION1 -a CONDITION2 ]
或:[ CONDITION1 -o CONDITION2 ]
非: [[ ! CONDITION ]]
命令组合:
COMMAND1 && COMMAND2 相当于: [ EXPR1 ] && [ EXPR2 ]
COMMAND1 || COMMAND2
! COMMAND1
COMMAND1 ; COMMAND2
[root@localhost ~]# [ -f /etc/fstab -a -b /dev/cdrom ] [root@localhost ~]# echo $? 0 [root@localhost ~]# [[ -f /etc/fstab -a -b /dev/cdrom ]] #发现并不能使用“[[ ]]” -bash: syntax error in conditional expression -bash: syntax error near `-a' [root@localhost ~]# [[ -f /etc/fstab -o -b /dev/cdrom ]] -bash: syntax error in conditional expression -bash: syntax error near `-o' [root@localhost ~]# [[ ! -f /etc/fstab ]] [root@localhost ~]# echo $? 1 [root@localhost ~]# [[ ! -f /etc/sysconfig ]] [root@localhost ~]# echo $? 0
[root@localhost ~]# echo "aaaa" || echo "bbbb" && echo "cccc" aaaa cccc [root@localhost ~]# echo $? 0 [root@localhost ~]# echo "aaaa" && echo "bbbb" || echo "cccc" aaaa bbbb [root@localhost ~]# echo $? 0 [root@localhost ~]# ecaho "aaaa" && echo "bbbb" || echo "cccc" -bash: ecaho: command not found cccc [root@localhost ~]# echo $? 0 [root@localhost ~]# eacho "aaaa" || echo "bbbb" && echo "cccc" -bash: eacho: command not found bbbb cccc [root@localhost ~]# echo $? 0 [root@localhost ~]# eacho "aaaa" || echao "bbbb" && echo "cccc" -bash: eacho: command not found -bash: echao: command not found [root@localhost ~]# echo $? 127