1.常见的内置命令
a echo ,
-e :解析转义字符
-n :不换行输出
rnd=$(rand $1 $2)
echo -ne "随机数是: \t$rnd"
echo -e "\t请拿好..."
exit 50
b exec :在不启动子进程的前题下运行命令,执行完后杀死当前进程。
实例:
[root@bogon test]# cat read.sh
#!/bin/bash
#Author:Anliu
#Blog: https://i.cnblogs.com/posts?cateId=1583983
#Time:2020-06-20 17:04:26
#Name:read.sh
#Version:V1.0
#Description:This is a test script.
exec < IP.txt
while read line
do
echo $line
done
echo OK
c read -p :读取用户输入的内容
d shift :移动位置参数
实例:企业垃圾桶参数偏移
[root@bogon test]# cat rm.sh
#!/bin/bash
#Author:Anliu
#Blog: https://i.cnblogs.com/posts?cateId=1583983
#Time:2020-06-20 17:27:37
#Name:rm.sh
#Version:V1.0
#Description:This is a test script.
[ -d /dev/mynull ] || mkdir /dev/mynull
shift
mv $1 /dev/mynull
e exit n (数字)
$?
2.字符串操作
定义:
[root@bogon test]#a=daahufsuufsdghfgdiha
[root@bogon test]#a=“cnsjv dsjf dshs”
[root@bogon test]#a=‘afnkjs$a##w*l’
查看:
[root@bogon test]# echo $a
[root@bogon test]# echo
a
a
f
h
k
j
s
f
j
s
d
f
j
d
s
k
f
a
s
l
i
{a} afhkjsfjsdfjdskfasli
aafhkjsfjsdfjdskfaslialkdahkjf
获取字符串长度:
[root@bogon test]# echo ${#a}
截取子串:
[root@bogon test]# echo ${a:4} #从第5个位置开始取子串
[root@bogon test]# echo ${a:4:1} #从第5个位置开始取1个字符
[root@bogon test]# echo ${a#wl} #从左向右最短匹配
[root@bogon test]# echo ${a##wl} #从左向右最长匹配
[root@bogon test]# echo ${a%lx} #从右往左最短匹配
[root@bogon test]# echo ${a%%lx} #从右往左最长匹配
[root@bogon test]# echo ${a/l*x/00000} #最大范围匹配到的字符替换
[root@bogon test]# echo ${a/l/0} #从左向右替换第一个匹配到的字符
[root@bogon test]# echo ${a//l/0} #从从往右替换所有匹配到的字符
补充:
sed 【参数】‘petter command1;command2’
[root@bogon ~]# sed -n ‘s/linux/LINUX/g;p’ a
p: sed 的打印命令,打印所有行
[root@bogon ~]# sed -n ‘s/linux/LINUX/gp’ a
p: sed的替换命令的label,打印匹配到的行
知识1:如何修改shell中的for循环以空格分割为换行
知识2:如何用shell字符串的取子串操作处理文本
[root@bogon test]# echo ${a}
[root@bogon test]# echo ${a#l}
ike linux
[root@bogon test]# echo ${a##l}
inux
[root@bogon test]# echo ${a%%l}
we
[root@bogon test]# echo ${a%l}
we like
[root@bogon test]# cat file3.sh
#!/bin/bash
#Author:Anliu
#Blog: https://i.cnblogs.com/posts?cateId=1583983
#Time:2020-06-23 15:44:39
#Name:file3.sh
#Version:V1.0
#Description:This is a test script.
#“如何修改shell中的for循环,使其不以空格分割。而是以换行”
#IFS:
IFS_old=
I
F
S
I
F
S
=
IFS IFS=
IFSIFS=’\n’
for i in ip a |grep -E '\<inet\>'
#for 循环默认以空格分割,—""
do
#echo $IFS
#echo
i
j
=
i j=
ij={i#t}
echo ${j%%/}
#echo KaTeX parse error: Expected '}', got 'EOF' at end of input: …%s*o} done IFS=IFS_old
字符串的特殊变量扩展
echo ${parameter:-word} :如果parameter为空,则输出word,parameter本身没有发生变化;如果不为空输出parameter的值。
echo ${parameter:=word} :如果parameter为空,则输出word,parameter已经赋予word的值;如果不为空输出parameter的值。
echo ${parameter:?word} :如果parameter为空,则输出word,此时word将是错误输出的提示,echo $? 返回值为1;如果不为空输出 parameter的值。
echo ${parameter:+word} :如果parameter为空,则输出空,如果不为空输出word,parameter本身没有发生变化。
[root@bogon test]# a=linux
[root@bogon test]# echo ${a}
linux
[root@bogon test]# echo ${a:-mysql}
linux
[root@bogon test]# unset a
[root@bogon test]# echo ${a}
[root@bogon test]# echo ${a:-mysql}
mysql
[root@bogon test]# unset a
[root@bogon test]# echo ${a}
[root@bogon test]# echo ${a:-mysql}
mysql
[root@bogon test]# echo ${a}
[root@bogon test]#
[root@bogon test]# echo ${a:=mysql}
mysql
[root@bogon test]# echo ${a}
mysql
[root@bogon test]# unset
[root@bogon test]# unset a
[root@bogon test]# echo ${a}
[root@bogon test]# echo ${a:?mysql}
-bash: a: mysql
[root@bogon test]# echo $?
1
[root@bogon test]# lll
-bash: lll: 未找到命令
[root@bogon test]# echo ${a:?“参数未定义”}
-bash: a: 参数未定义
[root@bogon test]# a=123
[root@bogon test]# echo ${a:?“参数未定义”}
123
[root@bogon test]# echo ${a}
123
[root@bogon test]#
[root@bogon test]#
[root@bogon test]# unset a
[root@bogon test]#
[root@bogon test]# echo ${a}
[root@bogon test]#
[root@bogon test]# echo ${a:+mysql}
[root@bogon test]# a=linux
[root@bogon test]# echo ${a}
linux
[root@bogon test]# echo ${a:+mysql}
mysql
[root@bogon test]# echo ${a}
linux
实例:Shell实现程序日志文件分割
日志文件过大:(1)资源浪费
(2)读写不方便,甚至后导致日志的输入延时而导致程序故障。
滚动切分:要求:(1)日志文件以当前日期命名:每小时生成一个新文件(以小时命名,并在存放在以天命令的文件夹中)
(2)每天凌晨时将前一天的日志文件归档压缩。20200623—> 00:00 20200623.tar.gz
(3)保留7天之内的日志,7天之外的删除。 20200623.tar.gz,20200624.tar.gz,20200625.tar.gz,20200626.tar.gz,
20200627.tar.gz, 20200628.tar.gz, 20200629.tar.gz, 20200630.tar.gz.
补充:定时计划任务坑:
坑1:[root@server02 ~]# vim /var/spool/cron/root 这样做,权限不对,正确的方法是crontab -e;.vimrc.bak;
-rw------- 1 root root 9 6月 23 18:35 root
坑2:计划任务在执行时,是在自己的家目录下执行的,所以脚本中一定要写绝对路径。
[root@bogon test]# crontab -e
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0 */1 * * * . /etc/profile;/root/test/ping_log.sh
0 0 */1 * * . /etc/profile;/root/test/ping_log1.sh
#!/bin/bash
#Author:Anliu
#Blog: https://i.cnblogs.com/posts?cateId=1583983
#Time:2020-06-23 17:51:43
#Name:ping_log.sh
#Version:V1.0
#Description:This is a test script.
DirName=date "+%Y%m%d"
FileName=date "+%H"
[ -d /root/test/
D
i
r
N
a
m
e
]
∣
∣
m
k
d
i
r
/
r
o
o
t
/
t
e
s
t
/
DirName ] || mkdir /root/test/
DirName]∣∣mkdir/root/test/DirName
mv /root/test/ping.log /root/test/
D
i
r
N
a
m
e
/
DirName/
DirName/FileName.log
[root@bogon test]# cat ping_log1.sh
#!/bin/bash
#Author:Anliu
#Blog: https://i.cnblogs.com/posts?cateId=1583983
#Time:2020-06-23 17:51:43
#Name:ping_log.sh
#Version:V1.0
#Description:This is a test script.
DataPath=/root/test
#DataPath=
SourceFile=date -d "-1 day" "+%Y%m%d"
#tar -czf
D
a
t
a
P
a
t
h
/
DataPath/
DataPath/SourceFile.tar.gz
D
a
t
a
P
a
t
h
/
DataPath/
DataPath/SourceFile &>/dev/null
#rm -rf
D
a
t
a
P
a
t
h
/
DataPath/
DataPath/SourceFile
#find $DataPath -mtime -7 exec rm -rf {} ;
find ${DataPath:-/tmp/} -mtime +3 -exec rm -rf {} ;
3.shell中的数值计算
命令:
a (()) :既能做数值运算,又能做数值比较
[root@bogon test]# a=$((1+1))
[root@bogon test]# echo a
a
[root@bogon test]# echo $a
2
if ((1>2))
then
echo “ok”
else
echo “not ok”
fi
b let :数值运算
[root@bogon test]# let a=1+2
[root@bogon test]# echo $a
3
c expr :数值运算(判断是否为数字),字符串对比(判断两字符串是否一致),求字串长度
[root@bogon test]# expr 1 + 2
3
[root@bogon test]# expr 1 * 2
2
[root@bogon test]# expr 1 / 2
0
[root@bogon test]# expr 1 % 2
1
字符串匹配。匹配的字符串以“:”相隔,匹配则为真,反之,为假。
[root@bogon test]# expr “123” : “124” &>/dev/null
[root@bogon test]# echo $?
1
[root@bogon test]# expr “123” : “123” &>/dev/null
[root@bogon test]# echo $?
0
[root@bogon test]# a=“mamahuhu”
[root@bogon test]# echo ${a}
mamahuhu
方法一:(最高)
[root@bogon test]# echo ${#a}
8
方案二:(和一相当)
[root@bogon test]# expr length $a
8
方法四:(较好)
[root@bogon test]# echo ${a} |awk ‘{print length($0)}’
8
方法三:(最差)
[root@bogon test]# echo ${a} |wc -L
8
[root@bogon test]# expr 1 + q &>/dev/null
[root@bogon test]# echo $?
2
[root@bogon test]# expr 1 + 1 &>/dev/null
[root@bogon test]# echo $?
0
[root@bogon test]# cat Calculator.sh
#!/bin/bash
#Author:Anliu
#Blog: https://i.cnblogs.com/posts?cateId=1583983
#Time:2020-06-29 01:05:12
#Name:Calculator.sh
#Version:V1.0
#Description:This is a test script.
read -p “num1>>” num1
read -p “num2>>” num2
if expr 1 + $num1 &>/dev/null
&& expr 1 + $num2 &>/dev/null
then
echo “
(
(
((
((num1+
n
u
m
2
)
)
"
e
c
h
o
"
num2))" echo "
num2))"echo"((
n
u
m
1
−
num1-
num1−num2))”
echo “
(
(
((
((num1*
n
u
m
2
)
)
"
e
c
h
o
"
num2))" echo "
num2))"echo"((
n
u
m
1
/
num1/
num1/num2))”
else
echo “请输入数字…”
exit 1
fi
4.数组
定义数组
一次定义一个数组
array1[0]=pear
array1[1]=apple
array1[2]=orange
array1[3]=peach
一次定义多个数组
array2=(tom jack alice)
array3=(cat /etc/passwd
) 希望是将该文件中的每一个行作为一个元数赋值给数组array3
array4=(ls /var/ftp/Shell/for*
) # array5=(tom jack alice “bash shell”) #默认存储以空格分割元素,引号应用的将是一个元素
red=0001 # blue=0002 # green=0003 # yellow=“ni shi yellow” # colors=($red $blue $green $recolor $yellow)
#数组中可引用变量
array5=(1 2 3 4 5 6 7 “linux shell” [20]=puppet) #若没有指定索引,将从0开始依次排 序,若有索引,将元素存储到对应索引上。指定索引的优先级高。 #echo ${array5[20]} puppet
还可以单独定义数组的各个部分
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
获取数组长度
#取得数组元素的个数
length=${#array_name[@]}
取得数组单个元素的长度
lengthn=${#array_name[n]}
遍历数组
[root@localhost Scripts]# filename=(`ls`) [root@localhost Scripts]# for var in ${filename[@]};do echo $var;done
数组的删除
unset array[1] # 删除数组中第一个元素 unset array # 删除整个数组
查看数组:
declare -a
访问数组元数:
echo ${array1[0]} 访问数组中的第一个元数
echo ${array1[@]} 访问数组中所有元数 等同于 echo ${array1[*]}
echo ${#array1[@]} 统计数组元数的个数
获取数组元数的索引
查看索引:
echo ${!array2[@]}
echo ${array1[@]:1} 从数组下标1开始
echo ${array1[@]:1:2} 从数组下标1开始,访问两个元素