一、Shell基础
1、命令解释器
Shell是用户与linux内核之间的解释器,常见的shell解释器/bin/bash、/bin/sh、/bin/csh。可以使用chsh或usermod命令选择默认使用的登录shell。如果想使用其他shell可以直接输入命令,如输入sh,会直接创建一个sh shell,之后输入的命令会使用sh解释器常用的shell解释器是bash,因为其支持快捷键,Tab补齐,命令历史(history),命令别名(aliase),管道、标准输入和标准输出的重定向。
一行命令想分多行写时使用\,表示换行
2、输入和输出
2.1、输出重定向
linux命令输出结果默认是终端窗口,可以使用 >、>> 等命令可以对命令输出进行重定向
# 将命令执行结果输出到a.txt,会覆盖a.txt中原来的内容
command > a.txt
# 将命令结果输出到a.txt,不会覆盖,相当于append
command >> a.txt
2> : 会将命令的报错结果输入到指定文件中。
&> : 会将命令的正确结果和错误结果都输入到指定文件中
2.2、输入重定向
(1)、将文件作为命令的输入
# 将file内容作为command命令的输入
command < file
(2)、将输入内容作为命令的输入
# EOF之间的内容作为cat命令的输出内容,EOF只是常用的tag,用其他tag也可以
cat << EOF
1
2
3
EOF
结合输出重定向,有以下两种方式:
# 必须是以EOF结尾,输出重定向不能写在后面
cat >>test.txt << EOF
输入内容
EOF
或
cat << EOF >>test.txt
输入内容
EOF
注: EOF后面的内容,如果不是文件最好换行写
3、变量
(1)、定义变量
变量名=变量值
#定义一个变量name
name="xiaoming"
(2)、取消变量
unset 变量名,一般情况下脚本编写过程中,是不需要unset的,脚本执行完成后会自动回收
(3)、使用变量
$变量名 或 ${变量名},两者的区别在于:使用括号适合变量进行一些字符串拼接,
X=Centos
echo ${X}6.5
输出: Centos6.5
echo $X6.5
输出: x6.5
4、变量类型
1、环境变量
存储在/etc/profile或~/.bash_profile等文件,命令env可以列出所有环境变量
2、位置变量(存储脚本执行时传入的参数)
$1、$2、…、${10}、${11}…(超过9以后必须使用花括号)
3、预定义变量
bash内置变量,用来保存脚本程序的执行信息,可以调用但是不能赋值或修改
$0: 当前所在的进程或脚本名
$$: 当前进程的PID
$?:上一条命令的执行状态,0表示正常,非0表示执行错误
$#:已加载的位置变量的个数
$*:所有位置变量的值
$@:与$*作用相同,区别在与,没有双引号包括时两者都是数组,被双引号包裹时,$*表示一个字符串。
$!:shell最后运行的后台Process的PID
4、自定义变量
用户自主设置
5、$符号的几个用法
1、$()
该符号与反引号等价,都是用做命令替换的,将符号所在处的内容替换为命令的执行结果。在某个地方需要命令执行结果的时候使用。
2、${}
用于变量替换,将符号所在处的内容替换为变量的值。加上{}只是方便明确变量名的界限。
3、$[]
内部可以进行变量运算,且变量不需要使用$表示 ,并且将运算结果进行替换。其效果和$(())等价,但不同的是(())单独使用时,内部可以像C程序一样进行运算,而[]只有和$一起使用时才能进行变量运算并进行替换。
6、多种引号的区别
1、双引号和单引号
双引号允许扩展,可在字符串内使用变量,单引号不允许扩展。
echo "$USER id is $UID"
root id is 0
echo '$USER id is $UID'
$USER id is $UID
2、反引号
命令替换,程序会优先执行反引号中的内容,并使用运行结果替换掉反引号出的内容。
test=`grep root/tec/shadow`
等效于
test=$(grep root/tec/shadow)
。
7、几个常用的命令
1、read
read [-p “提示信息”] 变量名
该命令会将输入的信息赋值给该变量,如果输入的是密码,不想显示在屏幕中可以加 -s。
2、echo命令
格式:echo -e "\033[字背景颜色;文字颜色m 字符串\033[0m"
加-n表示不换行
\033可以替换为\e,表示控制码的开始,m表示控制码的结束,0是表示终止前面的效果
文字 背景
黑色:30 40
红色:31 41
绿色:32 42
黄色:33 43
蓝色:34 44
粉色:35 45
青色:36 46
白色:37 47
灰色:38 48
8、全局变量和局部变量
(1)、局部变量
新定义的变量默认只在当前的shell环境中有效,无法在子shell环境中使用
(2)、全局变量
全局变量在当前shell及子shell环境中均有效。定义全局变量时使用export,例如export x=11
注:定义环境变量时都是用export,就是为了在子shell中也有效
9、数组变量
1、数组的定义
数组名=(值1 值2 值3)
2、读取数组
echo ${array[i]}
echo ${array[@]}
i是索引,其中@和*是特殊的索引,表示数组的所有成员。
3、数组的长度
echo ${#arrary[@]}
echo ${#arrary[*]}
4、提取数组成员
echo ${array[@]:1:3}
# 返回从数组1号位置开始的3个成员
10、字符串处理与变量初始化
(1)、字符串或变量长度
phone=18842579666
echo ${#phone}
11
(2)、字符串截取
# 从数组3号位置开始,截取3位
echo ${phone:3:3}
425
# 从数组1号位置开始,全部截取
echo ${phone:1}
8842579666
# 从数组的2号位置开始,截至到剩余后三个
echo ${phone:2:-3}
842579
(3)、字串替换
替换一个子串: ${变量/旧字串/新字串}
替换所有子串: ${变量//旧字串/新字串}
phone=134345789
echo ${phone/3/X}
1X4345789
echo ${phone//3/X}
1X4X45789
(4)、字符串掐头
# 关键词是正则表达式,然后将正则表达式从头开始匹配
# 从左到右,最短匹配删除:${变量#关键词}
A=root:x:0:01
echo ${A#root}
:x:0:01
echo ${A#*:}
x:0:01
# 从左到右,最长匹配删除,${变量##关键词}
echo ${A##*:}
01
(5)、字符串去尾
从右到左,最短匹配删除:${变量%关键词}
从右到左,最长匹配删除:${变量%%关键词}
规则参考字符串掐头
(6)、变量初始化
变量有值,则返回该变量的值
变量无值,则返回关键词
格式: ${变量:-关键词}
ipass=${ipass:-123456}
上例,ipass如果没有初始化,则将其初始化为123456
12、函数
(1)、语法格式
在shell环境中,将一些需要重复使用的操作,定义为公共的语句块,即可称为函数。
function 函数名{
命令序列
.. ..
}
函数名(){
命令序列
.. ..
}
(2)、函数使用示例
#!/bin/bash
# 函数定义
myping (){
ping -c 3 -W1 $1 &>/dev/null
if [ $? -eq 0];then
echo "$1 is up"
else
echo "$2 is down"
fi
}
for i in {1..254}
do
# 函数调用,后面为传入的参数。 &符号表示将执行的函数放入后台执行
myping "192.168.4.$i" &
done
# 等待当前脚本的所有后台进程结束后退出脚本
wait
二、shell进阶
2、中断与退出执行
continue:结束单次循环,进入下一次循环
break:退出当前循环
exit:退出脚本
个人理解:关于continue和break的使用,在c语言中,我们往往是在循环体中使用if判断条件然后进行处理,在shell中可以直接借助&&,例如[ $i -eq 3 ] && continue
1、条件判断
1、字符串比较
(1)、判断字符串是否为空
# -z 字符串为空时为true
[ -z "test" ]
# ! -z 字符串非空时为true
[ ! -z "test" ]
# -n 字符串非空时为true
[ -n "test"]
(2)、判断字符串是否相等
[ 字符串1==字符串2 ]
[ 字符串1!=字符串2 ]
2、整数比较
[ 整数值1 操作符 整数值2 ]
操作符: -eq 等于,-ne 不等于,-ge 大于或等于,-le 小于或等于,-gt 大于,-lt 小于
例如: 执行[3 -lt 7],$?的结果为0,则表示3小于7是成立的
注意:中括号符号[]要与内容之间保持空格
3、文件状态测试
[ 操作符 文件或目录 ]
操作符:
-e: 是否存在
-d: 是否为目录
-f:是否为一般文件,其实还可以判断文件是否存在
-r:是否有可读权限
-w:是否有可写权限
-x:是否有可执行权限
4、布尔运算符
!:非运算符
-o:或运算
-a:与运算
[ 表达式1 -o 表达式2 ]
[ 表达式1 -a 表达式2 ]
通过echo $?得到上一次的命令执行结果来获取条件判断结果,如果结果为0则表示符合判断结果。条件判断可以结合!使用。
2、命令组合
1、;、&&、||
;符号可以组合命令,但是组合的命令之间只有先后顺序关系而已,例如:cd /etc/; ls 。表示进入etc目录,然后再执行ls
由&&和||组合的命令之间具有逻辑关系,如&&只有前一条命令执行结果为真的时候才会执行后续的命令
2、&&和||的优先级
在bash中,&&和||的优先级是相同的,与c语言中&&的优先级高于||是不同的。优先级决定的不是执行顺序,而是结合顺序。
3、if条件判断
注意:条件判断一般都是使用[]测试字符串、整数、文件。也可以是命令,命令执行成功即$?为0,则表示条件成立
1、使用格式:
方式1:
if 条件判断
then
命令序列1
elif 条件判断
then
命令序列2
…
else
命令序列n
fi
方式2:
if 条件测试;then
命令序列1
elif 条件判断;then
命令序列2
…
else
命令序列n
fi
4、for语法格式
格式1:
for 变量 in 值列表
do
命令序列
done
例:
for i in 1 2 3
do
echo "I am $i"
done
结果:
I am 1
I am 2
I am 3
注意值列表类型:
(1)、{1…10}则表示1 2 3 4 5 … 10 。英文字符列表也是如此{a…z},都可当作值列表
(2)、例如1 2 3 4也可直接用作值列表
(3)、命令输出结果也可用作值列表,例如$(ls -a)
(4)、变量数组,例如array=(1 2 3 4 5),则${array}可用作值列表
(5)、字符串也可以,只要内容是以空格或者换行符分割的就可以当作for循环的列表
格式2:
for((初值;条件;步长))
do
命令序列
done
例:
for((i=1;i<=3;i++))
do
ehco "I am $i"
done
结果:
I am 1
I am 2
I am 3
5、while
使用格式:
while 条件判断
do
命令序列
done
常见的死循环方式:while ((1))、while [ 1 ]、while true、while : 、while (( 1 )),还有for(( ; ; ))
6、case语句
case 变量 in
变量值1)
命令序列1;;
变量值2)
命令序列2;;
… …
*)
默认命令序列
esac
在命令序列的最后一条命令后必须加;;表示当前命令序列执行完毕
7、let和(())
在shell中,使用let可以像类似C语言一样进行计算,变量计算不需要加上$来表示变量。
例如:
[lighthouse@VM-8-12-centos day02]$ i=1
[lighthouse@VM-8-12-centos day02]$ let "i++"
[lighthouse@VM-8-12-centos day02]$ echo $i
2
(())作用是和let等同的,上例中的let "i++"换成((i++))作用相同。
8、[]与[[]]的区别
(1)、&&、||、<、>等操作符号可以在[[]]中使用,在[]结构中无法使用例如
if [[ $a != 1 && $a != 2 ]]
(2)、[[]]支持字符串的模式匹配,[]不支持。使用=或==进行字符串比较,等号右边的可以作为一个模式,比如[[ “hello” == hell? ]]为真。模式匹配不能加引号,否则会作为固定字符串,如[[ “hello” == “hell?” ]]为假。
(3)、[[]]支持算术扩展,而[]不支持。如if [[ 1+2 -eq 3 ]],而if [ 1+2 -eq 3 ]则会报错。