
Bash基础及使用
Bash基础及使用
作为一名测试开发工程师,掌握Shell脚本就像掌握了一把瑞士军刀。无论是自动化测试、环境部署,还是日常运维,Shell都是我们不可或缺的利器。今天就让我们从最基础的变量开始,一步步走进Shell的世界!
变量:Shell脚本的基石
变量定义:给数据起个名字
想象一下,变量就像是给数据贴标签的便利贴。在测试脚本中,我们经常需要存储测试数据、配置信息等。
# 基本变量定义
a=1
b=seveniruby
d="hello from testerhome"
e='hello from "霍格沃兹测试学院" '
f=ls
# 重要提醒:等号左右不要有空格!
# 错误示例:a = 1 (这会报错)
# 正确示例:a=1💡 测试工程师小贴士:
- 单引号:原样输出,不解析变量
- 双引号:支持变量替换和转义字符
- 在测试脚本中,建议使用有意义的变量名,如
test_url、expected_result等
变量使用:让数据动起来
# 基本使用方式
echo $a # 输出:1
echo ${b} # 输出:seveniruby
echo "$a" # 输出:1
# 在测试脚本中的实际应用
test_url="https://api.example.com"
api_key="your_secret_key"
echo "正在测试接口:$test_url"
echo "使用API密钥:${api_key}_v2" # 注意这里必须用{}🔧 实战技巧:
$var和${var}都能访问变量,但${var}更严谨- 当变量名后面紧跟其他字符时,必须使用
${var} - 未定义的变量默认为空值,这在测试中可能导致意外结果,建议先检查变量是否存在
预定义变量:系统给我们的礼物
Shell为我们预定义了很多有用的变量,就像测试环境中预配置的常量一样:
echo $PWD # 当前工作目录
echo $USER # 当前用户名
echo $HOME # 用户主目录
echo $PATH # 可执行文件搜索路径
# 在测试脚本中的应用
echo "当前测试用户:$USER"
echo "测试脚本位置:$PWD"
echo "日志将保存到:$HOME/test_logs"🎯 测试场景应用: 这些变量在自动化测试中特别有用,比如动态生成日志路径、检查执行环境等。
数组变量
❖ array=(1 3 4 6)
❖ array=(`ls`)
❖ echo ${array[2]};
❖ echo ${array[*]}
❖ echo ${#array[*]}
❖ 使⽤ () 来定义数组变量,中间使⽤空格隔开案例:
array=(a b c d)
echo $#
echo ${array[0]}
echo ${array[*]}
echo ${#array[*]}结果:
1
a
a b c d
4特殊符号的使⽤
❖ 双引号⽤于括起⼀段字符串值,⽀持$var形式的变量替换
❖ 单引号也表⽰其内容是字符串值,不⽀持转义
❖ \ 反斜线,某些情况下表⽰转义
❖ ((a=a+3)) 是整数扩展。把⾥⾯的变量当作整数去处理。
❖ {1..10} 等价于 seq 1 10,表⽰1到10
❖ seq 1 3 10 表⽰⽣成⼀个1到10,步进为3
for i in `seq 1 3 10`;
do
echo ${i}
done
a=6
echo $((a+=3))
for i in {1..10};
do
echo ${i}
done变量类型
❖ 字符串 a="xx"
❖ 数字 i=1314
❖ 布尔 a=true b=false
数字型变量操作
❖ 计算
❖ i=1;echo $i;echo $((i+1))
❖ 更新
❖ ((i=i+1));echo $i
❖ 只能进⾏整数计算
❖ 浮点数计算请使⽤ awk 'BEGIN{print 1/3}'
❖ 格式化显⽰可以换⽤ awk 'BEGIN{printf("%.2f\n", 1/3)}'
字符串操作
❖ 取值
❖ ${value:offset}${value:offset:length} 从变量中提取⼦串
❖ ${#value} 字符串长度
❖ ${#array[*]}和${#array[@]}表⽰数组中元素的个数
❖ 掐头去尾与内容替换
❖ ${value#pattern} ${value##pattern} #表⽰掐头
❖ ${value%pattern} ${value%%pattern} %表⽰去尾
❖ ${value/pattern/string} ${value//pattern/string} /表⽰替换
❖ #与## %与%% /与//的区别:最短匹配模式VS最长匹配模式
❖ ${var/#Pattern/Replacement} ${var/%Pattern/Replacement}例子
❖ xx="1234567";
❖ echo ${xx:2:3};
❖ echo ${xx/3/c};
❖ echo ${xx##*3};
❖ echo ${xx%%5*};
❖ echo $xx|awk '{print substr($0,2,3)}'
❖ echo $xx|sed 's#3#c#g'布尔变量
❖ true
❖ false
❖ 命令执⾏返回值 $?
❖ 任何命令执⾏都会有⼀个返回值
❖ 0表⽰正确
❖ ⾮0表⽰错误
判断的类型
❖ 算术判断
❖ 字符串判断
❖ 逻辑判断
❖ shell内置判断
算术判断
❖ [ 2 –eq 2 ] 相等
❖ [ 2 –ne 2 ] 不等
❖ [ 3 –gt 1 ] ⼤于
❖ [ 3 –ge 3 ] ⼤于等于
❖ [ 3 –lt 4 ] ⼩于
❖ [ 3 –le 3 ] ⼩于等于
❖ (())也可以表⽰算术⽐较。((10>=8)) ,((10==10))
字符串⽐较
❖ [ string1 = string2 ] 如果两字符串相同,则结果为真
❖ [ string1 != string2 ] 如果两字符串不相同,则结果为真
❖ [ -n "$var" ] 如果字符串不是空,则结果为真
❖ [ -z "$var" ] 如果字符串是空,则结果为真
❖ [[ "xxxx" == x* ]] 在表达式中表⽰0或者多个字符
❖ [[ xxx == x?? ]] 在表达式中表⽰单个字符
❖ 在引⽤变量的时候要记得加双引号[ -z "$a"] 否则当a未定义时会语法报错
逻辑判断
❖ [ 2 -ge 1 -a 3 -ge 4 ];echo $? 与
❖ [ 2 -ge 1 -o 3 -ge 4 ];echo $? 或
❖ [[ 2 -ge 1 && 3 -ge 4 ]];echo $? 与
❖ [[ 2 -ge 1 || 3 -ge 4 ]];echo $? 或
❖ [ ! 2 -ge 1 ];echo $? ⾮
内置判断
❖ -e file 如果⽂件存在,则结果为真
❖ -d file 如果⽂件是⼀个⼦⽬录,则结果为真
❖ -f file 如果⽂件是⼀个普通⽂件,则结果为真
❖ -r file 如果⽂件可读,则结果为真
❖ -s file 如果⽂件的长度不为0,则结果为真
❖ -w file 如果⽂件可写,则结果为真
❖ -x file 如果⽂件可执⾏,则结果为真
❖ [[]]是[]的扩展语法,在⽼的sh⾥并不⽀持。推荐⽤[]
逻辑控制
❖ 条件 if
❖ 分⽀ case
❖ 循环 for while until select
❖ Break 和 continue
❖ 有⽣之年也许你只需要⽤到if、for、while
If结构
参考文献:https://blog.csdn.net/wxx_0124/article/details/95305625
❖ if [ condition ] ; then …;fi
❖ if [ condition ] ; then …;else …;fi
❖ if [ condition ] ; then …;elif …;fi
❖ 简单的逻辑可以使⽤ && || 去替代
❖ 条件可以⽤命令返回值代替
Case 结构
❖ ⽤于条件太多的情况。每⼀个条件最后使⽤两个分号结尾,不可缺少。
case $var in
p1) … ;;
p2) … ;;
…
pn) … ;;
*) …;;
esacSelect
Select var in var_list;do ….;done;
菜单选择,⼀般与case结构⼀起⽤
for循环
参考文献:https://www.jb51.net/article/186134.htm
for(( c1 ; c2 ; c3 ));
do
… ;
done
E.g:
for((i=0;i<10;i++));do echo $i;doneFor 遍历循环
❖ ⽤于递归数组,还可以递归以空格隔开的字符串序列。或者是某个命令的返回值。
for f in $array[*];
do
…..
done
E.g:
ss="aa bb cc dd";for x in $ss;do echo $x ;done
for x in `ls` ;do echo $x ;done
ss=(aa bb cc "sss dd");for x in "${ss[@]}";do echo $x ;doneWhile 循环
i=0;while [ $i -lt 3 ] ;do echo $i;((i=i+1));done
❖ ⼀个有⽤的⼩技巧。⼀⾏⾏的读取⽂件内容 while read line;do echo $line;done < /tmp/tmp
退出控制
❖ return 函数返回
❖ exit 脚本进程退出
❖ break 退出当前循环
❖ continue 跳过当前的循环,进⼊下⼀次循环。
Bash运⾏环境
Shell 运⾏环境概念
❖ bash下还可以再重新启动⼀个shell,这个shell是sub shell,原shell会复制⾃⾝给他。在sub shell中定义的变量,会随着sub shell的消亡⽽消失
❖ () ⼦shell中运⾏
❖ $(ls) 表⽰执⾏ls后的结果,与``作⽤⼀致,不过可以嵌套
❖ {} 当前shell中执⾏
❖ $$ 当前脚本执⾏的pid
❖ & 后台执⾏
❖ $!运⾏在后台的最后⼀个作业的PID(进程ID)
Shell环境变量
❖ Shell⾸先是⼀个⼯作环境,有很多变量可以供我们使⽤。
❖ set 可以获得当前的所有变量
❖ env可以获得可以传递给⼦进程的变量
❖ export aa=bbbb 把私有变量导出
Shell 输⼊输出
❖ Read ⽤来读取输⼊,并赋值给变量
❖ echo ,printf可以简单输出变量。
❖ > fifile 将输出重定向到另⼀个⽂件
❖ >> 表⽰追加 等价于tee -a
❖ < fifile 输⼊重定向
❖ | 表⽰管道,也就是前⼀个命令的输出传⼊下⼀个命令的输⼊
⽂件描述符
❖ 输⼊⽂件—标准输⼊0
❖ 输出⽂件—标准输出1
❖ 错误输出⽂件—标准错误2
❖ 使⽤ 2>&1 >/tmp/tmp < /tmp/tmp
通配
❖ Bash可以⾃动扩展特定的关键词
❖ echo * 在shell中表⽰当前⽂件
脚本编写
❖ 注释
❖ 传⼊参数
❖ 函数
❖ 执⾏
❖ 调试
注释
参考文献:shell脚本中的多行注释_叨陪鲤的博客-CSDN博客_shell多行注释
❖ #以后的语句,shell不会解析。
❖ 多⾏注释可以考虑采⽤:<<
#########################################################################
# File Name: hereDocument.sh
# Author: sun
# mail: 13039040421@163.com
# Created Time: 2020年03月01日 星期日 11时00分27秒
#########################################################################
#!/bin/bash
<<comment
1. 可以用来多行注释
2. 常用来描述一个函数的用法说明
3. 使用任意个字符串括起来就行,不一定是comment
comment
usage(){
#如果添加一个'-',则用来说明忽略行首的制表符
cat <<EOF
usage:commond [-x] [-v] [-z] [file ...]
a short explation of the opteration goes here;
It might be a few lines long, but shouldn't be excessive.
EOF
}
if [ $# -ne 1 ];
then
usage
exit 0
fi
length=$1
#生成随机密码
tr -dc A-Za-z0-9_ < /dev/urandom | head -c${length} | xargs
exit传参
❖ $0 表⽰执⾏的程序,是相对于执⾏⽬录的路径
❖ $1 ,$2 ,$3 分别表⽰第⼏个参数。默认shell只⽀持9个参数,使⽤shift可以传递更多的参数。
❖ $@,$* 表⽰所有的参数,不含$0
❖ ${#*}和${#@}表⽰位置参数的个数
❖ 通过${*:1:3}, ${*:$#} 来表⽰多个参数。$@ PK $*
❖ $@ 可以在函数之间传递参数,并不改变参数的排列
❖ ⽐如 1 2 3 ‘ 4 5 “6 7” 8 ‘ 。这个参数在经过多次传递后,依然表⽰4个参数
❖ 记得使⽤”$ @” ,不要直接使⽤ $@
❖ $* 会把参数打散。相对顺序不变,但是参数的个数就变成8个了。
❖ 演⽰⽅法 ff()
❖ ff(){ for d in $ @ " $@" $ * " $*"; do echo $d ; done; } ; ff 1 2 '3 "4 5" 6' 7 "8 9"
函数
function name()
{
..
}❖ Function 可以省略。除了可以在脚本⽂件中使⽤函数外,还可以shell中定义。这些定义会在本次shell结束后消失。
❖ 如果没有return,返回值是最后⼀句指令的返回值。
执⾏⽅式
❖ chmod u+x xxx.sh; ./xxx.sh
❖ bash xxx.sh (这种⽅式会开启⼀个sub shell)
❖ source xxx.sh (在当前shell中执⾏ . Xxx.sh 同义)
❖ eval 可以执⾏shell原义语句
❖ exec 尽量不要使⽤,这会破坏当前的shell
