shell学习笔记

字符串
字符串替换
- ${变量名#匹配规则} 从变量开头进行规则匹配,将符合最短的数据删除。
- ${变量名##匹配规则} 从变量开头进行规则匹配,将符合最长的数据删除。
- ${变量名%匹配规则} 从变量尾部进行规则匹配,将符合最短的数据删除。
- ${变量名%%匹配规则} 从变量尾部进行规则匹配,将符合最长的数据删除。
- ${变量名/旧字符串/新字符串} 变量内容符合旧字符串,则第一个旧字符串会被新字符串取代。
- ${变量名//旧字符串/新字符串} 变量内容符合旧字符串,则全部旧字符串会被新字符串取代。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17var_1="I love you, Do you love me"
var=${var_1#*ov} # e you, Do you love me
var=${var_1##*ov} # e me
var=${var_1%ov*} # I love you, Do you l
var=${var_1%%ov*} # I l
var_2="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
第一个小写bin被替换为大写的BIN
var=${var_2/bin/BIN} # /usr/local/BIN:/usr/bin:/bin:/usr/sbin:/sbin
所有小写bin会被替换为大写的BIN
var=${var_2//bin/BIN} # /usr/local/BIN:/usr/BIN:/BIN:/usr/sBIN:/sBIN抽取子串
- ${string:position} 从string的 position 开始。
- ${string:position:length} 从position开始,匹配长度为 length
- ${string: -position} 从右边开始匹配。
- ${string:(position)} 从左边开始匹配。
- expr substr $string $postion $length 从 position 开始,匹配长度为 length
字符串长度
1 |
|
获取子串在字符串中的索引位置
expr index $string $substring 从1开始计算索引位置
1
2
3
4
5var_1="quickstart is an app"
ind=`expr index "$var_1" start` # 6
ind=`expr index "$var_1" uniq` # 1
ind=`expr index "$var_1" f` # 0计算子串长度
expr match $string substr
从头开始匹配子串长度,如果没有匹配到则返回0,匹配到了返回匹配子串的长度
1 | var_1="quickstart is an app" |
字符串替换大小写
1 | #! /bin/bash |
数组
定义数组
1 | array=('v1' 'v2' 'v3') |
输出数组内容
1 | {array[@]} # 输出全部内容 |
获取数组长度
1 | {#array} # 数组内元素个数 |
数组赋值
1 | array[0]="frank" # 给数组下标为1的元素赋值为frank |
删除数组
1 | unset array[2] # 清除元素 |
数组遍历
1 | for v in ${array[@]} |
函数
定义
函数名后面的圆括号不加任何参数
函数的完整定义必须置于函数的调用之前
1
2
3函数名 (){
函数体
}传参
1
2
3
4
5
6
7!/bin/bash
print_something(){
echo "hello $1" # $1 获取第一个参数
}
print_something Lion # Lion 为参数
print_something Frank # Frank 为参数参数获取
1
2
3
4
5
61~$9:函数的第一个到第9个的参数。
0:函数所在的脚本名。
#:函数的参数总数。
@:函数的全部参数,参数之间使用空格分隔。
*:函数的全部参数,参数之间使用变量$IFS值的第一个字符分隔,默认为空格,但是可以自定义。
?:显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。可以用于函数返回值返回值
1
2
3
4
5
6
7
8
9
10
11
12testFun(){
echo "helloworld!"
return 99
}
# 千万要注意shell并不像其他语言直接返回返回值,其返回值放到$?中,这也是为什么只能返回整型的原因
# 所以这种承接方法是错误的,获取到的值是echo打印的内容
# return_value=`testFun`
# 以下才是正确获取通过return返回的返回值的正确写法
testFun
echo "the return value is: $?"局部变量
不做特殊声明,shell中变量都是全局变量
局部变量 使用 local 关键字,函数内外同时存在同名变量,则函数内部会覆盖函数外部变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20!/bin/bash
localvar="fun1"
main() {
func1
func2
}
func1() {
local localvar="funlocal"
echo ${localvar}
localvar="fun2"
}
func2() {
echo ${localvar}
}
main "$@"循环
until
1
2
3
4until [ 条件判断式 ]
do
程序
donewhile循环
1
2
3
4while [ 条件判断式 ]
do
程序
donefor循环
两种程式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22//方式一
for 变量 in 值1 值2 值3 …(可以是一个文件等)
do
程序
done
这种语法中for循环的次数,取决于in后面值的个数(空格分隔),有几个值就循环几次,并且每次循环都把值赋予变量。
也就是说,假设in后面有三个值,for会循环三次,第一次循环会把值1赋予变量,第二次循环会把值2赋予变量,以此类推。
//方式二
for (( 初始值;循环控制条件;变量变化 ))
do
程序
done
语法二中需要注意:
初始值:在循环开始时,需要给某个变量赋予初始值,如i=1;
循环控制条件:用于指定变量循环的次数,如i<=100,则只要i的值小于等于100,循环就会继续;
变量变化:每次循环之后,变量该如何变化,如i=i+1。代表每次循环之后,变量i的值都加1。
逻辑控制
多分支case
每个程序之后;; 双分号结尾;以 case开头以esac结尾
1 | [root@localhost ~]$ vi sh/if-case.sh |
if
1 | if [ 条件判断式1 ] |
文件
文件与目录
| 操作符 | 说明 |
|---|---|
| pwd | 查看当前目录 |
| cd | 切换目录 cd.. cd ~ cd / |
| ls | 查看当前目录的文件列表 |
| mkdir | 创建目录或文件 |
| echo | 打印 |
| cat | 链接、查看文件 > , >> |
| less | 文件内容过多,以分页方式查看 |
| q | 退出 |
| mv | 移动, . 代表当前目录;移动文件到一个目录,最后一个为目标目录 |
| cp | 复制文件或目录 |
| rm | 移除文件或者目录 |
| rmdir | 删除目录 |
1 | # 移动文件到某个目录 |
运算
bash的运算有以下几种方式
$(( ))
只能计算整数
expr
语法格式: expr $num1 operator $num2
- num1 | num2 – num1 不为空且非0,返回 num1 ; 否则返回 num2
- num1 & num2 – num1 不为空且非0,返回 num1 ;否则返回0
- num1 < num2 – num1 小于 num2 ,返回1;否则返回0
- num1 <= num2 – num1 小于等于 num2 ,返回1;否则返回0
- num1 = num2 – num1 等于 num2 ,返回1;否则返回0
- num1 != num2 – num1 不等于 num2 ,返回1;否则返回0
- num1 > num2 – num1 大于 num2 ,返回1;否则返回0
- num1 >= num2 – num1 大于等于 num2 ,返回1;否则返回0
- num1 + num2 – 求和
- num1 - num2 – 求差
- num1 * num2 – 求积
- num1 / num2 – 求商
- num1 % num2 – 求余
let
let命令声明变量时 可以直接执行算术表达式1
2let "foo = 1 + 2"
echo $foo # 3运算符
文件测试运算符
文件测试运算符用于检测Unix/Linux文件的各种属性
| 操作符 | 说明 |
|---|---|
| -b file | 检测文件是否是块设备文件 |
| -c file | 检测文件是否是字符设备文件 |
| -d file | 检测文件是否是目录 |
| -f file | 检测文件是否是普通文件,不是目录或者设备文件 |
| -g file | 检测文件是否设置了SGID位 |
| -p file | 检测文件是否是明管道 |
| -r file | 检测文件是否可读 |
| -w file | 检测文件是否可写 |
| -x file | 检测文件是否可执行 |
| -s file | 检测文件是否为空 |
| -e file | 检测文件(包括目录)是否存在 |
-e $file exist 的缩写,表示文件是否存在。
-d $file directory 的缩写,表示文件是否为一个目录。
-f $file file 的缩写,表示文件是否是一个文件。
-L $file Link 的缩写,表示链接。
-r $file readable 的缩写,表示文件是否可读。
-w $file writable 的缩写,表示文件是否可写。
-x $file executable 的缩写,表示文件是否可执行。
$file1 -nt $file2 表示文件 file1 是否比 file2 更新。
$file1 -ot $file2 表示文件 file1 是否比 file2 更旧。
字符串测试运算符
运算符 说明 = 检测两个字符串是否相等 != 检测两个字符串是否不相等 -z 检测字符串长度是否为0 -n 检测字符串长度是否不为0 str 检测字符串是否不为空 $string1 = $string2 表示两个字符串是否相等。
$string1 != $string2 表示两个字符串是否不相等。
-z $string 表示字符串 string 是否为空。
-n $string 表示字符串 string 是否不为空。
数字测试运算符
运算符 单词 说明 -eq equal 检查两个数是否相等,相等返回true -ne not equal 检查两个数是否相等,不相等返回true -gt great than 检测左边的数是否大于右边的,如果是 返回true -lt less than 检测左边数是否小于右边数,如果是 返回true -ge great than or equal 检测左边数是否大于等于右边的,如果是,返回true -le less than or equal 检测左边数是否小于等于右边,如果是,返回true
如果在shell脚本中使用linux命令,可以使用$() 包裹命令,如 disk_size=$(df -h | awk ‘NR==2 {print $5}’)
$num1 -eq $num2 equal 的缩写,表示两个数字是否相等。
$num1 -ne $num2 not equal 的缩写,表示两个数字是否不相等。
$num1 -lt $num2 lower than 的缩写,表示 num1 是否小于 num2 。
$num1 -le $num2 lower or equal 的缩写,表示 num1 是否小于或等于 num2 。
$num1 -gt $num2 greater than 的缩写,表示 num1 是否大于 num2 。
$num1 -ge $num2 greate or equal 的缩写,表示 num1 是否大于或等于 num2
逻辑判断
&& 表示逻辑与,只要有一个不为真,整个条件测试为假。
|| 表示逻辑或,只要有一个为真,整个条件测试就为真。
! 表示反转测试条件。
变量
预定义变量
预定义变量 作用 $? 最后一次执行命令的返回状态,为0表示,上一个命令正确执行,否则代表上一个命令执行错误 $$ 当前进程的进程号 PID $! 后台运行的最后一个进程号PID
1 | [root@localhost sh]$ ls |
位置参数
| 位置参数变量 | |
|---|---|
| $n | $0 表示当前脚本程序的名称,$1-9代表第一到第九参数,10以上参数需要大括号 {10} |
| $* | 代表命令行中所有参数,$把所有参数看成一个整体 |
| $@ | 代表命令行中所有参数,每个参数区分对待 |
| $# | 代表命令行中所有参数的个数 |
1 | [root@localhost sh]$ vi parameter2.sh |
环境变量设置
export 声明的变量即是环境变量
环境变量查询和删除
env命令和set命令区别:set命令可以查看所有变量,而env命令只能查看环境变量
1 | [root@localhost ~]$ unset gender #删除环境变量gender |
变量删除
unset 变量名
变量查看
set
-u 调用未声明变量会报错
-x 执行之前会把命令先输出一次
+<参数> 取消魔偶个set曾启动的参数
1 | [root@localhost ~]$ set [选项] |
细节
反引号
如果命令不用反引号包含,命令不会执行,而是直接输出
只有用反引号包含的命令、使用${命令}的方式也是可以
1 | [root@localhost ~]$ echo ls |
单引号和双引号
如果输出使用单引号,则$name原封不动输出
如果输出使用双引号,则输出变量name的值sc
反引号和双引号括起来的命令会正常执行; 反引号被单引号括起来命令不会执行当做普通字符串输出
1 | [root@localhost ~]$ name=sc |
Shell反引号、$()和${}的区别
反引号与$()
用于命令替换,获取命令的返回值
1 | all_files=`ls` # 获取ls命令的执行结果 |
- ${}
用于变量替换
1 | echo ${A}B |
特殊变量替换
1 | 1. ${var:n} 若n为正数,n从0开始,表示在变量var中提取第n个字符到末尾的所有字符 |
[]和[[ ]] 、(())
1 | 在使用[]或者test指令进行字符串判空时,需要在引用的变量上加上双引号""。 |







