变量:
自定义变量、环境变量、命令行变量。
(1)变量的定义和赋值
注意:赋值号两边没有空格;变量只能包含英文字母和数字,且不能以字母开头。
(2)变量的引用:$
(3)变量的种类
普通用户自定义变量;系统预定义的环境变量;命令行变量,如$#、$*。
命令行变量
特殊符号
单引号:单引号之间的内容原封不动赋值给变量。//内部所有成分被视为普通字符
双引号:将双引号中的词变成一个值赋值。如:today="today is `date`", //反引号里面的变量视为命令 等同于 "today is" $(date)
反引号:命令替换。
管道符:将前一命令的结果提交给后一个命令再加工。
重定向:>(输出)、<(输入)【标准输入:0,标准输出1,标准出错2】
如:ls 1> 1.txt 【1>之间无空格】
echo
"hello world"
1
>
&2 【
把一句话输出到标准出错设备中去
】
计算字符串个数:echo "${#var}"
数值测试
【
test命令专门用来实现所谓的测试语句,用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试】【 使用[]代替test
[
-e
1
.c
]
&&
[
-r
1
.c
]
】
-eq 等于则为真 -ne 不等于则为真
-gt 大于则为真 -ge 大于等于则为真
-lt 小于则为真 -le 小于等于则为真
注:test后不加括弧
字符串测试
=:等于则为真
!=:不相等则为真
-z :字符串长度为0则为真
-n:字符串长度不为0则为真
文件测试
-e:文件存在则为真
-r:文件存在且可读则为真
-w:文件存在且可写则为真
-x:文件存在且可执行则为真
-s:文件存在且至少有一个字符则为真
-d:文件存在且为目录则为真
-f:文件存在且为普通文件则为真
-c:文件存在且为字符型特殊文件则为真
-b:文件存在且为块特殊文件则为真
字面量拼接:
str01="1""2"或者str01="1"'2' 【字面量之间不能有空格】
变量拼接:
str03=${part01}${part02} 或 str04=${part01}"end" 或 str05="${part01} ${part02}"
获取字符串长度
wc -l:获取字符串内容的行数
expr length:获取string的长度
awk:获取域的个数,如:
echo
"abc"
|
awk
-F
""
'{print NF}'
awk+length:获取字符串的长度,如:
echo
“Alex”|
awk
'{print length($0)}'
提取字符串
${varible##*string} 从左向右截取最后一个string后的字符串
${varible#*string} 从左向右截取第一个string后的字符串
${varible%%string*} 从右向左截取最后一个string后的字符串
${varible%string*} 从右向左截取第一个string后的字符串
如:myname=hello.worlds
echo ${myname##*l} >>$ ds
${varible:n1:n2}
截取变量varible从n1到n2之间的字符串,可以根据特定字符偏移和长度,来选择特定子字符串
如: EXCLAIM=cowabunga
echo ${EXCLAIM:0:3} >>$ cow
数组【只支持一维数组】
定义数组:数组名=(元素1 元素2 ... 元素n)
指定数组对应下标的元素进行赋值:数组名[下标]=值
同时指定多个数组元素进行赋值:数组名=([下标1]=值1 [下标2]=值2 [下标n]=值n)
引用数组对应下标的元素:${数组名[下标]}
遍历数组元素
①使用for循环语句
②使用${a[*]}或者${a[@]}
获取数组长度
使用#来获取数组长度,注:在shell中越界访问数组不会报错
如:echo "a len: ${#a[*]}"
合并数组
如:a=(1 2 3) b=("hello" "world") c=(${a[*]} ${b[*]}) echo ${c[*]} >>$ 1 2 3 hello world
删除数组元素
unset 数组名[下标]:删除该数组的第几个元素
unset 数组名:删除整个数组
变量传参
$0 代表执行的文件名 $1 代表传入的第1个参数
$n 代表传入的第n个参数 $# 参数个数
$* 以一个单字符串显示所有向脚本传递的参数
$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数
$$ 脚本运行当前进程号
$! 后台运行的最后一个进程ID
#? 显示最后命令的退出状态,0代表没错误,其它值代表有错误
运算符
加法 expr $a + $b
减法 expr $a - $b
乘法 expr $a \* $b
除法 expr $b / $a
取余 expr $b % $a
赋值 a=$b
相等 [ $a == $b ]
不相等 [ $a != $b ]
注:条件表达式需要放在方括号之间,并且要留空格。使用expr进行计算时需要使用反引号。如:val=`expr $a + $b`
关系运算符
检测两个数是否相等 [ $a -eq $b ] -eq
检测两个数是否不相等 [ $a -ne $b ] -ne
检测左边的数是否大于右边的 [ $a -gt $b ] -gt
检测左边的数是否小于右边的 [ $a -lt $b ] -lt
检测左边的数是否大于等于右边的 [ $a -ge $b ] -ge
检测左边的数是否小于等于右边的 [ $a -le $b ] -le
注:关系运算符只支持数字,不支持字符串,除非字符串的值的数字。
布尔运算符
非运算 [ !false ]
或运算 [ $a -lt 20 -o $b -gt 100 ]
与运算 [ $a -lt 20 -a $b -gt 100 ]
逻辑运算符
逻辑的and [[
$a -lt 100 && $b -gt 100 ]]
逻辑的or [[
$a -lt 100
||
$b -gt 100 ]]
布尔运算符和逻辑运算符的区别:
逻辑运算需要双括弧,布尔运算只需要单大括弧功能上,逻辑运算具有特殊的短路功能,即是在AND运算中第一个表达式为false时则不执行第二个表达式,在OR运算中第一个表达式为true时不执行第二个表达式。
例:[ ! -e /var/log/cbs_log_bak ] && mkdir /var/log/cbs_log_bak //如果目录不存在则新建
字符串运算符
检测两个字符串是否相等 [ $a = $b ]
检测两个字符串是否不相等 [ $a != $b ]
检测字符串长度是否为0 [ -z $a ]
检测字符串长度是否不为 0 [ -n “$a” ]
检测字符串是否为空 [ $a ]
文件测试运算符
检测文件是否是块设备文件 [ -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
运算指令
(()):
使用双圆括弧计算其中的内容,如((var=a+b)),该指令经常在if/while等条件判断中需要计算时使用。
let:计算表达式时使用,如:let var=a+b
expr:常用的计算指令,使用时需在外部加反引号,如:var=`expr a+b`
bc:bc计算器支持shell中的小数进行计算,如:
基本使用方式为
var=$(echo "(1.1+2.1)"|bc)
;
$[]:可以直接使用此方法计算中括弧的内容,如echo $[1+2]
分支控制
① if...else...fi
-
每一个if语句都有一个fi作为结束标记;
-
分支结构中使用then作为起始语句;
-
当且仅当if后面的语句执行为真时,才会执行then后面的语句。
如:if condition
then
command1
else
command2
fi
② if...elseif...fi
③ case...in...esac【多选择语句】
语法格式:case 值 in
模式1)
command1
command2
;; //该模式结束标记
*)
command1
esac
如:
#!/bin/bash
read VAR # 从键盘输入一个数字
case $VAR in # 判断用户输入的值$VAR
1) echo "one" #如果$VAR的值是1,就显示one
;;
2) echo "two" #如果$VAR的值是2,就显示two
;;
*) echo "unknown" # 星号*是shell中的通配符,代表任意字符
esac
④select...in... 【
select in是shell中独有的一种循环,非常适合终端的交互场景,它可以显示出带编号的菜单,用户出入不同编号就可以选择不同的菜单,并执行不同的功能】
语法格式:select var in seq
do
action
done
如:#!/bin/bash
echo "What is your favourite OS?"
select var in "Linux" "Gnu Hurd" "Free BSD" "Other"; do
break;
done
echo "You have selected $var"
循环控制
① while循环 while......do......
如:while condition
do
command
done
② until循环 until......do......
如:until condition
do
command
done
③ for循环【
for循环中,in后面接的是一个字符串,字符串里面包含几个单词循环体就执行几遍,每执行一遍a的值都轮换地等于字符串里边的各个单词】
如:for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
跳出循环
break/continue区别:break跳出整个循环,continue只跳出当前循环
函数
-
函数的定义中,括号里不能写任何东西
-
函数必须定义在调用之前
-
给函数传参时,在函数定义里用n来代表第n个参数,如果是n>10,必须用{n}表示
-
$?表示函数调用的返回值
Trap
当脚本收到某个信号时,需要处理一些清理工作,然后再退出。
如:
trap “” INT 【
当脚本收到信号SIGINT时,忽略该信号】
trap do_something INT QUIT HUP 【当脚本收到INT\QUIT\HUB信号时执行函数do_something】
Printf
printf format-string [arguments...] 【
format-string:为格式控制字符串
】
如:
printf
"%-10s %-8s %-4.2f
\n
"
郭靖 男
66.1234
%s %c %d %f 都是格式替代符,%s 输出一个字符串,%d 整型输出,%c 输出一个字符,%f 输出实数,以小数形式输出。
%-10s 指一个宽度为 10 个字符(- 表示左对齐,没有则表示右对齐),任何字符都会被显示在 10 个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
%-4.2f 指格式化为小数,其中 .2 指保留2位小数。
如:
printf "%d %s\n" 1 "abc" 【format-string为双引号】
printf '%d %s\n' 1 "abc" 【单引号与双引号效果一样】
printf %s abcdef 【没有引号也可以输出】
// 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用
printf %s abc def
printf "%s\n" abc def
printf "%s %s %s\n" a b c d e f g h i j
printf "%s and %d \n" 【如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替】
重定向
输入重定向:command1 < file
输出重定向:command1 > file
command > file 2> $1 【将标准输出文件和标准输入文件合并】
command1 > /dev/null
颜色显示
echo -e "\e[31;40m"
第一个数字(31)为前景颜色(红色);第二个数字为(40)背景颜色(黑色)
echo -e "
\e
[0m"
我们需要使用 "\e[0m" 序列将颜色重新设置为正常值。
\033
[30m -- \033[37m 设置前景色(字体颜色)
\033[30m 将字符的显示颜色改为黑色
\033[31m 将字符的显示颜色改为红色
\033[32m 将字符的显示颜色改为绿色
\033[33m 将字符的显示颜色改为淡红色
\033[
34
m
将字符的显示颜色改为蓝色
\033[35m 将字符的显示颜色改为紫色
\033[36m 将字符的显示颜色改为淡蓝色
\033[37m 将字符的显示颜色改为灰色
\033[40m -- \033[47m 设置背景色
\033[40m 将背景色设置为黑色
\033[41m 将背景色设置为红色
\033[42m 将背景色设置为绿色
\033[43m 将背景色设置为淡红色
\033[44m 将背景色设置为蓝色
\033[45m 将背景色设置为紫色
\033[46m 将背景色设置为淡蓝色
\033[47m 将背景色设置为灰色
预定义变量:$1 $2 【执行脚本命令时输入文件名后,如:./test.sh lichaun 123qwerty】
df / -h | awk '/\//{print $4}' 【提取根分区剩余空间】
free -m | awk '/Mem/{print $4}' 【提取内存剩余空间】
RANDOM:随机数
stty -echo:关闭回显
stty echo:开启回显
seq:用于输出区间内的所有整数
sort【对文本进行排序】
sort -n:按数字排序
sort -r:倒叙排序
sort -t -k:按指定字段排序 【
sort -t : -k 3 表示以:作为字段分隔符,按照第三个字段排序】
uniq 【对连续重复行进行操作
】常与sort合用
uniq -c:打印每行出现的次数
uniq -q:只打印重复出现的行
uniq -D:打印所有重复行
uniq -i:忽略大小写
uniq -u:只打印出现一次的行
echo -n:不换行输出
tr【字符替换或删除】
tr -d:删除字符,如:
echo "Merry Christmas" | tr -d r 返回值:Mey Christmas
tr -s:压缩字符,如:
echo "aaabbbeeecccddd" | tr -s abcde 返回值:abecd
tr -c:替换字符,如:
echo "Merry Christmas" | tr -c a-z "#" 返回值:
#erry##hristmas#
tr a-z A-Z:替换小写为大写字母
例:tr "[a-z]" "[A-Z]" < filename 将该文件中的小写全改为大写
read【交互式命令】
read -a:用于数组
read -p:输入提示符
read -t:指定读取时等待的时间,单位秒
read -s:不显示输入的值,多用于输入密码【read -p "密码:" -s pass】
cut
cut -b:仅显示行中指定范围的内容
cut -c:仅显示行中指定范围的
字符
cut -d:指定分隔符,默认“TAB”制表符
cut -f:显示指定
字段的内容
cut -n:与-b连用,不分割多字节符
seq
seq -s:使用指定符号分割数字,不加-s默认换行输出【seq -s ' ' 1 2 10 输出1到10间等差为2的数字,中间加空格】
seq -w:在每一列数字前加0
awk 行处理器
awk -f:调用脚本
awk -F:指定分隔符
如:
awk -F":" '{print $1 $3}' /etc/passwd //$1与$3相连输出,不分隔
awk -F":" '{print $1,$3}' /etc/passwd //多了一个逗号,$1与$3使用空格分隔
awk -F":" '{print $1 " " $3}' /etc/passwd //$1与$3之间手动添加空格分隔
awk -F":" '{print "Username:" $1 "\t\t Uid:" $3 }' /etc/passwd //自定义输出
awk -F: '{print NF}' /etc/passwd //显示每行有多少字段
awk -F: '{print $NF}' /etc/passwd //将每行第NF个字段的值打印出来
awk -F: 'NF==4 {print }' /etc/passwd //显示只有4个字段的行
awk -F: 'NF>2{print $0}' /etc/passwd //显示每行字段数量大于2的行
awk '{print NR,$0}' /etc/passwd //输出每行的行号
awk -F: '{print NR,NF,$NF,"\t",$0}' /etc/passwd //依次打印行号,字段数,最后字段值,制表符,每行内容
awk -F: 'NR==5{print}' /etc/passwd //显示第5行
awk -F: 'NR==5 || NR==6{print}' /etc/passwd //显示第5行和第6行
route -n|awk 'NR!=1{print}' //不显示第一行