shell脚本编程初级篇
--------------------------------------------------------------------------------------------------------------------------------
程序脚本基本概念
程序:算法+数据结构
数据:程序的核心
算法:处理数据的方式
程序编程风格
过程式:以指令为中心,数据服务于指令
对象式:以数据为中心,指令服务于数据
高级编程语言
编译:高级语言→编译器→机器代码→执行,例如c,c++等
解释:高级语言→执行→解释器→机器代码,例如shell,python,php,javascript,perl等
编程逻辑处理方式
顺序执行、循环执行、选择执行
Shell脚本:包含一些命令或者声明,并符合一定格式的文本文件
格式要求:#!/bin/bash(或者其他类型的shell文件,根据使用的shell类型进行选择)
Shell脚本用途
自动化常用命令
执行系统管理和故障排除
创建简单的应用程序
处理文本或文件
编写完一个脚本后,使用chmoda+x给其执行权限,然后将脚本放入bash文件夹内或者更改$PATH或者输入绝对/相对路径来执行,写的脚本属于外部命令
变量
强类型:变量不经过强制转换,它永远是这个数据类型,不允许隐式的类型转换。一般定义变量时必须指定类型、参与运算必须符合类型要求;调用未声明变量会产生错误
如java,c#
弱类型:语言的运行时会隐式做数据类型转换。无须指定类型,默认均为字符型;参与运算会自动进行隐式类型转换;变量无须事先定义可直接调用如:bash不支持浮点数,php
变量命名法则:
1、不能使程序中的保留字:例如if,for
2、只能使用数字、字母及下划线,且不能以数字开头
3、见名知义
4、统一命名规则:驼峰命名法,例如小驼峰:studentName,大驼峰StudentName
局部变量:变量只能在当前进程使用,不可以给父进程或者子进程使用,name=“a”
环境变量:全局变量,生效范围为其自身和其子进程,不能给父进程使用,exportname=”a”
本地变量:生效范围为当前shell进程中某代码片断,通常指函数
位置变量:$1,$2,...来表示,用于让脚本在脚本代码中调用通过命令行传递给它的参数
特殊变量:$?,$0,$*,$@,$#,$$
$?判断前一个命令成功还是失败,没有特别指定下,0为成功,1-255为失败
$0脚本名
$*所有参数,参数是一个独立的整体
$@所有参数,参数是独立的个体
$#参数个数
$数字第数字个参数
$@$*只在被双引号包起来的时候才会有差异
Shift:shift键1次后,第一个参数将没有,之前第二个参数变为第一个参数,第n个参数变为第n-1个参数
$$查看命令当前进程
$PPID查看当前进程的父进程
启用命令source、.和bash之间的区别
Source/.运行脚本不开启子进程,会影响变量,而bash开启子进程,不会影响变量,所有一般使用bash激活脚本,除非设备需要变化环境变量才会使用./source
变量赋值
变量赋值:name=‘value’,可以使用引用value:
(1)可以是直接字串;name=“root"
(2)变量引用:name="$USER"
(3)命令引用:name=`COMMAND`name=$(COMMAND)
变量引用:${name}$name
"":弱引用,其中的变量引用会被替换为变量值
'':强引用,其中的变量引用不会被替换为变量值,而保持原字符串
显示已定义的所有变量:set
删除变量:unsetname
显示所有环境变量:
env
printenv
export
declare-x
只读变量:只能声明,但不能修改和删除
声明只读变量:
readonlyname
declare-rname
查看只读变量:readonly–p
位置变量:在脚本代码中调用通过命令行传递给脚本的参数
set--清空所有位置变量
算术运算
bash中的算术运算:helplet
+,-,*,/,%取模(取余),**(乘方)
实现算术运算:
(1)letvar=算术表达式
(2)var=$[算术表达式]
(3)var=$((算术表达式))
(4)var=$(exprarg1arg2arg3...)
(5)declare–ivar=数值
(6)echo‘算术表达式’|bc
乘法符号有些场景中需要转义,如*
bash有内建的随机数生成器:$RANDOM(0-32767)
echo$[$RANDOM%50]:0-49之间随机数
赋值
增强型赋值:
+=,-=,*=,/=,%=
letvarOPERvalue
例如:letcount+=3
自加3后自赋值
自增,自减:
letvar+=1
letvar++
letvar-=1
letvar—
逻辑运算
true, false
1, 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,结果必定为0
第一个为1,第二个必须要参与运算
短路或
第一个为1,结果必定为1
第一个为0,第二个必须要参与运算
异或:^
异或的两个值,相同为假,不同为真
条件测试
判断某需求是否满足,需要由测试机制来实现
专用的测试表达式需要由测试命令辅助完成测试过程
评估布尔声明,以便用在条件性执行中
若真,则返回0
若假,则返回1
测试命令:test EXPRESSION
[ EXPRESSION ]
[[ EXPRESSION ]]
注意:EXPRESSION前后必须有空白字符
根据退出状态而定,命令可以有条件地运行,&& 代表条件性的AND THEN,|| 代表条件性的OR ELSE
测试命令
test命令
长格式的例子:
test "$A" = "$B" && echo "Strings are equal"
test “$A”-eq “$B” && echo "Integers are equal"
简写格式的例子:
[ "$A" = "$B" ] && echo "Strings are equal"
[ "$A" -eq "$B" ] && echo "Integers are equal"
bash的数值测试
-v VAR
变量VAR是否设置
数值测试:
-gt 是否大于
-ge 是否大于等于
-eq 是否等于
-ne 是否不等于
-lt 是否小于
-le 是否小于等于
bash的字符串测试
字符串测试:
= 是否等于
> ascii码是否大于ascii码
< 是否小于
!= 是否不等于
=~ 左侧字符串是否能够被右侧的PATTERN所匹配
注意: 此表达式一般用于[[ ]]中;扩展的正则表达式
-z "STRING“ 字符串是否为空,空为真,不空为假
-n "STRING“ 字符串是否不空,不空为真,空为假
注意:用于字符串比较时的用到的操作数都应该使用引号
Bash的文件测试
存在性测试
-a FILE:同-e
-e FILE: 文件存在性测试,存在为真,否则为假
存在性及类别测试
-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:当前有效用户是否为文件属组
双目测试:
FILE1 -ef FILE2: FILE1是否是FILE2的硬链接
FILE1 -nt FILE2: FILE1是否新于FILE2(mtime)
FILE1 -ot FILE2: FILE1是否旧于FILE2
Bash的组合测试条件
第一种方式:
COMMAND1 && COMMAND2 并且
COMMAND1 || COMMAND2 或者
! COMMAND 非
如:[[ -r FILE ]] && [[ -w FILE ]]
第二种方式:
EXPRESSION1 -a EXPRESSION2 并且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION
必须使用测试命令进行
使用read来把输入值分配给一个或多个shell变量
-p 指定要显示的提示
-s 静默输入,一般用于密码
-n N 指定输入的字符长度N
-d ‘字符’ 输入结束符
-t N TIMEOUT为N秒
read 从标准输入中读取值,给每个单词分配一个变量
所有剩余单词都被分配给最后一个变量
read -p “Enter a filename: “ FILE
把命令行分成单个命令词
展开别名
展开大括号的声明({})
展开波浪符声明(~)
命令替换$() 和 ``)
再次把命令行分成命令词
展开文件通配(*、?、[abc]等等)
准备I/0重导向(<、>)
运行命令
防止扩展
反斜线(\)会使随后的字符按原意解释
$ echo Your cost: \$5.00
Your cost: $5.00
加引号来防止扩展
单引号(’)防止所有扩展
双引号(”)也防止所有扩展,但是以下情况例外:
$(美元符号) - 变量扩展
`(反引号) - 命令替换
\(反斜线) - 禁止单个字符扩展
!(叹号) - 历史命令替换
bash的配置文件
按生效范围划分,存在两类:
全局配置:
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
个人配置:
~/.bash_profile
~/.bashrc
shell登录两种方式
交互式登录:
(1)直接通过终端输入账号密码登录
(2)使用“su - UserName” 切换的用户
执行顺序:/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc
非交互式登录:
(1)su UserName
(2)图形界面下打开的终端
(3)执行脚本
(4)任何其它的bash实例
执行顺序: ~/.bashrc --> /etc/bashrc --> /etc/profile.d/*.sh
Profile类
按功能划分,存在两类:
profile类和bashrc类
profile类:为交互式登录的shell提供配置
全局:/etc/profile, /etc/profile.d/*.sh
个人:~/.bash_profile
功用:
(1) 用于定义环境变量
(2) 运行命令或脚本
Bashrc类
bashrc类:为非交互式和交互式登录的shell提供配置
全局:/etc/bashrc
个人:~/.bashrc
(1) 定义命令别名和函数
(2) 定义本地变量
编辑配置文件生效
修改profile和bashrc文件后需生效
两种方法:
1重新启动shell进程
2 . 或source
Bash 退出任务
保存在~/.bash_logout文件中(用户)
在退出登录shell时运行
用于
创建自动备份
清除临时文件
$-变量
h:hashall,打开这个选项后,Shell 会将命令所在的路径hash下来,避免每次都要查询。通过set +h将h选项关闭
i:interactive-comments,包含这个选项说明当前的 shell 是一个交互式的 shell。所谓的交互式shell,在脚本中,i选项是关闭的。
m:monitor,打开监控模式,就可以通过Job control来控制进程的停止、继续,后台或者前台执行等。
B:braceexpand,大括号扩展
H:history,H选项打开,可以展开历史列表中的命令,可以通过!感叹号来完成,例如“!!”返回上最近的一个历史命令,“!n”返回第 n 个历史命令