Linux运维之shell脚本

时间:2023-02-14 02:29:23

一、bash漏洞

1)bash漏洞

bash漏洞是控制Linux计算机命令提示符的软件中存在的漏洞。
bash是一个为GNU计划编写的Unix shell。它的名字是一系列缩写:Bourne-Again SHell ,Bourne shell是一个早期的重要shell,
由史蒂夫·伯恩在1978年前后编写,并同Version 7 Unix一起发布。
网络安全专家警告称,开源软件Linux中一个频繁使用的片段"Bash",发现存在安全漏洞,
其对计算机用户造成的威胁可能要超过2014年4月爆出的"心脏出血"(Heartbleed)漏洞

2)漏洞原理

Bash是用于控制Linux计算机命令提示符的软件。网络安全专家表示,黑客可以利用Bash中的一个安全漏洞,对目标计算机系统进行完全控制。
网络安全公司Trail of Bits的首席执行官丹·吉多(Dan Guido)指出:"与Heartbleed"相比,后者只允许黑客窥探计算机,
但不会让黑客获得计算机的控制权。"他说:"利用Bash漏洞的方法也简单得多,你可以直接剪切和粘贴一行软件代码,就能取得很好的效果。"
吉多还表示,他正考虑将自己公司非必要的服务器断网,以保护他们不会受到Bash漏洞的攻击,直到他能够修补这一漏洞为止。
网络安全公司Rapid7的工程经理托德·比尔兹利(Tod Beardsley)则警告称,Bash漏洞的严重程度被评为10级,意味着它具有最大的影响力,
而其利用的难度被评为"低"级,意味着黑客比较容易地利用其发动网络攻击。
比尔兹利称:"利用这个漏洞,攻击者可能会接管计算机的整个操作系统,得以访问机密信息,并对系统进行更改等等。
任何人的计算机系统,如果使用了Bash软件,都需要立即打上补丁。"

3)修复方式

A - centos系统
yum clean allyum makecacheyum -y update bash
如果是centos系统只要运行上面简单的脚本就可以。 B - Ubuntu系统
apt-get updateapt-get -y install --only-upgrade bash C - debian系统
如果是7.5 64位 && 32位环境运行
apt-get updateapt-get -y install --only-upgrade bash

4)漏洞测试

BASH爆出来一个远程代码执行的bash漏洞CVE-2014-6271。
BASH除了可以将shell变量导出为环境变量,还可以将shell函数导出为环境变量!当前版本的bash通过以函数名作为环境变量名,
以"(){"开头的字串作为环境变量的值来将函数定义导出为环境变量。
此次爆出的bash 漏洞在于BASH处理这样的"函数环境变量"的时候,并没有以函数结尾"}"为结束,而是一直执行其后的shell命令!例如
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
如果返回
vulnerable
this is a test
这样的结果的话,请尽快升级

二、用户登录的提示语

Last login: Wed Feb 28 12:10:06 2018 from 192.168.1.100
welcome to linux
this is test
[root@tomcat ~]#
[root@tomcat ~]# cat /etc/motd
welcome to linux
[root@tomcat ~]# cat /etc/profile.d/test.sh
echo "this is test"

三、常用变量的使用

1)常用变量的意思

shell特殊变量*****
1:位置变量
$0 获取当前执行的shell脚本的文件名,包括路径
$n 获取当前执行的shell脚本的第n个参数值,n=1..9,当n为0时表示脚本的文件名,如果n大于9,用大括号括起来${10}
$* 获取当前shell脚本的所有参数,将所有的命令行参数视为单个字符串,相当于"$1$2$3"...注意与$#的区别
$# 获取当前shell命令行中参数的总个数
$@ 这个程序的所有参数"$1" "$2" "$3" "...",这是将参数传递给其他程序的最佳方式,因为他会保留所有内嵌在每个参数里的任何空白
提示:$* 和$@的区别?
$* 将所有的命令行所有参数视为单个字符串,等同于"$1$2$3","$*"
$@ 将命令行每个参数视为单独的字符串,等同于"$1","$2","$3"。这个将参数传递给其他程序的最佳方式,因为他会保留所有内嵌在每个参数里的任何空白

  

if [ -f  file ]      如果文件存在
if [ -d ... ] 如果目录存在
if [ !-n ... ] 如果是空
if [ !-n ... ] || [ !-n ... ] 都要满足,只要其中一个为空,就要怎么的
if [ -s file ] 如果文件存在且非空
if [ -r file ] 如果文件存在且可读
if [ -w file ] 如果文件存在且可写
if [ -x file ] 如果文件存在且可执行
if [ int1 -eq int2 ] 如果int1等于int2
if [ int1 -ne int2 ] 如果不等于
if [ $# -ne 2 ] 如果不等于 2
if [ int1 -ge int2 ] 如果>=
if [ int1 -gt int2 ] 如果>
if [ int1 -le int2 ] 如果<=
if [ int1 -lt int2 ] 如果<

2)常用变量的使用

[root@oldboy66 day1]# cat q.sh
echo $1 $2 $3 $4 $5 $9 ${10} ${11}
echo $#
[root@oldboy66 day1]# sh q.sh {a..z}
a b c d e i j k
26
====》$# 接收参数的总算

简单的逻辑判断

[root@tomcat day2]# cat abc.sh
[ $# -ne 2 ] && #-ne是不等于
{
echo "must two"
exit 1
}
echo oldgirl
==》如果接收的参数不等于2,就输入"must two"
==》否则执行后面的内容
[root@tomcat day2]# sh abc.sh
must two
[root@tomcat day2]# sh abc.sh he
must two
[root@tomcat day2]# sh abc.sh he ab
oldgirl

exit 1 的意义

[root@tomcat day2]# sh abc.sh he ab
oldgirl
[root@tomcat day2]# echo $?
0
[root@tomcat day2]# sh abc.sh he
must two
[root@tomcat day2]# echo $?
1

四、pid的作用和$$的作用

  1)不完整版

  $$ 获取当前shell的进程号(PID)

[root@tomcat day2]# cat pid.sh
echo $$>/tmp/a.pid
sleep 300
[root@tomcat day2]# sh pid.sh &
[1] 57267
[root@tomcat day2]# cat /tmp/a.pid
57267
[root@tomcat day2]# ps -ef|grep pid.sh|grep -v grep
root 57267 57235 0 15:25 pts/0 00:00:00 sh pid.sh
[root@tomcat day2]# kill -USR2 `cat /tmp/a.pid`
[root@tomcat day2]# ps -ef|grep pid.sh|grep -v grep

 2)脚本完整版,意义。不会重复启动进程。启动前,先杀死原有进程

[root@tomcat day2]# cat pid.sh
#!/bin/sh
pidpath=/tmp/a.pid
if [ -f "$pidpath" ]
then
# kill -USR2 `cat $pidpath` # 这样会输出内容
kill -USR2 `cat $pidpath` >/dev/null 2>&1
rm -f $pidpath
fi
echo $$ >$pidpath
sleep 300
# 如果这个文件存在
# 就去这个文件杀死
# 并删除文件

五、批量改名

1)单个测试

[root@tomcat day2]# cat files.log  # 名字中删除所有的finished
stu_102999_1_finished.jpg
stu_102999_2_finished.jpg
stu_102999_3_finished.jpg
stu_102999_4_finished.jpg
stu_102999_5_finished.jpg
[root@tomcat day2]# cat files.log |tr "\n" " "
stu_102999_1_finished.jpg stu_102999_2_finished.jpg stu_102999_3_finished.jpg stu_102999_4_finished.jpg stu_102999_5_finished.jpg [root@tomcat day2]#
[root@tomcat day2]# touch `cat files.log |tr "\n" " "`
[root@tomcat day2]# ls
stu_102999_1_finished.jpg stu_102999_3_finished.jpg stu_102999_5_finished.jpg
stu_102999_2_finished.jpg stu_102999_4_finished.jpg
[root@tomcat day2]# f=stu_102999_1_finished.jpg
[root@tomcat day2]# echo $f
stu_102999_1_finished.jpg
[root@tomcat day2]# echo ${f%finish*.jpg}
stu_102999_1_
[root@tomcat day2]# mv $f `echo ${f%finish*.jpg}`.jpg
[root@tomcat day2]# ls stu_102999_1_.jpg
stu_102999_1_.jpg

2)for循环批量修改

[root@tomcat day2]# for f in `ls *fin*` ;do mv $f `echo ${f%finish*.jpg}`.jpg; done
[root@tomcat day2]# ls
stu_102999_1_.jpg stu_102999_3_.jpg stu_102999_5_.jpg
stu_102999_2_.jpg stu_102999_4_.jpg

3)批量改后缀名

[root@tomcat day2]# f=stu_102999_1_.jpg
[root@tomcat day2]# echo ${f/%jpg/htm}
stu_102999_1_.htm
[root@tomcat day2]# mv $f ${f/%jpg/htm}
[root@tomcat day2]# ls stu_102999_1_.htm
stu_102999_1_.htm
[root@tomcat day2]# for f in `ls *jpg`;do mv $f ${f/%jpg/htm};done
[root@tomcat day2]# ls *.htm
stu_102999_1_.htm stu_102999_2_.htm stu_102999_3_.htm stu_102999_4_.htm stu_102999_5_.htm

六、变量的数值计算

1)变量计算的方式,命令

  (())  let  expr  $[] 前面整数   bc最后小数

  对计算命令的时间,耗时对比

time for i in $(seq 11111);do count=${#chars};done;			  最快
time for i in $(seq 11111);do count=`echo ${chars}|wc -L`;done;   最慢
time for i in $(seq 11111);do count=`echo expr length "${chars}"`;done   其次  

2)各个运算符的意义

运算符				意义
++ -- 增加及减少,可前置也可放在结尾
+ - ! 一元的正号与负号;逻辑与位的取反
* / % 乘法、除法、与取余
+ - 加法、减法
< <= > >= 比较符号
== != 相等于不相等 一个"="是赋值
<< >> 向左位移 向右位移
& 位的AND
^ 位的异或
| 位的或
&& 逻辑的AND
|| 逻辑的OR
?: 条件表达式
= += -= *= /= &= 赋值运算符 a+=1 都相当于a=a+1
^= <<= >>= |=

运算例子

[root@oldboy66 ~]# ((a=1+2**3-4%3))			==》1+8-1
[root@oldboy66 ~]# echo $a
8
[root@oldboy66 ~]# b=$((a=1+2**3-4%3))
[root@oldboy66 ~]# echo $b
8
[root@oldboy66 ~]# echo $((a=1+2**3-4%3))
8
[root@oldboy66 ~]# echo $a
8
[root@oldboy66 ~]# echo $((a+=1))
9
[root@oldboy66 ~]# echo $a
9
[root@oldboy66 ~]# echo $((a++))
9
[root@oldboy66 ~]# echo $a
10
[root@oldboy66 ~]# echo $((++a))
11

小结

  对++,--。变量在前,先输出原来的值,在输出计算表达后的值;变量在后。就是先运算输出表达式后的值,后又输出计算之后的值

3)比较大小和取余

比较大小,不成立是0,成立是1
[root@oldboy66 ~]# echo $((3>2))
1
[root@oldboy66 ~]# echo $((3<2))
0
[root@oldboy66 ~]# echo $((3=2))
-bash: 3=2: attempted assignment to non-variable (error token is "=2")
[root@oldboy66 ~]# echo $((3==2))
0
[root@oldboy66 ~]# echo $((100*(100+1)/2))
5050
下面是取余
[root@oldboy66 ~]# echo $((100%5))
0
[root@oldboy66 ~]# echo $((100%3))
1

4)简单四则运算

案例一:固定值执行

[root@oldboy66 day1]# cat jisuan.sh
#!/bin/bash
a=6
b=2
echo "a-b =$(($a - $b))"
echo "a+b =$(($a + $b))"
echo "a*b =$(($a * $b))"
echo "a/b =$(($a / $b))"
echo "a**b =$(($a ** $b))"
echo "a%b =$(($a % $b))"
[root@oldboy66 day1]# sh jisuan.sh
a-b =4
a+b =8
a*b =12
a/b =3
a**b =36
a%b =0

案例二,传参方式执行

[root@oldboy66 day1]# cat jisuan2.sh
#!/bin/bash
a=$1
b=$2
echo "a-b =$(($a - $b))"
echo "a+b =$(($a + $b))"
echo "a*b =$(($a * $b))"
echo "a/b =$(($a / $b))"
echo "a**b =$(($a ** $b))"
echo "a%b =$(($a % $b))"
[root@oldboy66 day1]# sh jisuan2.sh 6 4
a-b =2
a+b =10
a*b =24
a/b =1
a**b =1296
a%b =2

案例三、实现一个简单的四则计算器,通过命令行参数的方式实现脚本的功能

[root@oldboy66 day1]# cat jisuan3.sh
echo $(($1$2$3))
[root@oldboy66 day1]# sh jisuan3.sh 3+4 由于挨在一起,相当于只接收了一个参数,只传给了$1
7

[root@oldboy66 day1]# cat jisuan4.sh
echo $(($1))
[root@oldboy66 day1]# sh jisuan4.sh 7+3
10

5)let 命令的用法

格式:let赋值表达式
注:let赋值表达式功能等同于:((赋值表达式))
给自变量i+8,例如
[root@oldboy66 ~]# i=2
[root@oldboy66 ~]# let i=i+8
[root@oldboy66 ~]# echo $i
10
[root@oldboy66 ~]# i=2
[root@oldboy66 ~]# i=i+8 <==去掉let定义
[root@oldboy66 ~]# echo $i
i+8

七、expr命令的用法

1)expr 命令的计算

expr命令一般用于整数值,但也可用于字符串,用来求表达式变量的值同时expr是一个手工命令行计算器
语法:expr Expression
[root@oldboy66 ~]# expr 2 + 2
4
[root@oldboy66 ~]# expr 2+2
2+2
[root@oldboy66 ~]# expr 2 \* 2 乘法 *需要转义
4
[root@oldboy66 ~]# expr 2 / 2
1
[root@oldboy66 ~]# expr 5 % 2
1

注意:

1:运算符及计算的数字左右都有至少一个空格
        2:使用乘号时,必须用反斜线屏蔽器特定含义。因为shell可能会误解星号的含义
   增量计数:
       expr在循环中可用于增量计算。首先,循环初始化为0,然后循环值加1,反引号的用法为命令替代。最基本的一种是从(expr)命令接受输出并将值放入循环变量

[root@oldboy66 ~]# i=0
[root@oldboy66 ~]# i=`expr $i + 1`
[root@oldboy66 ~]# echo $i
1
[root@oldboy66 ~]# b=`expr $i + 1`
[root@oldboy66 ~]# echo $b
2
[root@oldboy66 ~]# expr $[2+3]
5
[root@oldboy66 ~]# expr $[ 2 + 3 ]
5
[root@oldboy66 ~]# echo $[2+3]
5

2)expr的特殊用法

案例一:判断是否是整数

[root@tomcat day3]# cat expr2.sh
#!/bin/sh
# 判断是否是整数
expr 1 + $1 &>/dev/null
if
[ $? -eq 0 ]
then
echo "整数"
else
echo "非整数"
fi
[root@tomcat day3]# sh expr2.sh 2
整数
[root@tomcat day3]# sh expr2.sh 2.5
非整数

案例二:判断文件后缀名

[root@oldboy66 day1]# cat expr.sh
#!/bin/sh
# 判断后缀名
if
expr "$1" : ".*\.pub" &>/dev/null
then
echo "you are using $1"
else
echo "pls use *.pub file"
fi
[root@oldboy66 day1]# sh expr.sh n.sh
pls use *.pub file
[root@oldboy66 day1]# sh expr.sh oldboy.pub
you are using oldboy.pub

案例三:read和expr结合判断整数和浮点数

[root@tomcat day3]# cat expr3.sh
#!/bin/sh
while true
do
read -p "Pls input:" a
expr $a + 0 >/dev/null 2>&1
[ $? -eq 0 ] && echo int||echo chars
done
[root@tomcat day3]# sh expr3.sh
Pls input:3
int
Pls input:3.5
chars
Pls input:quit
chars
Pls input:^C
[root@tomcat day3]#

八、read 用法

1)read基本用法

-p prompt	设置提示信息
-t timeout 设置输入等待的时间,单位默认为秒
[root@oldboy66 day1]# read -t 5 -p "pls input:" a 如果5秒钟不输出内容,则退出。pls input,是输出的提示符,a是变量,输出的内容赋值给a
pls input:1
[root@oldboy66 day1]# echo $a
1
[root@oldboy66 day1]# read -t 5 -p "pls input:" a b
pls input:1 3
[root@oldboy66 day1]# echo $a
1
[root@oldboy66 day1]# echo $b
3

2)read 实现4则运算脚本

[root@tomcat day3]# cat read2.sh
#!/bin/sh
read -t 10 -p "pls input:" a b
echo "a-b=$(( $a - $b ))"
echo "a+b=$(( $a + $b ))"
echo "a*b=$(( $a * $b ))"
echo "a/b=$(( $a / $b ))"
echo "a**b=$(( $a ** $b ))"
echo "a%b=$(( $a % $b ))"
[root@tomcat day3]# sh read2.sh
pls input:24 4
a-b=20
a+b=28
a*b=96
a/b=6
a**b=331776
a%b=0

3)read 实现4则运算脚本,改良版

[root@tomcat day3]# cat read.sh
#!/bin/sh
echo "This is a calulation script,welcome to use"
read -p "pls input:" a b
expr $a + $b >/dev/null
if [ $? -eq ]
then
echo "a-b=$(( $a - $b ))"
echo "a+b=$(( $a + $b ))"
echo "a*b=$(( $a * $b ))"
echo "a/b=$(( $a / $b ))"
echo "a**b=$(( $a ** $b ))"
echo "a%b=$(( $a % $b ))"
else
echo "You can only enter two value and they are integer."
echo "please int two"
exit
fi
[root@tomcat day3]# sh read.sh
This is a calulation script,welcome to use
pls input:
a-b=
a+b=
a*b=
a/b=
a**b=
a%b=

4)实现2个整数比较大小,read以交互式的方式实现

#!/bin/sh
# [ -z STRING ] “STRING” 的长度为零则为真。
read -p "Pls input two num:" a b
# 首先确定输入的是2个数
# 如果 a 或者 b 任意一个长度为0 ,都执行请再次输入,并退出
[ -z "$a" ] || [ -z "$b" ] && {
echo "Pla input two num again"
exit
}
# 在确定是不是输入的2个整数
expr $a + &>/dev/null
RETVAL1=$?
expr $b + &>/dev/null
RETVAL2=$?
test $RETVAL1 -eq -a $RETVAL2 -eq ||{
echo "Pla input two intnum again"
exit
}
[ $a -lt $b ] && {
echo "$a < $b"
exit
}
[ $a -eq $b ] && {
echo "$a = $b"
exit
}
[ $a -gt $b ] && {
echo "$a > $b"
exit
}

5)命令行直接输入比较大小

#!/bin/sh
a=$
b=$
[ $# -ne ] && {
echo "USAGE:$0 NUM1 NUM2"
exit
} expr $a + &>/dev/null
RETVAL1=$?
expr $b + &>/dev/null
RETVAL2=$? test $RETVAL1 -eq -a $RETVAL2 -eq ||{
echo "Pla input two intnum again"
exit
}
[ $a -lt $b ] && {
echo "$a < $b"
exit
}
[ $a -eq $b ] && {
echo "$a = $b"
exit
}
[ $a -gt $b ] && {
echo "$a > $b"
exit
}

6)read 实现简单的菜单功能

[root@tomcat day3]# cat menu.py
menu(){
cat <<END
1.[install lamp]
2.[install lnmp]
3.[exit]
pls input the num you want;
END
read -t 15 a
}
menu [ $a -eq 1 ]&&{
echo "installing lamp"
sleep 3
echo "lamp is installed"
exit
} [ $a -eq 2 ]&&{
echo "installing lnmp"
sleep 3
echo "lnmp is installed"
exit
}
[ $a -eq 3 ]&&{
exit
} [ ! $a -eq 1 -o ! $a -eq 2 -o ! $a -eq 3 ] &&{
echo "Please enter your correct choice"
exit 1
} 

九、bc的用法

1)直接输入bc,进入bc计算器

[root@oldboy66 day1]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
100*3
300
quit

2)输出值给bc进行运算

[root@oldboy66 day1]# echo 1+2|bc
3
[root@oldboy66 day1]# echo 1+2.4|bc
3.4
[root@oldboy66 day1]# echo 5.23*3.13|bc
16.36
[root@oldboy66 day1]# echo "scale=6;5.23*3.13"|bc scale是保留小数点几位
16.3699
[root@oldboy66 day1]# echo 5.23*3.13|bc -l
16.3699
[root@oldboy66 day1]# echo "scale=5;5.23/3.13"|bc
1.67092
[root@oldboy66 day1]# echo 5.23/3.13|bc -l
1.67092651757188498402
[root@oldboy66 day1]# echo "obase=2;255"|bc 后面的10进制转换成前面的2进制
11111111

3)算式拼接:输出内容如1+2+3+4+5+6+7+8+9+10=55

[root@oldboy66 day1]# echo `seq -s '+' 10`=`seq -s "+" 10|bc`
1+2+3+4+5+6+7+8+9+10=55
[root@tomcat day3]# echo "`seq -s '+' 10`="$((`seq -s "+" 10`))
1+2+3+4+5+6+7+8+9+10=55
[root@tomcat day3]# echo `seq -s '+' 10`=`seq -s " + " 10|xargs expr`
1+2+3+4+5+6+7+8+9+10=55
[root@tomcat day3]# echo `seq -s " + " 10`|xargs expr
55 [root@oldboy66 day1]# seq -s " + " 10
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10
[root@oldboy66 day1]# echo {1..10}|tr " " "+"
1+2+3+4+5+6+7+8+9+10
[root@oldboy66 day1]# echo {1..10}|tr " " "+"|bc
55

九、typeset命令的用法:使用整数变量之间进行计算

[root@tomcat day3]# typeset -i a= b=
[root@tomcat day3]# a=a+b
[root@tomcat day3]# echo $a [root@tomcat day3]# typeset -i a= b=
[root@tomcat day3]# c=a+b
[root@tomcat day3]# echo $c
a+b
[root@tomcat day3]# b=a+b
[root@tomcat day3]# echo $b