1.1 变量
变量:使用一串固定的字符来表示不固定的目标。
1.1.1 变量类型
在shell中会同时存在三种类型变量。
- 局部变量:局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
- 环境变量:所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。
必要的时候shell脚本也可以定义环境变量。
- shell变量:shell变量是由shell程序设置的特殊变量。
shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
1.1.2 变量操作
- 创建普通变量:name=“test”,注意:等号两边不能有空格。
- 创建局部变量:local name=“test”,使用
local
修饰的变量在函数体外无法访问,只能在函数体中使用。 - 创建只读变量:name=“only_read” -> readonly name,这种变量不可以被修改。
- 使用变量:echo $name 或者 echo ${name}
- 删除变量:unset name,删除之后的变量无法被访问,注意:无法删除只读变量。
1.1.3 字符串变量
1.1.3.1 字符串变量的创建
- 使用单引号创建:var=‘test’
这种方式创建的变量只能原样输出,变量无效,我们可以借用c中的“字符串常量”的定义理解这种特性。
除此以外,单引号中不能出现单独的单引号,转义也是不可以的。
- 使用双引号创建:var=“my name is ${name}”
这种方式创建的字符串变量有效,也可以出现转义符。
1.1.3.2 拼接字符串
-
字面量拼接
str="1""2"或者str01=“1”‘2’,这样就将1和2两个字符拼接在了一起。需要注意的是两个串之间不可以有空格。 -
变量拼接:下面这三种方式都可以拼接字符串变量。
- str= p a r t 01 {part01} part01{part02}
- str02=${part01}“end”
- str03=“${part01} ${part02}”
-
命令拼接:这里的date是一个shell命令,需要使用引用
str= date“end”
str02=`date`"end"
1.1.3.3 获取字符串长度
- 使用
wc -L
命令
wc -L
可以获取到当前行的长度,因此对于单独行的字符串可以用这个简单的方法获取,另外wc -l
则是获取当前字符串内容的行数。
echo "abc" |wc -L
- 使用
expr length
可以获取string的长度
expr length ${<!--{C}%3C!%2D%2D%20%2D%2D%3E-->str}
- awk获取域的个数
但是如果大于10个字符的长度时是否存在问题需要后面确认
echo "abc" |awk -F "" '{print NF}'
- 通过
awk+length
的方式获取字符串长度
echo "Alex"|awk '{print length($0)}'
- 通过
echo ${#name}
的方式
echo "Alex"|awk '{print length($0)}'
1.1.3.4 提取子字符串
代码 | 意义 |
---|---|
${varible##*string} | 从左向右截取最后一个string后的字符串 |
${varible#*string} | 从左向右截取第一个string后的字符串 |
${varible%%string*} | 从右向左截取最后一个string后的字符串 |
${varible%string*} | 从右向左截取第一个string后的字符串 |
$ var=firenation.jpg
$ echo ${var##\*i}
运行结果为on.jpg
2.使用${varible:n1:n2}
截取变量varible从n1到n2之间的字符串,可以根据特定字符偏移和长度,来选择特定子字符串,如下代码:
$ var=azula
$ echo ${var:0:3}
运行结果最终显示azu
。
1.1.4 数组
数组是多个变量的集合,它存储多个元素在一片连续的内存空间中。
在bash中,只支持一维数组,不支持多维数组。
1.1.4.1 数组定义与引用
定义一个数组方式如下:
数组名=(元素1 元素2 元素1 ... 元素n)
指定数组对应下标的元素进行赋值:
数组名[下标]=值
同时指定多个数组元素进行赋值:
数组名=([下标1]=值1 [下标2]=值2 ... [下标n]=值n)
引用数组对应下标的元素:
${数组名[下标]}
1.1.4.2 遍历数组元素
使用for
(或while
循环)循环遍历数组元素:
#!/bin/bash
a=(1 2 3 4 5 6)
for((i=0; i<10; i++))
do
echo "a[$i]=${a[$i]}"
done
除此以外我们还可以使用${a[*]}
或者${a[@]}
来遍历数组元素,具体代码如下:
#!/bin/bash
a=(1 2 3 4 5 6)
echo ${a[\*]}
echo ${a[@]}
1.1.4.3 获取数组长度
我们可以使用#
来获取数组长度,需要注意的是在shell脚本中我们越界访问数组时是不会报错的。
#!/bin/bash
a=(1 2 3 4 5 6)
echo ${a[\*]}
echo "a len: ${#a[\*]}"
我们先使用其获取数组中的元素后使用#
获取元素个数即可。
1.1.4.4 合并数组
我们可以如下进行拼接:
#!/bin/bash
a=(1 2 3 4 5 6)
b=("hello" "zhaixue.cc")
c=(${a[\*]} ${b[\*]})
这样我们就将两个数组拼接起来了。
1.1.4.5 删除数组元素
如果我们想要删除某个数组元素,具体代码如下:
#!/bin/bash
a=(1 2 3 4 5 6)
echo ${a[\*]}
echo "a len: ${#a[\*]}"
unset a[5]
echo ${a[\*]}
echo "a len: ${#a[\*]}"
我们如果要删除整个数组,可以执行unset a
,举例代码如下:
#!/bin/bash
a=(1 2 3 4 5 6)
echo ${a[\*]}
echo "a len: ${#a[\*]}"
unset a
echo ${a[\*]}
echo "a len: ${#a[\*]}"
1.1.3 变量传参
相关的变量含义为:
变量 | 含义 |
---|---|
$0 | 代表执行的文件名 |
$1 | 代表传入的第1个参数 |
$n | 代表传入的第n个参数 |
$# | 参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数。 |
$@ | 与$*相同,但是使用时加引号,并在引号中返回每个参数 |
$$ | 脚本运行的当前进程号 |
$! | 后台运行的最后一个进程的ID |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
1.2 运算符
原生的bash并不支持简单的数学运算,通常要通过其它命令来实现。
1.2.1 算数运算符
以下表格中的a
和b
都是变量。
运算 | shell中格式 |
---|---|
加法 | expr $a + $b |
减法 | expr $a - $b |
乘法 | expr $a \* $b |
除法 | expr $b / $a |
取余 | expr $b % $a |
赋值 | a=$b |
相等 | [ $a == $b ] |
不相等 | [ $a != $b ] |
需注意:条件表法式需要放在方括号之间,并且要有空格。使用
expr
进行计算时需要使用反引号,为了让读者更容易理解,给出下列示例代码。
#!/bin/bash
a=10
b=20
val=`expr $a + $b`
echo "a + b : $val"
1.2.2 关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
运算 | shell中的实现 | 主要符号 |
---|---|---|
检测两个数是否相等 | [ $a -eq $b ] | -eq |
检测两个数是否不相等 | [ $a -ne $b ] | -ne |
检测左边的数是否大于右边的 | [ $a -gt $b ] | -gt |
检测左边的数是否小于右边的 | [ $a -lt $b ] | -lt |
检测左边的数是否大于等于右边的 | [ $a -ge $b ] | -ge |
检测左边的数是否小于等于右边的 | [ $a -le $b ] | -le |
举例代码如下:
#!/bin/bash
a=1
b=2
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a == $b: a 等于 b"
1.2.1 布尔运算符
具体如下:
运算 | shell中的实现 | 主要符号 |
---|---|---|
非运算 | [ ! false ] | ! |
或运算 | [ $a -lt 20 -o $b -gt 100 ] | -o |
与运算 | [ $a -lt 20 -a $b -gt 100 ] | -a |
1.2.2 逻辑运算符
具体如下:
运算 | shell中的实现 | 主要符号 |
---|---|---|
逻辑的 AND | [[ $a -lt 100 && $b -gt 100 ]] | && |
逻辑的 OR | [[ $a -lt 100 ` |
布尔运算符和逻辑运算符的区别:
语法上,逻辑运算需要双括弧,布尔运算只需要单大括弧功能上,逻辑运算具有特殊的短路功能,即是在AND运算中第一个表达式为false时则不执行第二个表达式,在OR运算中第一个表达式为true时不执行第二个表达式。
1.2.3 字符串运算符
下表列出了常用的字符串运算符:
运算 | shell中的实现 | 主要符号 |
---|---|---|
检测两个字符串是否相等 | [ $a = $b ] | = |
检测两个字符串是否不相等 | [ $a != $b ] | != |
检测字符串长度是否为0 | [ -z $a ] | -z |
检测字符串长度是否不为 0 | [ -n “$a” ] | -n |
检测字符串是否为空 | [ $a ] | $ |
1.2.6 文件测试运算符
主要用于检测unix文件的各种属性:
运算 | shell中的实现 | 主要符号 |
---|---|---|
检测文件是否是块设备文件 | [ -b $file ] | -b file |
检测文件是否是字符设备文件 | [ -c $file ] | -c file |
检测文件是否是目录 | [ -d $file ] | -d file |
检测文件是否是普通文件(既不是目录,也不是设备文件) | [ -f $file ] 返回 true | -f file |
检测文件是否设置了 SGID 位 | [ -g $file ] | -g file |
检测文件是否设置了粘着位(Sticky Bit) | [ -k $file ] | -k file |
检测文件是否是有名管道 | [ -p $file ] | -p file |
检测文件是否设置了 SUID 位 | [ -u $file ] | -u file |
检测文件是否可读 | [ -r $file ] | -r file |
检测文件是否可写 | [ -w $file ] | -w file |
检测文件是否可执行 | [ -x $file ] | -x file |
检测文件是否为空(文件大小是否大于0) | [ -s $file ] | -s file |
检测文件(包括目录)是否存在 | [ -e $file ] | -e file |
举例如下:
#!/bin/bash
file="/home/westos/Desktop/textcpp/test.sh"
if [ -r $file ]
then
echo "文件可读"
else
echo "文件不可读"
fi
1.2.7 运算指令
1.(( ))
我们可以直接使用双圆括弧计算其中的内容,如((var=a+b))
该指令经常在if/while等条件判断中需要计算时使用。
2.let
在计算表达式的时候我们可以直接使用let
如:let var=a+b。
3.expr
在前面的内容中我们也提到了它,是非常常用的计算指令,使用时需要在外部增反引号
var=`expr a+b`
4.bc计算器
bc计算器支持shell中的小数进行运算,并且可以交互式或者非交互式的使用。
基本使用方式为
var=$(echo "(1.1+2.1)"|bc)
;
5.$[]
我们可以直接使用这种方式计算中括弧中的内容,如echo $[1+2]
1.3 控制语句
和其他语句不同,shell的流传呢个控制不可为空。接下来我们为大家介绍sehll中常用的语法。
1.3.1 if语句结构
1.3.1.1 if-fi
就类似于c中的if条件判断,如下:
if condition
then
command1
command2
...
commandN
fi
1.3.1.2 if-else-fi
代码如下:
if condition
then
command1
else
command2
fi
若condition成立则执行command1,否则执行command2。
为了做好运维面试路上的助攻手,特整理了上百道 【运维技术栈面试题集锦】 ,让你面试不慌心不跳,高薪offer怀里抱!
这次整理的面试题,小到shell、MySQL,大到K8s等云原生技术栈,不仅适合运维新人入行面试需要,还适用于想提升进阶跳槽加薪的运维朋友。
本份面试集锦涵盖了
- 174 道运维工程师面试题
- 128道k8s面试题
- 108道shell脚本面试题
- 200道Linux面试题
- 51道docker面试题
- 35道Jenkis面试题
- 78道MongoDB面试题
- 17道ansible面试题
- 60道dubbo面试题
- 53道kafka面试
- 18道mysql面试题
- 40道nginx面试题
- 77道redis面试题
- 28道zookeeper
总计 1000+ 道面试题, 内容 又全含金量又高
- 174道运维工程师面试题
1、什么是运维?
2、在工作中,运维人员经常需要跟运营人员打交道,请问运营人员是做什么工作的?
3、现在给你三百台服务器,你怎么对他们进行管理?
4、简述raid0 raid1raid5二种工作模式的工作原理及特点
5、LVS、Nginx、HAproxy有什么区别?工作中你怎么选择?
6、Squid、Varinsh和Nginx有什么区别,工作中你怎么选择?
7、Tomcat和Resin有什么区别,工作中你怎么选择?
8、什么是中间件?什么是jdk?
9、讲述一下Tomcat8005、8009、8080三个端口的含义?
10、什么叫CDN?
11、什么叫网站灰度发布?
12、简述DNS进行域名解析的过程?
13、RabbitMQ是什么东西?
14、讲一下Keepalived的工作原理?
15、讲述一下LVS三种模式的工作过程?
16、mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?
17、如何重置mysql root密码?
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
人员打交道,请问运营人员是做什么工作的?
3、现在给你三百台服务器,你怎么对他们进行管理?
4、简述raid0 raid1raid5二种工作模式的工作原理及特点
5、LVS、Nginx、HAproxy有什么区别?工作中你怎么选择?
6、Squid、Varinsh和Nginx有什么区别,工作中你怎么选择?
7、Tomcat和Resin有什么区别,工作中你怎么选择?
8、什么是中间件?什么是jdk?
9、讲述一下Tomcat8005、8009、8080三个端口的含义?
10、什么叫CDN?
11、什么叫网站灰度发布?
12、简述DNS进行域名解析的过程?
13、RabbitMQ是什么东西?
14、讲一下Keepalived的工作原理?
15、讲述一下LVS三种模式的工作过程?
16、mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?
17、如何重置mysql root密码?
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!