一、Linux Bash介绍
Bash是UNIX系统下的一个命令解析器,全称为Bourne-Again Shell是一个为GNU开源项目编写的Unix shell。bash功能强大,尤其是在处理自动循环或者耗时大的任务方面可以节省大量时间,同时他也是Linux平台的内定Shell。
二、创建运行Bash示例
1 - 新建文件test.sh
touch test.sh
2 - 为bash文件test.sh添加可执行权限
chmod +x test.sh
3 - 使用vim编辑test.sh,修改内容如下
#! /bin/bashecho "hello world"exit 0
4 - 执行bash脚本
/bin/bash test.sh
三、bash的基础语法
1 - [ ]条件表达式
基本语法格式
[ Expression ]
语法说明:
注意条件表达式与两个中括号之间一定要有空格
Expression使用说明参考如下:
条件判断表达式Expression说明
Expression表达式 | Expression说明 |
Expression | Expression为真 |
!Expression | Expression为假 |
Expression1 -a Expression2 | Expression1和Expression2同时为真 |
Expression1 -o Expression2 | Expression1或Expression2同时为真 |
-n STR | 字符串STR的长度不为0 |
-z STR | 字符串STR的长度为0 |
STR1 = STR2 | 字符串相等 |
STR1 != STR2 | 字符串不相等 |
num1 -eq num2 | num1 等于 num2 |
num1 -ge num2 | num1 大于或等于 num2 |
num1 -gt num2 | num1大于num2 |
num1 -le num2 | num1小于或者等于num2 |
num1 -lt num2 | num1小于num2 |
num1 -ne num2 | num1不等于num2 |
File1 -ef File2 | 文件File1和File2有相同的device和inode数目 |
File1 -nt File2 | File1的修改时间早于FIle2 |
File1 -ot File2 | File1的修改时间晚于File2 |
-b File | File是块设备 |
-c File | File是字符设备 |
-d File | File是文件夹 |
-e File | File存在 |
-f File | File存在且是一个文件 |
-g File | File存在,且有group-id |
-G File | FIle存在,且group-ID是有效的 |
-h File | File存在且是一个硬链接 |
-k File | File存在,且它的sticky bit被设置了 |
-L File | File存在,且是一个软连接 |
-O File | File存在且它的拥有者是有效的 |
-p File | File存在,且是一个管道文件 |
-r File | File存在,且有可读权限 |
-s File | File存在,且size大于0 |
-S File | File存在,且是socket文件 |
-w | File存在且具有可写权限 |
-x File | File存在且具有可执行权限 |
使用示例
## 判断变量num是否等于50[ "$num" -eq "50" ]## 判断文件/home/temp/123.txt是否存在[ -f /home/temp/123.txt ]
2 - 逻辑表达式
使用说明
Expression指的条件表达式
1)逻辑与
[ Expression1 -a Expression2 ] 或者[ Expression1 ] && [ Expression2 ]
2)逻辑或
[ Expression1 -o Expression2 ] 或者[ Expression1 ] || [ Expression2 ]
3)逻辑否
[ ! Expression]
3 - test判断语句
基础语法格式:
test Expression
语法说明:
test表示判断 Expression表示被判断
使用示例:
判断当前目录下123.txt是否存在且是一个文件
test -f 123.txt## 输出结果0表示成功存在且是文件 其他表示失败## echo $?可输出上一个命令的执行结果到当前终端
4 - if then else语句
基础语法格式
if Expression; then
Statement1
elif Expression2; then
Statement2
else Statement3
fi
基础语法说明:
if语句必须以单词fi终止。elif和else为可选项,表示其他条件
使用示例:
判断文件是否存在
#! /bin/bashif [ -f 123.txt ];thenecho "file exists"elseecho "file not exists"fiexit 0
判断数字大小
#!/bin/bashnum1=0num2=1if [ "$num1" -eq "$num2" ]; thenecho "$num1 equal $num2"elseecho "$num1 not equal $num2"fiif [ "$num1" -le "$num2" ]; thenecho "$num1 less or equal than $num2"elseecho "$num1 greater than $num2"fiexit 0
5 - case语句
case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令
基础语法格式:
case 值 in
模式1)
Statement1
;;
模式2)
Statement2
...
;;
esac
基础语法说明:
模式部分可以为元字符,例如:
* 任意字符
? 任意单字符
[...] 范围中任意字符
使用示例:
#! /bin/bash# 输入字符串echo -n "are you female(Y/N):"# 保存用户输入的值到va中read valcase $val inY|y)echo "yes";;N|n)echo "no";;*)echo "invalid Input";;esacexit 0
6 - for循环
基础语法格式:
for 变量名 in 列表
do
Statement1
Statement2...
done
使用示例:
#! /bin/bash# 输出当前目录的文件CUR_DIR=`ls`echo $CUR_DIRfor val in $CUR_DIRdoif [ -f "$val" ]; thenecho "File: $val"fidone# 输出1-10之间数字的总和sum=0for ((i=1;i<10;i++))do((sum=$sum+$i))doneecho "sum=$sum"exit 0
7- until循环
基础语法格式:
until Expression
Statement1
...
done
基础语法说明:
条件可为合法的条件表达式,测试发生在循环末尾,因此循环至少执行一次。
使用示例:
#! /bin/bashval=0until [ "$val" -eq "5" ]doecho "val=$val"((val++))done
8 - while循环
基础语法格式:
while Expression
do
Statement1
Statement2
...
done
使用示例:
#! /bin/bashval=0while [ "$val" -lt "5" ]doecho "val=$val"((val++))done;
9 - 使用break和continue控制循环
基础语法格式:
break命令用于跳出循环
continue跳出当前循环步从循环开始出重新执行
使用示例:
break
#! /bin/bashval=0while truedoif [ "$val" -eq "5" ];thenbreakelseecho "val=$val"((val++))fidoneexit 0
continue
#! /bin/bashval=-1while [ "$val" -lt "10" ]do((val++))if [ "$val" -eq "5" ];thencontinue;elseecho "val=$val"fidoneexit 0
四、Bash数组
1 - 数组定义
1)array=(1 2 3 4)
一对括号表示的是数组,数组元素用“空格”分割开
2)单独定义数组 array[0]=10 array[1]=11 array[3]=13
3)var="10 20 30 40"; array=($var)
2 - 数组操作
1)显示数组中的第2项
echo ${array[1]}
2)显示数组中的所有元素
echo ${array[@]}
或者
echo ${array[*]}
3)显示数组长度
echo ${#array[@]}
等价于
echo ${#array[*]}
4)删除数组中的第2项元素
unset array[1]
5)删除整个数组
unset array
6)输出数组的第1-3项
echo ${array[@]:0:3}
等价于
echo ${array[*]:0:3}
7)将数组中的0对应的下表元素值替换成7
echo ${a[@]/0/7}
注意这里修改只是数组副本的值原数组并未修改
五、函数
基础语法格式
function funcName(){
...
}
语法说明:
function可以去掉但建议保留,这样阅读代码更方便
使用示例:
#! /bin/bashfunction myAddCal(){local sum=0local num=$@for ((i=0;i<${num[0]};i++))do((sum=$sum+$i))donereturn $sum}myAddCal 10echo "1+2+....10=$?"exit 0
六、数值运算
bash脚本常用的数值运算方式有四种,包括(())、let、expr、bc
效率对比:
(()) == let > expr > bc
(())和let是bash的内建命令,执行效率较高,而expr和bc是系统命令会消耗内存,执行效率低,并且let、(())和expr只支持整数运算,bc支持浮点数运算
使用示例
#! /bin/bash## 数学运算(方式1:$(())实现)val=$((3*(5+2)))echo "(()) val=$val"## 数学运算(方法2:let实现)let "val=3*(5+2)"echo "let val=$val"## 数学运算(方法3:expr实现)注意3和expr和\符号之间必须有空格加号运算两侧的操作数5和2与大## 括号之间也必须有空格val=`expr 3 \* \( 5 + 2 \)`echo "expr val=$val"## 数学运算(方法4:bc实现)val=`echo "3*(5+2)"|bc`echo "bc val=$val"exit 0
七、字符串运算
1 - 字符串定义
字符串定义
字符串定义 | 定义说明 |
${str} | 变量str的值,与$str相同 |
${str-DefaultStr} | 如果str没有被声明,那么就以DefaultStr为其值 |
${str:-DefaultStr} | 如果str没有被声明,或者其值为空,那么就以DefaultStr作为其值 |
${str=DefaultStr} | 如果str没有被声明,那么就以DefaultStr作为其值 |
${str:=DefaultStr} | 如果str没有被声明,或者其值为空,那么就以$DefaultStr作为其值 |
${str+OTHER} | 如果str声明了,那么其值就是OTHER,否则就为null字符串 |
${str:+OTHER} | 如果str被设置了,那么其值就是OTHER,否则就是null字符串 |
${str?ERR_MSG} | 如果str没被声明,那么就打印ERR_MSG |
${str:?ERR_MSG} | 如果str没被设置,那么就打印ERR_MSG |
使用示例:
#! /bin/bashstr1="hello"echo "${str1-DefaultStr}"str2=" "echo "${str2:-DefaultStr}"echo "${str3=DefaultStr3}"str4=""echo "${str4+OTHER}"echo "${str5?ERR_MSG}"
2 - 字符串操作
String操作定义
String操作 | 操作说明 |
${#str} | 字符串str的长度 |
${str:position} | 在字符串str中从position开始提取字符串 |
${str:position:length} | 在字符串str中从position处提取长度为length的子串 |
${str#substring} | 从字符串str开头,删除最短匹配substring的子串 |
${str##substring} | 从字符串str的开头,删除最长匹配substring的子串 |
${str%substring} | 从字符串str的结尾,删除最短匹配substring的子串 |
${str%%substring} | 从字符串的结尾,删除最长匹配substring的子串 |
${str/substring/replacement} | 使用replacement来替代第一个匹配的字符串substring |
${str//substring/replacement} | 使用replacement代替所有匹配的substring |
${str/#substring/replacement} | 如果str的前缀匹配substring那么就用replacement替代它 |
${str/%substring/replacement} | 如果str的后缀匹配substring,那么就用replacement来替代匹配到的substring |
使用示例:
#! /bin/bashstr="hello world"echo "${#str}"echo "${str:1}"echo "${str:1:3}"echo "${str#hello}"echo "${str##hello*}"echo "${str/hello /Hello}"
八、bash自带参数
bash自带参数
参数 | 参数说明 |
$? | 上一个代码或者shell程序在shell中退出的情况,如果正常退出则返回0 |
$# | 代表后接的参数个数 |
$@ | 代表全部变量,例如["$1" "$2" "$3"]每个变量是独立的(使用空格隔开) |
$* | 代表全部变量,例如["$1 $2 $3"] |
$- | 在shell启动时或者使用set命令时提供选项 |
$$ | 当前shell的进程号 |
$! | 上一个子进程的进程号 |
$0 | 当前shell名 |
$n | 位置参数值,n表示位置,n取值大于0的整数,$1表示第一个参数 |
使用示例:
九、bash命令调试
1 - bash调试
bash [-nvx] script.sh
选项与参数:
-n: 不要执行script只是查询语法问题
-v: 在执行script之前,先将script的内容输出到终端
-x: 将使用到的script内容显示到终端,通常用于调试查看bash的调用流程
2 - echo调试
echo [-neE] String
选项与参数:
-n: 输出内容之后不进行换行,默认是输入内容之后进行换行,通常用于用户输入脚本参数
-e: 开启反斜线"\"转义功能
-E: 开启反斜线转义功能(默认)
3 - printf
与echo一样也可用于输出,语法与c一样高
使用示例:
printf "hello world\n"
十、bash注释
1 - 单行注释
# 注释单行
# 放在开头表示注释掉本行
2 - 多行注释
:||{...被注释的多行}
或者
if false;then...注释多行fi
十一、bash的内建指令
1 - 常用内建指令的查看方法
基本语法格式
type cmd
用于判断命令cmd是否是bash的内建命令若是输出builtin
2 - 常用的内建命令
1)echo
2)read var
从标准设备输入中读取一行,分解成若干个变量赋值给变量var
3)alias name='value'
使用别名name替换value,value为参数名必须使用单引号括住
4)export var=value
export可以把bash的变量向下带入子bash(即子bash中可以使用父bash的变量),从而让子进程继承父进程中的环境变量。但子bash不能用export把它的变量向上带入父bash。
5)readonly var
定义只读变量。不带任何参数的readonly会输出所有的只读变量
6)exec args(命令参数)
当bash执行到exec语句时,不会去创建新的子进程,而是转去执行指定的命令,当指定的命令执行完时,该进程(也就是最初的bash)就终止了,所以bash程序中exec后面的语句将不再执行