shell脚本编程
Bash为用户提供了编程环境
相对于计算机而言,只能识别二进制文件,因此其所运行的其实是二进制指令,而这些二进制指令我们称之为机器语言,属于低级语言;程序员编程所使用的语言为高级语言,是人们比较容易理解的语言;因此,程序的执行过程:先把源码程序翻译成机器语言(生成可执行的文件),然后解释执行。
程序( 程序=指令+数据 )的编程风格有两种:
-
面向过程的编程:以指令为中心,数据服务指令
面向对象的编程:以数据为中心,指令服务数据;
shell程序是一个过程式的解释器,提供了编程能力,然后解释执行;对于过程式编程而言,把一行源码程序翻译成机器语言,然后执行,再翻译下一行的源码程序为机器语言,然后执行;
-
编译过程:高级语言–>编译器–>目标代码
需要提前编译,编译成机器可以理解二进制文件,然后再执行
靠近底层,执行效率非常高,跨平台性比较差
C++ CentOS—-> SuSE(腾讯云)
C#(微软) 只能在windows运行
IIS C# .net SQLServer
Golang -
解释过程:高级语言–>解释器–>机器代码
并不需要提前编译,只需要把代码转换成中间代码,边解释边运行
执行效率稍逊,跨平台
JAVA、 Python 、Shell 、PHP 、Ruby
shell脚本:
shell脚本其实就是一系列命令组合起来的文本文件,利用这些命令组合起来完成一个或者一项功能;
-
shell脚本开头环境的指定:
#!/bin/bash
#
#Filename:BeiFen.sh
#Description:Test
#Author:Li Nan
#Email:xxx@126.com
#Revision:3.1
#Date:20170407
#Note:Test# 表示注释,此行不执行
-
shell脚本组成:
变量
命令
控制语句(if、for、while) -
运行脚本:
1、给予执行权限,通过具体的文件路径对指定文件执行;-
加执行权限
1)相对路径
2)绝对路径
3)放到$PATH变量指定的目录里面,直接执行(tab)
2、直接运行解释器,将脚本作为解释器程序的参数运行;
- bash、sh
3、脚本调试执行:
-
bash -n 检查语法错误,不检查拼写错误
bash -x 显示脚本执行的时候每一个命令具体的执行结果
-
加执行权限
变量
- 变量:命名的内存空间
- 数据存储的方式:字符、数值;
-
变量的作用:
-
1、数据存储格式
2、参与的运算
3、表示的数据范围
-
1、数据存储格式
变量的类型:
-
字符
数值:整型、浮点型
注:相同类型的数据在一起才可以进行运算,数值型和字符型不能运算 -
对于编程语言来说还分为:强类型、弱类型;
-
强类型:JAVA C#
数值型和字符型不能直接计算
除非显式 把字符型转换成数值型才可以计算C++
int a=10;
char a=10
double b=10 -
弱类型 :shell php
不会严格区分变量类型
定义变量的时候不用指定变量类型,默认字符型
如果想要计算的时候,会自动帮你转换成数值型Shell
I=10
J=2
-
变量的命名规则:
- 不能使用if for bash cd ls date关键字
-
不能以数字开头,不能使用特殊符号
只能使用数字 字母及下划线 - 见名知义
- 建议变量使用大写
bash变量的种类
-
本地变量(全局变量): 仅仅对当前shell生效
-
变量的赋值:name=’value’
value 可以使用引用:1、可以直接使用字符串;name = “username”
2、变量引用:name = “$username”
3、命令引用:name=COMMAND,name=$(COMMAND) -
变量引用:$name、${name}
“” :弱引用 会把双引号里面的变量替换
” :强引用 不会把引号里面的变量进行替换
“ : 把反引号里面的命令执行结果赋值给变量
HZ=$SH 用变量赋值变量 -
显示已定义的所有变量:set
-
取消变量:unset name
-
取消变量和变量置空是两种不同概念
unset HZ
HZ=
-
取消变量和变量置空是两种不同概念
-
-
环境变量 : 对当前shell以及其他shell都生效,使用export可使变量改变为环境变量
子shell只会继承环境变量,并不会继承父shell中的变量-
变量声明、赋值:
- export name = VALUE
-
name = VALUE
export name - declare -x name = VALUE
-
name = VALUE
declare -x name
-
变量引用:$name、${name}
- 显示所有环境变量:export、env、printenv、declare -x 、set
- 取消变量:unset name
-
Bash中有很多内建的环境变量(大写):PATH,SHELL,UID,HISTSIZE,PWD,OLD,HISTFILE,PS1等。
- 局部变量(私有变量) :通常用在函数里面,使用local定义
-
位置变量:$1,$2,…$n,${10}来表示,用于放在脚本代码中调用通过命令行传递给它的参数;
shift + [n] 换位置 -
特殊变量:
$?:上个命令执行成功与否的结果
$0:表示命令本身
$#:传递给脚本参数的个数
$*:传递给脚本的所有参数,(全部参数合为一个字符串)
$@:引用传递给脚本的所有参数,(每个参数为独立字符串)
当被括号括起来的时候会看出区别
$$:显示此脚本的进程号 -
只读变量:
只能声明,但不能修改和删除
声明只读变量:
readonly name
declare -r name
查看只读变量:
readonly -p
变量的高级操作
-
字符串切片
-
${变量:位置起点}
由指定的位置开始,截取字符串到字符串结束 -
${变量:位置起点:长度}
eg:MYNAME=”123456789″
substr2=${MYNAME:4:6} -
计算字符串长度
${#变量名称}
传回变量值的字符串长度
filename=”/usr/sbin/ntpd”
ehco ${#filename}PS:另一种方法:
expr length “$filename” -
由前面(最左边)开始,对比变量值,删除“最短相符合的字符串”
${变量#样式}
filename=”/usr/sbin/ntpdate”
echo ${filename#/*/} -
由前面对比,删除最长的
${变量##样式}
filename=”/usr/sbin/ntpdate”
echo ${filename##//}
-
由后面对比,删除最短的
${变量%样式}
filename=”/usr/sbin/ntpd”
echo ${filename%/
} -
由后面对比,删除最长的
${变量%%样式}
domainname=”www.178linux.com”
echo ${domainname%%.*}
-
由后面对比,删除最短的
- 只替换第一个对比符合的字符串
${变量/样式/替换字符串}
name=”liangchenye”
echo ${name/liang/wang} - 替换全部对比符合的字符串
${变量//样式/替换字符串}
name=”zhaoritian”
echo ${name//zhao/ye} - 把对比符合的字符串删除
只删除一个
${变量/样式/}
name=”liangchenye”
echo ${name/liang/} - 把对比符合的字符串全部删除
${变量//样式/}
name=”zhaoritian”
echo ${name//zhao/}
-
${变量:位置起点}
测试存在性及空值
-
${待测变量-默认值}
若变量不存在,则符合判断,传回默认值
unset myname
echo ${myaname-“fuerkang”} -
${待测变量:=默认值}
若变量不存在或其值为空,则符合判断,传回默认值
unset myname
echo ${myname:=”fuerkang”} -
测试变量是否为空或者不存在,提示错误信息
${待测变量:?提示信息}
echo ${name:?”sorry no name”} -
测试变量的存在性,若存在且非空,则符合判断
${待测变量:+”ture”}
echo ${magedu:+”true”}
-
${待测变量-默认值}
算数运算
bash会对数字执行隐式的类型转换
-
运算操作符:+、-、、/、%(取余)、*(乘方)
bash运算的实现方式:-
(1) let num=算术表达式 ,let r=9+9
(2) var=$[算术表达式] , r=$[9+9]
(3) var=$((算术表达式)) , r=$((9+9))
(4) 外部命令:expr 8 + 3 (+ 两边要有空格)
(5)declare -i,declare -i r=9+9
(6)bc ,echo {1..100} | tr ” ” “+” | bc
注意 :expr 8 * 8 ;乘号需要转义
-
(7)echo $((12+$i))是否可以执行
建议把$i中的$去掉
正确姿势 echo $((12+i)) -
bash内建的随机数生成器,$RANDOM (0-32767)
echo $[$RANDOM%50]:0-49之间的随机数
-
(1) let num=算术表达式 ,let r=9+9
-
赋值
-
增强型赋值:
+=, i+=3等于i=i+3
-=, i-=3等于i=i-3
=, i=3等于i=i*3
/=,
%= -
自增、自减:
++ 先执行 执行完加1 (用的比较多)
++i 先加1,再执行
var=$[$var+1]–>let var+=1 –> let var++
[root@Centos7 script]# a=10
[root@Centos7 script]# b=10
[root@Centos7 script]# let c=a++
[root@Centos7 script]# echo $c
10
[root@Centos7 script]# echo $a
11
[root@Centos7 script]# let d=++b
[root@Centos7 script]# echo $d
11
[root@Centos7 script]# echo $b
11 -
增强型赋值:
字体颜色
-
字体颜色:30——37
echo -e “\033[30m 黑色字 \033[0m”
echo -e “\033[31m 红色字 \033[0m”
echo -e “\033[32m 绿色字 \033[0m”
echo -e “\033[33m 黄色字 \033[0m”
echo -e “\033[34m 蓝色字 \033[0m”
echo -e “\033[35m 紫色字 \033[0m”
echo -e “\033[36m 天蓝字 \033[0m”
echo -e “\033[37m 白色字 \033[0m” -
字体背景颜色40—–47
echo -e “\033[40;37m 黑底白字 \033[0m”
echo -e “\033[41;37m 红底白字 \033[0m”
echo -e “\033[42;37m 绿底白字 \033[0m”
echo -e “\033[43;37m 黄底白字 \033[0m”
echo -e “\033[44;37m 蓝底白字 \033[0m”
echo -e “\033[45;37m 紫底白字 \033[0m”
echo -e “\033[46;37m 天蓝底白字 \033[0m”
echo -e “\033[47;30m 白底黑字 \033[0m”
逻辑运算
true (1)、false (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;
短路预算:
命令1 && 命令2 命令1 成功执行 则执行命令2
命令1 执行失败 则不会执行命令2命令1 || 命令2 命令1成功执行,则命令2不执行
命令1执行失败,则命令2执行命令1 && 命令2 || 命令3
如果命令1 成功执行 则执行命令2 且命令3不会执行
如果命令1 执行失败 那么命令2就不会执行,则命令3执行如果 命令1 成功
则 命令2;
否则 命令3;
退出状态
进程使用退出状态来报告成功或失败
-
0 代表成功,1-255代表失败
$? 变量保存最近的命令退出状态
[root@magedu bin]# ping -c1 -W1 hostdown &> /dev/null
[root@magedu bin]# echo $?
2
-
exit [n]:自定义退出状态码
注意:脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字
注意:如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码
测试条件
-
test 测试条件
[ 测试条件 ]
[[ 测试条件 ]] 条件测试的前后要加上空格
生产环境建议使用两个中括号 -
数值测试:
-gt: 是否大于
-ge: 是否大于等于
-eq: 是否等于
-ne: 是否不等于
-lt: 是否小于
-le: 是否小于等于[root@Centos7 script]# [ 1 -gt 2 ] && echo “OK”
[root@Centos7 script]# [ 3 -gt 2 ] && echo “OK”
OK
[root@Centos7 script]#
[root@Centos7 script]# [ 3 -ge 2 ] && echo “OK”
OK
[root@Centos7 script]# [ 2 -ge 2 ] && echo “OK”
OK -
字符串测试:
== 是否等于 [[ "abs" == ??? ]] 使用通配符不加引号 > 是否大于 < 是否小于 != 是否不等于 =~ 左边的字符串是否包含右边指定的字符串 -z 测试字符串是否为空 -n 测试字符串是否不为空 -f filename
注:此表达式一般用于[[]]中,并且用于字符串比较时用到的操作数都应该使用引号;
[[ -f filename ]] 应用:
[root@Centos7 script]# [[ -f /etc/profile ]] && echo “OK” || echo “not OK”
OK
[root@Centos7 script]#
[root@Centos7 script]# [[ -f /etc/profilefdfd ]] && echo “OK” || echo “not OK”
not OK
[root@Centos7 script]#
[root@Centos7 script]# [[ -f /etc/ ]] && echo “OK” || echo “not OK”
not OK -
文件测试
-
文件存在性测试:
-e FILE:文件存在性测试,存在为真,否则为假
-a FILE:同-e -
存在性及类别测试
-b FILE:是否存在且为块设备文件
-c FILE:是否存在且为字符设备文件
-d FILE:是否存在且为目录文件
-f FILE:是否存在且为普通文件
-h FILE 或 -L FILE:是否存在且为符号链接文件
-p FILE:是否存在且为命名管道文件
-S FILE:是否存在且为套接字文件 -
文件权限测试:(针对于当前用户)
-r FILE:是否存在且可读
-w FILE:是否存在且可写
-x FILE:是否存在且可执行 -
文件特殊权限测试:
-u FILE:是否存在且拥有suid权限
-g FILE:是否存在且拥有sgid权限
-k FILE:是否存在且拥有sticky权限 -
文件大小测试:
-s FILE:是否存在且非空 -
文件是否打开:
-t fd:fd表示文件描述符是否已经打开且与某终端相关
-N FILE:文件自从上一次被读取之后是否被修改过
-O FILE:当前有效用户是否为文件属主
-G FILE:当前有效用户是否为文件属组
-
文件存在性测试:
组合测试条件
-
COMMAND1 && COMMAND2 并且
COMMAND1 || COMMAND2 或者
! COMMAND 非
如:[[ -r FILE ]] && [[ -w FILE ]] -
EXPRESSION1 -a EXPRESSION2 并且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION
“!” 最高,”-a” 次之,”-o” 最低。
[]与[[]]的区别
-
[ $A == “boy” ]
报错:-bash:[: ==:期待一元表达式
使用[ “$A” == “boy” ]
或者[ X”$A” == X”boy” ] 或者 [[ “$A” == “boy” ]] ( 最佳方案) -
[ 1 > 2 ]
使用 [[ 1 > 2 ]]不用对大于号进行转义 -
[[ ]]支持通配符和正则表达式
[[ “aaa” == ??? ]]
[[ “aaa” =~ .{3} ]] 扩展正则表达式
bash的配置文件
-
按生效范围划分,存在两类:
-
全局配置:
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc -
个人配置:
~/.bash_profile
~/.bashrc
-
全局配置:
-
按功能划分,存在两类:
-
profile类:为交互式登录的shell提供配置
- 全局:/etc/profile,/etc/profile.d/*.sh
-
个人:~/.bash_profile
功用:
- 用于定义环境变量
- 运行命令或脚本
- bashrc类:为非交互式和交互式登录的shell提供配置
- 全局:/etc/bashrc
-
个人: ~/.bashrc
功用:
- 定义命令别名和函数
- 定义本地变量
-
profile类:为交互式登录的shell提供配置
shell登录两种方式
-
交互式登录:
- 直接通过终端输入账号密码登录;
-
使用 “su – UserName” 切换的用户
执行顺序:
/etc/profile –> /etc/profile.d/*.sh –> ~/.bash_profile –> ~/.bashrc
–> /etc/bashrc
- 非交互式登录:
- su UserName
- 图形界面下打开的终端
-
执行脚本
执行顺序:
~/.bashrc –> /etc/bashrc –> /etc/profile.d/*.sh
-
交互式登录:
编辑配置文件生效
- 重新启动shell进程
- . 或 source
bash 退出任务
- 保存在~/.bash_logout文件中(用户)
- 在退出登录shell时运行
- 用于:创建自动备份;清除临时文件;
语句控制
-
过程式编程语言有三种过程:
顺序执行:按照顺序一条一条语句执行
选择执行:按照条件进行选择执行
循环执行:按照给定的循环条件进行循环执行
其中顺序执行不需要特定的控制,只需要按照语句依次执行即可;选择执行,则需要特定的语句(if、case)来判断选择执行;
循环执行则需要特定的循环控制体来控制(for、while、until) -
read
-p 指定要显示的提示
-s 静默输入,不显示输入的字符
-n N指定输入的字符长度N
-d ‘字符’输入结束符
-t N TIMEOUT为N秒
read 从标准输入中读取值,给每个单词分配一个变量,所有剩余单词都被分配给最后一个变量
read -p “Enter a filename : ” FILE -
选择执行
- if
-
循环执行(for、while、until)
循环就是程序按照一定的条件反复进行执行相关操作,直到不再满足循环条件时结束;-
for、while:当型循环,条件为真时循环,条件为假时退出;
until :直到型循环,条件为假时循环,条件为真时退出; -
3种循环比较,循环主要有2种结构
-
从上面流程图,显然可以看出while循环是”当型的”,until循环是”直到的”
-
原创文章,作者:s,如若转载,请注明出处:http://www.178linux.com/73285
评论列表(2条)
主要介绍了bash编程的变量,循环语句,判断语句,内容写的很不详细,排版也非常好,继续努力 !
16Mi6rion,Exastem muitas marcas sérias, mas todos os dias surgem pedidos de ‘vamos fazer um post em troca de um bloquinho?’ e coisas do tipo.Não sei como tem gente que cai nessas.Concordo contigo q tá faltando uma boa dose de respeito!Beijo grande,