linux-Shell 脚本

        

1. Shell概述

Shell是一个命令解释器,它接收应用程序/用户命令,然后调用操作系统内核。

Shell是一个功能强大的编程语言,易编写、易调试、灵活性强。

  1. Linux提供的Shelll解析器有

cat /etc/shells

  1. bash和sh的关系

cd /bin
ll | grep bash

[root@lys bin]# echo $SHELL
/bin/bash

2. Shell 脚本入门

(1) 脚本格式

脚本以#!/bin/bash开头 (指定解析器)

(2)第一个Shell脚本 helloworld.sh

touch helloworld.sh
vim helloworld.sh

# 内容
# !/bin/bash
echo "hellow world"

(3) 脚本的常用执行方式

  1. bash或sh + 脚本的相对路径或绝对路径 (不用赋予脚本+x权限)(重新开了一个进程执行bash命令)

sh ./helloworld.sh
bash ./helloworld.sh

  1. 采用输入脚本的绝对路径或相对路径执行脚本(必须具有可执行权限+x)(本质是使用当前的bash进程执行命令)

./helloworld.sh
  1. 【了解】在脚本的路径前加“.”或者source

source helloworld.sh 
. helloworld.sh

原因:

前两种方式都是在当前shell找那个打开一个子shell来执行脚本内容,当脚本内容结束,则子shell关系,回到父shell中。

第三种,也就是使用在脚本路径前加”." 或者source的方式,可以使脚本内容在当前shell里执行,而无需打开子shell。这就是为什么我们每次要修改完/etc/profile文件以后,需要source一下的原因。

开子shell与不开子shell的却别就在于,环境变量的集成关系,如在子shell中设置的当前变量,父shell是不可见的。

子Shell

[root@lys shell]# ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
root      1907 10679  0 12:46 pts/1    00:00:00 ps -f
root     10679 10672  0 09:47 pts/1    00:00:00 -bash
[root@lys shell]# bash
[root@lys shell]# ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
root      1970 10679  0 12:46 pts/1    00:00:00 bash
root      2006  1970  0 12:46 pts/1    00:00:00 ps -f
root     10679 10672  0 09:47 pts/1    00:00:00 -bash
[root@lys shell]# exit
exit
[root@lys shell]# ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
root      2034 10679  0 12:46 pts/1    00:00:00 ps -f
root     10679 10672  0 09:47 pts/1    00:00:00 -bash

3. 变量

3.1 系统预定义变量

常用系统变量

PWD、

USER

(1)查看系统变量的值

echo $HOME

(2)显示当前Shell中所有变量:

env
set # 包含所有系统自定义和用户自定义的变量 
printenv $USER
printenv USER

3.2 自定义变量

(1)基本语法

  1. 定义变量:变量名=变量,注意,= 前后不能有空格
  2. 撤销变量:usset变量名
  3. 声明静态变量:readonly变量,注意:不能unset

(2)变量定义规则

  1. 变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写。
  2. 等号两侧不能有空格
  3. 在bash中,变量默认类型都是字符串类型,无法进行数值运算。
  4. 变量的值如果有空格,需要使用双引号或单引号括起来。

[root@lys shell]# a=2
[root@lys shell]# echo $a
2
# 提升为全部变量
[root@lys shell]# export a

new_var='hello linux'
vim helloworld.sh
# 追加
echo $new_var

sh helloworld.sh
#发现没有值
# 使用一下命令就有值
. hellworld.sh
sourcce hellowrld.sh

计算

a=$((1+5))
a=$[1+5]

定义只读变量

readonly=5f

撤销变量

unset a

3.3 特殊变量

3.3.1 $n

$n n为数字,¥0代表该脚本名称,$1-

{10}

vim helloworld.sh
echo "hello,$1"
# 执行
sh helloworld.sh a
# 输出
hello,a

示例2

#!/bin/bash
echo '======$n====='
echo script name: $0
echo 1st paramater: $1
echo 2nd paramater: $2

[root@lys shell]#  sh parameter.sh 0 1 2
======$n=====
script name: parameter.sh
1st paramater: 0
2nd paramater: 1

# 获取调用文件名称
basename

3.3.2 $#

$# 获取所有输入参数个数,常用于循环,判断参数的个数是否正确以及加强脚本的健壮性

vim parameter.sh 
#!/bin/bash
echo '======$n====='
echo script name: $0
echo 1st paramater: $1
echo 2nd paramater: $2
echo '======$#====='
echo paramter numbers: $#


sh parameter.sh ab cd
# 结果
======$n=====
script name: parameter.sh
1st paramater: ab
2nd paramater: cd
======$#=====
paramter numbers: 2

3.3.3

@

*把所有的参数看成一个整体

@把每个参数区分对待

vim paramter.sh
#!/bin/bash
echo '======$n====='
echo script name: $0
echo 1st paramater: $1
echo 2nd paramater: $2
echo '======$#====='
echo paramter numbers: $#
echo $*
echo $@


[root@lys shell]# sh parameter.sh ab cd
======$n=====
script name: parameter.sh
1st paramater: ab
2nd paramater: cd
======$#=====
paramter numbers: 2
ab cd
ab cd

3.3.4 $?

$?  最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量非0(具体是哪个数,由命令自己来决定)则证明上一命令执行不正确了)

[root@lys shell]# ./helloworld.sh 
helloworld
hello,
[root@lys shell]# echo $?
0

# 如果错误执行,就非0
[root@lys shell]# $?
-bash: 0: command not found
[root@lys shell]# echo $?
127

4 运算符

$((运算式)) 或 $[运算式]

计算  (2+3)*4

[root@lys shell]# echo $[(2+3)*4]
20

expr使用

expr 1 + 2
3

# 乘法需转义
expr 5 \* 2
10

命令替换

[root@lys shell]# a=$(expr 2 + 2)
[root@lys shell]# echo $a
4


[root@lys shell]# a=`expr 5 + 2`
[root@lys shell]# echo $a
7

加法脚本

#!/bin/bash
sum=$[$1 + $2]
echo $sum

5 条件判断

基本语法

test condition

[ condition] (注意condition前后要有空格)

注意: 条件非空即为true, [lys] 返回true, [ ]返回false

常用判断条件

(1) 两个整数之间比较

-eq 等于(equal)

-ne 不等于 (not equal)

-lt 小于 (less than)

-le 小于等于 (less equal)

-gt 大于 (greate than)

-ge 大于等于 (greater equal)

注:如果是字符串之间的比较,用等号”=“判断相等;用”!=“判断不等。

(2)按照文件权限进行判断

-r 有读的权限(read)

-w 有写的权限 (write)

-x 有执行的权限 (execute)

# 判断文件是否有可执行权限
[root@lys shell]# [ -x helloworld.sh ]
[root@lys shell]# echo $?
0
# 结果0代表有

(3) 按照文件类型进行判断

-e 文件存在(existence)

-f 文件存在并且是一个常规的文件(file)

-d 文件存在并且是一个目录(directory)

案例实操

(1)23是否大于等于22

$ [ 23 -ge 22 ]

(2)判断文件是否有可执行权限

$ [ -x helloworld.sh ]

(3) 文件是否存在

$ [ -e helloworld.sh]

6 流程控制

6.1 if判断

(1)单分支

if [条件判断]; then
	程序
fi

或者

if [ 条件判断式 ]
then 
	程序
fi

if [ "$1"x = "lys"x ]
then
        echo 'welcome, lys'
fi

if [ $a -gt 18 -a $a -lt 35]; then echo OK; fi 
-a and
-o or

多分支

if [ 条件判断式 ]
then 
	程序

if [ $2 -lt 18 ]
then
        echo "未成年人"
elif [ $2 -lt 35 ]
then
        echo "中年人"
else
        echo "成年人"
fi

6.2 case语句

基本语法

case $变量名 in
"值1")
;;
"值2")
;;
*)
	如果变量的值都不是以上的值,则执行此程序
;;
esac

注意事项:

(1) case行尾必须为单词 "in", 每个模式匹配必须以有括号")" 结束

(2)双分号“;;"表示命令序列结束,相当于java的breakl

(3)最后的“*)"表示默认模式,相当于java中的default

case $1 in
1)
        echo "one"
;;
2)
        echo "two"
;;
3)
        echo "three"
;;
*)
        echo "number else"
;;
esac

sh case_test.sh 1

6.3 for 循环

基本语法

for ((初始值; 循环控制条件; 变量变化 ))
do 
	程序
done

#!/bin/bash

for (( i=1; i <= $1 ; i++  ))
do
        sum=$[ $sum + $i ]

done;

echo $sum

 for os in linux windows macos; do echo $os; done

for i in {1..100}; do sum=$[$sum+$i]; done; echo $sum

for 与

@

echo '$#'
for para in $*
do
        echo $para
done


echo '$@'
for para in $@
do
        echo $para
done


[root@lys shell]# sh for_test2.sh 1 2 3 
$#
1
2
3
$@
1
2
3

如果使用引号包围起来

echo '$#'
for para in "$*"
do
        echo $para
done


echo '$@'
for para in "$@"
do
        echo $para
done


[root@lys shell]# sh for_test2.sh 1 2 3 
$#
1 2 3
$@
1
2
3

6.4 while循环

while [ 条件判断式 ]
do 	
	程序
done

while循环实现 1+ 100

i=1
sum=0
while [ $i -le 100 ]
do
        sum=$[ $sum + $i ]
        i=$[$i + 1]
# 		let sum+=i
#		let i++ let 实现方式 
done;
echo $sum

7 read读取控制台输入

基本语法

read (选项) (参数)

-p:指定读取值时的提示符:

-t:指定读取值时等待的时间(秒)如果-t不加表示一直等待

参数:

变量:指定读取值的变量名

案例实操

提示7秒内,读取控制台输入的名称

read -t 10 -p "请输入您的名称:" name
echo "welcome $name"

8 函数

8.1 系统函数

8.1.1 basename

basename [string/pathname] [suffix] basename命令会删除所有的前缀包括最后一个(“/")字符,然后再字符串显示出来

basename 可以理解为取路径里的文件名称

选项:

suffix为后缀,如果suffix被指定了,basename会讲pathname或string中的suffix去掉。

filename="$1"_log_$(date +%s)
echo $filename

basename 基础用法

[root@lys shell]# basename helloworld.sh 
helloworld.sh

[root@lys shell]# basename helloworld.sh .sh
helloworld

8.1.2 dirname

dirname 文件绝对路径 从给定的包含绝对路径的文件名中取出文件名(非目录的部分),然后返回剩下的路径(目录的部分))

dirname 可以理解为取文件路径的绝对路径名称

获取hellowolrd.sh的目录名称

[root@lys shell]# dirname /java-project/shell/helloworld.sh 
/java-project/shell

8.2 自定义函数

[function] funname[()]

{

Action;

[return int;]

}

经验技巧

(1)必须在调用函数地方之前,先声明函数,shell脚本是逐行运行。不会像其他语言一样先编译。

(2)函数返回值,只能通过$?系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果作为返回值。return后跟述职n(0--255)

计算两数的和

function add(){
        s=$[$1+$2]
        echo "sum=$s"
}
read -p "请输入第一个整数" a
read -p "请输入第二个整数" b
add $a $b

使用#?最大只能返回255

function add(){
        s=$[$1+$2]
        return $s
}
read -p "请输入第一个整数" a
read -p "请输入第二个整数" b
add $a $b
echo "sum="$?

使用$()获取值

function add(){
        s=$[$1+$2]
        echo $s
}
read -p "请输入第一个整数" a
read -p "请输入第二个整数" b
sum=$(add $a $b)
echo "sum=$sum"

11 综合案例

11.1 归档文件

实际生产中,往往需要对重要数据进行归档备份。

需求:实现一个每天对指定目录归档备份的脚本,输入一个目录名称(末尾不带/),将目录下所有文件按天归档保存,并将归档日期附加在归档文件名上,放在/root/archive下。

这里使用到了归档命令:tar

后面可以加上-c表示归档。加上-z选项表示同时进行压缩,得到的文件后缀名为tar.gz

脚本实现:

 #!/bin/bash


#首先判断输入参数个数是否为1
if [ $# -ne 1 ]
then
        echo "参数个数错误!应该输入一个参数,作为归档目录"
        exit
fi

# 从参数中获取目录名称
if [ -d $1 ]
then
        echo 
else
        echo
        echo "目录不存在!"
        exit
fi

DIR_NAME=$(basename $1)
DIR_PATH=$(cd $(dirname $1); pwd)


# 获取当前日期
DATE=$(date +%y%m%d)
# 生成的归档文件名称
FILE=archive_${DIR_NAME}_$DATE.tar.gz
DEST=/root/archive/$FILE

# 开始归档
echo "开始归档..."
echo 

tar -zcf $DEST  $DIR_PATH/$DIR_NAME

if [ $? -eq 0 ]
then
        echo
        echo "归档成功"
        echo "归档文件为:$DEST"
else
        echo "归档出现问题"
        echo 
fi
exit

执行

 mkdir /root/archive
 sh tar.sh ../shell/

定时执行

crontab -e
0 2 * * * /java-project/shell/tar.sh /java-project/shell

9 正则表达式入门

正则表达式使用单个字符串来描述、匹配一系列符合某个语法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。在Linux中,grep,sed,awk等文本处理工具都支持通过正则表达式进行模式匹配。

9.1 常规匹配

一串不包含规则字符的正则表达式匹配它自己,例如:

cat /etc/passwd | grep lys

就会匹配所有包含lys的行

9.2 常用特殊字符

  1. 特殊字符: ^
    ^匹配一行的开头,例如:
cat /etc/passwd | grep ^a


会匹配出所有的a开头的行

  1. 特殊字符:$
    $ 匹配一行的结束,例如:
cat /etc/passwd | grep t$


查找空行

cat helloworld.sh | grep ^$

  1. 特殊字符:.
cat /etc/passwd | grep r..t


会匹配包含rabt,rbbt,rxdt,root等的所有行

  1. 特殊字符:*
    *不单独使用,他上一个字符连用,表示上一个字符0次或多次,例如
cat /etc/passwd | grep ro*t


会匹配rt,rot,root,roooor等
.*会匹配全部

  1. 字符区间(中括号):[]
    [] 表示匹配某个范围内的一个字符,例如
    [6,8]-------匹配6或者8,
    [0-9]------匹配一个0-9的数字
    [0-9]*-----匹配任意长度的数字字符串
    [a-z] --- 匹配一个a-z之间的字符串
    [a-z]* ------ 匹配任意长度的字母字符串
    [a-z,e-f]-- 匹配a-c,或者e-f之间的任意字符
cat /etc/passwd | grep r[a,b,c]*t


会匹配rt,rat,raat等等行
6 特殊字符:\
\标识转义,并不会单独使用。由于所有特殊字符都有其特定匹配模式,当我们想匹配某一特殊字符本身时(例如,我想找出所有包含’$'的行),就需要将转义符合特殊字符连用,来表示特殊字符本身,例如

cat /etc/passwd | grep 'a\$b'


就会匹配所有包含a$b的行。主要需要使用单引号将表达式引起来、

10 文本处理工具

10.1 cut

cut的工作就是“剪”,具体的说 就是在文件中负责剪切数据用的。cut命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。

基本用法

cut [选项参数] filename

说明:默认分隔符是制表符

选项参数

功能

-f

列号,提前第几列

-d

分隔符,按照指定分隔符分割列,默认是制表符“\t"

-c

按字符进行切割 后加加n 表示取第几列 比如 -c 1

数据准备

dong shen
guan zhen
wo wo
lai lai
le le

切割 cut.txt 第一列

cut -d " " -f 1 cut.sh

截取第二列

cut -d " " -f 2 cut.sh

截取区间

cut -d " " -f 1-4 cut.sh 
cut -d " " -f -4 cut.sh
cut -d " " -f 4- cut.sh

在cut切割guan

cat cut.sh | grep guan | cut -d " " -f 1

选取系统 PATH 变量值,第 2 个“:”开始后的所有路径:

echo $PATH 
/java-project/jdk1.8.0_321/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bi

echo $PATH | cut -d ":" -f 3-
/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

切割 ifconfig 后打印的 IP 地址

ifconfig ens33 | grep netmask | cut -d " " -f 10

10.2 awk

一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。

基本用法

awk [选项参数] '/pattern1/{action}'  '/patten2/{action2}' filename

pattern:表示awk在数据中查找的内容,就是匹配模式

action:在匹配内容时所执行的一系列命令

选项参数

功能

-F

指定输入文件分隔符

-v

赋值一个用户定义变量

案例实操

(1)数据准备

搜索passwd文件以root关键字开头的所有行,并输出该行的第7列

#cut 实现
 cat /etc/passwd | grep ^root | cut -d ";" -f 7
# awk实现
cat /etc/passwd | awk -F ":" '/^root/ {print $7}'
ps -ef | awk '{print $}'
# 打印文件大小
ll -l | awk '{print $5}'

搜索passwd文件以root关键字开头的所有行,并输出该行的第1列和第7列,中间以“,”号分割。

cat /etc/passwd | awk -F ":" '/^root/ {print $1","$7}'

(4)只显示/etc/passwd的第一列和第七列,以逗号分割,且在所有行前面添加列名"begin"在最后一行添加"end"

cat /etc/passwd | awk -F ":" 'BEGIN{print "begin"}{print $1","$7}END{print "end"}'

(5)将passwd文件中的用户id增加1并输出

cat /etc/passwd | awk -F ":" '{print $3+1}'
# 使用变量
cat /etc/passwd | awk -v i=1 -F ":" '{print $3+i}'

awk的内置变量

变量

说明

FILENAME

文件名

NR

已读的记录数(行号)

DF

浏览记录的域的个数(切割后,列的个数)

案例实操

(1)统计passwd文件名,每行的行号,每行的列数

cat /etc/passwd | awk  -F ":" '{print "文件名 :"FILENAME "行号:" NR "列数: "NF }'

(2) 查询ifconfig命令和输出结果中的空行所在的行号

  ifconfig | awk '/^$/ {print "空行: " NR}'

11 综合应用

我们可以利用 Linux 自带的 mesg 和 write 工具,向其它用户发送消息。

需求:实现一个向某个用户快速发送消息的脚本,输入用户名作为第一个参数,后面直 接跟要发送的消息。脚本需要检测用户是否登录在系统中、是否打开消息功能,以及当前发送消息是否为空。

前置知识

who 查看有多少控制台
[root@bogon logs]# who
root     pts/0        2022-05-26 17:34 (124.64.252.49)
root     pts/1        2022-05-27 10:12 (120.244.202.117)
root     pts/2        2022-05-27 11:37 (58.34.52.34)
root     pts/5        2022-05-27 10:16 (120.244.202.117)
root     pts/6        2022-05-27 19:10 (120.245.102.201)
root     pts/8        2022-05-25 10:18 (124.64.252.49)

# 向某个控制台发出消息
write root pts/1
hi

脚本实现如下:

#!/bin/bash/

# 查看用户是否登录
login_user=$(who | grep -i -m 1 $1 | awk '{print $1}' )

if [ -z $login_user ]
then
	echo "$1 不在线!"
	echo "脚本退出"
	exit
fi


# 查看用户是否开启消息功能
is_allowed=$(who -T | grep -i -m 1 $1 | awk '{print $2}' )

if [ $is_allowed != "+" ]
then
	echo "$1 没有开启消息功能"
	echo "脚本退出..."
	exit
fi

# 确认是否有消息发送

if [ -z $2 ]
then
	echo "没有消息发送"
	echo "脚本退出"
	exit
fi


# 从参数中获取要发送的消息
whole_msg=$(echo $* | cut -d " " -f 2-)

# 获取用户登录的终端
user_terminal=$(who | grep -i -m 1 $1 | awk '{print $2}' )


# 写入要发送的消息
echo $whole_msg | write $login_user $user_terminal

if [ $? != 0 ]
then 
	echo "发送失败!"
else
	echo "发送成功!"
fi

exit

超级实用的shell脚本

1. 编写 helloworld 脚本

#!/bin/bash

echo "hello world"

2. 通过位置变量创建 Linux 系统账户及密码

#!/bin/bash
#$1 是执行脚本的第一个参数,$2 是执行脚本的第二个参数
useradd "$1"
echo "$2"  |  passwd  ‐‐stdin  "$1"

3. 每周 5 使用 tar 命令备份/var/log 下的所有日志文件

#vim  /root/logbak.sh
#编写备份脚本,备份后的文件名包含日期标签,防止后面的备份将前面的备份数据覆盖
#注意 date 命令需要使用反引号括起来,反引号在键盘<tab>键上面
tar    -czf    log-`date +%Y%m%d`.tar.gz    /var/log
# crontab ‐e                             #编写计划任务,执行备份脚本
00    03    *    *    5      /root/logbak.sh

4. 一键部署 LNMP(RPM 包版本)

#!/bin/bash
#使用 yum 安装部署 LNMP,需要提前配置好 yum 源,否则该脚本会失败
#本脚本使用于 centos7.2 或 RHEL7.2
yum ‐y install httpd
yum ‐y install mariadb mariadb‐devel mariadb‐server
yum ‐y install php  php‐mysql
systemctl start httpd mariadb
systemctl enable httpd mariadb

5. 实时监控本机内存和硬盘剩余空间,剩余内存小于 500M、根分区剩余空间小于 1000M

时,发送报警邮件给 root 管理员

#!/bin/bash
#提取根分区剩余空间
useradd    "$1"
3 / 38
#提取内存剩余空间
mem_size=$(free |awk '/Mem/{print $4}')
while :
do
#注意内存和磁盘提取的空间大小都是以 Kb 为单位
if  [  $disk_size  ‐le  512000  ‐a  $mem_size  ‐le  1024000  ];then
     mail  ‐s  Warning  root  <<EOF
Insufficient resources,资源不足
EOF
fi
done

6. 脚本生成一个 100 以内的随机数,提示用户猜数字,根据用户的输入,提示用户猜对了,

猜小了或猜大了,直至用户猜对脚本结束。

#!/bin/bash

#RANDOM 为系统自带的系统变量,值为 0‐32767 的随机数
#使用取余算法将随机数变为 1‐100 的随机数
num=$[RANDOM%100+1]
#使用 read 提示用户猜数字
#使用 if 判断用户猜数字的大小关系:‐eq(等于),‐ne(不等于),‐gt(大于),‐ge(大于等于),‐lt(小于),‐le(小
于等于)
while  :
do
      read ‐p  "计算机生成了一个 1‐100 的随机数,你猜: "  cai
      if   [  $cai  ‐eq   $num  ];then
             echo   "恭喜,猜对了"
             exit
      elif  [  $cai   ‐gt   $num  ];then
             echo   "Oops,猜大了"
      else
             echo   "Oops,猜小了"
      fi
done

7. 检测本机当前用户是否为超级管理员,如果是管理员,则使用 yum 安装 vsftpd,如果不

是,则提示您非管理员(使用字串对比版本)

#!/bin/bash
if  [  $USER  ==  "root"  ];then
         yum  ‐y  install   vsftpd
else
        echo "您不是管理员,没有权限安装软件"
fi

8. 检测本机当前用户是否为超级管理员,如果是管理员,则使用 yum 安装 vsftpd,如果不

是,则提示您非管理员(使用 UID 数字对比版本)

#!/bin/bash
if  [  $UID  ‐eq  0  ];then
         yum  ‐y  install   vsftpd
else
        echo "您不是管理员,没有权限安装软件"
fi

9. 编写脚本:提示用户输入用户名和密码,脚本自动创建相应的账户及配置密码。如果用户

不输入账户名,则提示必须输入账户名并退出脚本;如果用户不输入密码,则统一使用默

认的 123456 作为默认密码。

#!/bin/bash
read  ‐p  "请输入用户名: "   user
#使用‐z 可以判断一个变量是否为空,如果为空,提示用户必须输入账户名,并退出脚本,退出码为 2 #没有输入用户名脚本退出后,使用$?查看的返回码为 2
if  [   ‐z  $user  ];then
      echo "您不需输入账户名"
      exit 2
fi
#使用 stty ‐echo 关闭 shell 的回显功能
#使用 stty  echo 打开 shell 的回显功能
stty  ‐echo
read  ‐p  "请输入密码: "     pass
stty  echo
pass=${pass:‐123456}
useradd   "$user"
echo  "$pass"  |  passwd  ‐‐stdin   "$user"

10. 依次提示用户输入 3 个整数,脚本根据数字大小依次排序输出 3 个数字

#!/bin/bash
read ‐p "请输入一个整数:" num1
read ‐p "请输入一个整数:" num2
read ‐p "请输入一个整数:" num3
#不管谁大谁小,最后都打印 echo "$num1,$num2,$num3"
#num1 中永远存最小的值,num2 中永远存中间值,num3 永远存最大值
#如果输入的不是这样的顺序,则改变数的存储顺序,如:可以将 num1 和 num2 的值对调
tmp=0
#如果 num1 大于 num2,就把 num1 和和 num2 的值对调,确保 num1 变量中存的是最小值
if [ $num1 ‐gt $num2 ];then      
tmp=$num1
num1=$num2
num2=$tmp
fi
#如果 num1 大于 num3,就把 num1 和 num3 对调,确保 num1 变量中存的是最小值
if [ $num1 ‐gt $num3 ];then      
tmp=$num1
num1=$num3
num3=$tmp
fi
#如果 num2 大于 num3,就把 num2 和 num3 对标,确保 num2 变量中存的是小一点的值     
if [ $num2 ‐gt $num3 ];then   
tmp=$num2
num2=$num3
num3=$tmp
fi
echo "排序后数据为:$num1,$num2,$num3"

11. 编写脚本,实现人机<石头,剪刀,布>游戏

#!/bin/bash
game=(石头 剪刀 布)
num=$[RANDOM%3]
computer=${game[$num]}
#通过随机数获取计算机的出拳
#出拳的可能性保存在一个数组中,game[0],game[1],game[2]分别是 3 中不同的可能
echo "请根据下列提示选择您的出拳手势"
echo "1.石头"
echo "2.剪刀"
echo "3.布"
read  ‐p  "请选择 1‐3:"  person
case  $person  in
1)
if [ $num ‐eq 0 ];then
   echo "平局"
elif [ $num ‐eq 1 ];then
   echo "你赢"
else
   echo "计算机赢"
fi;;
2)   
if [ $num ‐eq 0 ];then
   echo "计算机赢"
elif [ $num ‐eq 1 ];then
   echo "平局"
else
   echo "你赢"
fi;;
3)
if [ $num ‐eq 0 ];then
   echo "你赢"
elif [ $num ‐eq 1 ];then
   echo "计算机赢"
else
   echo "平局"
fi;;
*)
echo "必须输入 1‐3 的数字"
esac

12. 编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,哪些主机处于关机

状态(for 版本)

#!/bin/bash
for  i  in   {1..254}
do
          ping ‐c2 ‐i0.3 ‐W1 192.168.4.$i  &>/dev/null
         if  [ $? –eq 0 ];then
               echo "192.168.4.$i is up"
         else
               echo  "192.168.4.$i is down"
         fi
done

13. 编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,哪些主机处于关机

状态(while 版本)

#!/bin/bash
i=1
while  [  $i  ‐le  254 ]
do
          ping ‐c2 ‐i0.3 ‐W1 192.168.4.$i  &>/dev/null
         if  [ $? –eq 0 ];then
               echo "192.168.4.$i is up"
         else
               echo  "192.168.4.$i is down"
         fi
         let i++
done

14. 编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,哪些主机处于关机

状态(多进程版)

#!/bin/bash

#定义一个函数,ping 某一台主机,并检测主机的存活状态
myping(){
ping ‐c2 ‐i0.3 ‐W1 $1  &>/dev/null
if  [ $? ‐eq 0 ];then
echo "$1 is up" 
else
echo    "$1 is down" 
fi
}
for  i  in   {1..254}
do
         myping 192.168.4.$i &
done
#使用&符号,将执行的函数放入后台执行
#这样做的好处是不需要等待 ping 第一台主机的回应,就可以继续并发 ping 第二台主机,依次类推。

15. 编写脚本,显示进度条

#!/bin/bash
jindu(){
while :
do
     echo  ‐n  '#'
     sleep 0.2
done
}
jindu &
cp  ‐a  $1  $2
killall  $!
echo  "拷贝完成''

16. 进度条,动态时针版本

#!/bin/bash
#定义一个显示进度的函数,屏幕快速显示|  / ‐ \
rotate_line(){
INTERVAL=0.1                 #设置间隔时间
COUNT="0"                   #设置 4 个形状的编号,默认编号为 0(不代表任何图像)
while :
do
COUNT=`expr $COUNT + 1`          #执行循环,COUNT 每次循环加 1,(分别代表 4 中不同的形状)
case $COUNT in                     #判断 COUNT 的值,值不一样显示的形状就不一样
"1")                                 #值为 1 显示‐ 
          echo ‐e '‐'"\b\c"                     
          sleep $INTERVAL
          ;;
    "2")                               #值为 2 显示\\,第一个\是转义
          echo ‐e '\\'"\b\c"
          sleep $INTERVAL
          ;;
    "3")                              #值为 3 显示|
          echo ‐e "|\b\c"
          sleep $INTERVAL
          ;;
   "4")                             #值为 4 显示/
          echo ‐e "/\b\c"
          sleep $INTERVAL
          ;;
    *)                                #值为其他时,将 COUNT 重置为 0
          COUNT="0";;
    esac
done
}
rotate_line

17. 9*9 乘法表(编写 shell 脚本,打印 9*9 乘法表)

#!/bin/bash
for  i  in  `seq 9`
do
         for  j   in  `seq $i`
         do
                     echo ‐n  "$i*$j=$[i*j]  "
         done
         echo
done

18. 使用死循环实时显示 eth0 网卡发送的数据包流量

#!/bin/bash
while :
do
          echo  '本地网卡 eth0 流量信息如下: '
          ifconfig  eth0   |  grep "RX pack"  | awk  '{print $5}'
          ifconfig  eth0   |  grep "TX pack"  | awk  '{print $5}'
          sleep 1
done

19. 使用 user.txt 文件中的人员名单,在计算机中自动创建对应的账户并配置初始密码

#!/bin/bash
#本脚本执行,需要提前准备一个 user.txt 文件,该文件中包含有若干用户名信息
for  i  in  `cat  user.txt`
do
         useradd  $i
         echo "123456" | passwd ‐‐stdin $i
done

20. 编写批量修改扩展名脚本,如批量将 txt 文件修改为 doc 文件

#!/bin/bash
#执行脚本时,需要给脚本添加位置参数
#脚本名  txt   doc(可以将 txt 的扩展名修改为 doc) #脚本名  doc  jpg(可以将 doc 的扩展名修改为 jpg)
for  i   in   "ls *.$1"
do
        mv  $i    ${i%.*}.$2
done

21. 使用 expect 工具自动交互密码远程其他主机安装 httpd 软件

#!/bin/bash

#删除~/.ssh/known_hosts 后,ssh 远程任何主机都会询问是否确认要连接该主机

rm ‐rf ~/.ssh/known_hosts

expect <<EOF

spawn ssh  192.168.4.254

expect "yes/no"    {send "yes\r"}

#根据自己的实际情况将密码修改为真实的密码字串

expect "password"  {send "密码\r"}

expect "#"      {send "yum ‐y install httpd\r"}

expect "#"      {send "exit\r"}

EOF

22.一键部署 LNMP(源码安装版本)

#!/bin/bash

	menu(){
	clear
	echo " ##############‐‐‐‐Menu‐‐‐‐##############"
	echo "# 1. Install Nginx"
	echo "# 2. Install MySQL"
	echo "# 3. Install PHP"
	echo "# 4. Exit Program"
	echo " ########################################"
	}

	choice(){
	read ‐p "Please choice a menu[1‐9]:" select
	}

	install_nginx(){
	id nginx &>/dev/null
	if [ $? ‐ne 0 ];then
   useradd ‐s /sbin/nologin nginx
	fi
	if [ ‐f nginx‐1.8.0.tar.gz ];then
		tar ‐xf nginx‐1.8.0.tar.gz
		cd nginx‐1.8.0
		yum ‐y install gcc pcre‐devel openssl‐devel zlib‐devel make
		./configure ‐‐prefix=/usr/local/nginx ‐‐with‐http_ssl_module
		make	
		make install
		ln ‐s /usr/local/nginx/sbin/nginx /usr/sbin/
		cd ..
	else
		echo "没有 Nginx 源码包"
	fi
	}
	install_mysql(){
	yum ‐y install gcc gcc‐c++ cmake ncurses‐devel perl
	id mysql &>/dev/null
	if [ $? ‐ne 0 ];then
		useradd ‐s /sbin/nologin mysql
	fi
	if [ ‐f mysql‐5.6.25.tar.gz ];then
		tar ‐xf mysql‐5.6.25.tar.gz
		cd mysql‐5.6.25
		cmake .
		make
		make install
	/usr/local/mysql/scripts/mysql_install_db ‐‐user=mysql ‐‐		datadir=/usr/local/mysql/data/‐‐basedir=/usr/local/mysql/
	
		chown ‐R root.mysql /usr/local/mysql
		chown ‐R mysql /usr/local/mysql/data
		/bin/cp ‐f /usr/local/mysql/support‐files/mysql.server /etc/init.d/mysqld
		chmod +x /etc/init.d/mysqld
		/bin/cp ‐f /usr/local/mysql/support‐files/my‐default.cnf /etc/my.cnf
		echo "/usr/local/mysql/lib/" >> /etc/ld.so.conf
		ldconfig
		echo 'PATH=\$PATH:/usr/local/mysql/bin/' >> /etc/profile
		export PATH
  		  else
        		echo "没有 mysql 源码包"
		exit
	fi
	}
	install_php(){
	#安装 php 时没有指定启动哪些模块功能,如果的用户可以根据实际情况自行添加额外功能如‐‐with‐gd 等
	  yum ‐y install gcc libxml2‐devel
	if [ ‐f mhash‐0.9.9.9.tar.gz ];then
		tar ‐xf mhash‐0.9.9.9.tar.gz
		cd mhash‐0.9.9.9
		./configure
		make
		make install
		cd ..
		if [ ! ‐f /usr/lib/libmhash.so ];then
			ln ‐s /usr/local/lib/libmhash.so /usr/lib/
		fi
		ldconfig
	else
		echo "没有 mhash 源码包文件"
		exit
	fi
	if [ ‐f libmcrypt‐2.5.8.tar.gz ];then
		tar ‐xf libmcrypt‐2.5.8.tar.gz
		cd libmcrypt‐2.5.8
		./configure
	   make
		make install
		cd ..
		if [ ! ‐f /usr/lib/libmcrypt.so ];then 
			ln ‐s /usr/local/lib/libmcrypt.so /usr/lib/
		fi
		ldconfig
	else
		echo "没有 libmcrypt 源码包文件"
		exit
	fi
	
	if [ ‐f php‐5.4.24.tar.gz ];then
		tar ‐xf php‐5.4.24.tar.gz
		cd php‐5.4.24
		./configure ‐‐prefix=/usr/local/php5 ‐‐with‐mysql=/usr/local/mysql ‐‐enable‐fpm  ‐‐enable‐mbstring ‐‐with‐mcrypt ‐‐with‐mhash ‐‐with‐config‐file‐path=/usr/local/php5/etc ‐‐with‐mysqli=/usr/local/mysql/bin/mysql_config
		make && make install
		/bin/cp ‐f php.ini‐production /usr/local/php5/etc/php.ini
		/bin/cp ‐f /usr/local/php5/etc/php‐fpm.conf.default /usr/local/php5/etc/php‐fpm.conf
		cd ..
	else
		echo "没有 php 源码包文件"
		exit
	fi
}
while :
do
menu
choice
case $select i
)
install_nginx
;;
2)
install_mysql
;;
3)
install_php
;;
4)	
exit	
;;
*)
echo Sorry!
esac
done

23. 编写脚本快速克隆 KVM 虚拟机

#!/bin/bash
#本脚本针对 RHEL7.2 或 Centos7.2
#本脚本需要提前准备一个 qcow2 格式的虚拟机模板,名称为/var/lib/libvirt/images /.rh7_template 的虚
拟机模板
#该脚本使用 qemu‐img 命令快速创建快照虚拟机
#脚本使用 sed 修改模板虚拟机的配置文件,将虚拟机名称、UUID、磁盘文件名、MAC 地址
# exit code: 
#  65 ‐> user input nothing
#  66 ‐> user input is not a number
#  67 ‐> user input out of range
#  68 ‐> vm disk image exists

IMG_DIR=/var/lib/libvirt/images
BASEVM=rh7_template
read ‐p "Enter VM number: " VMNUM
if [ $VMNUM ‐le 9 ];then
VMNUM=0$VMNUM
fi

if [ ‐z "${VMNUM}" ]; then
  echo "You must input a number."
  exit 65
elif [[ ${VMNUM} =~ [a‐z] ]; then
  echo "You must input a number."
  exit 66
elif [ ${VMNUM} ‐lt 1 ‐o ${VMNUM} ‐gt 99 ]; then
  echo "Input out of range"
  exit 67
fi
NEWVM=rh7_node${VMNUM}
if [ ‐e $IMG_DIR/${NEWVM}.img ]; then
  echo "File exists."
  exit 68
fi
echo ‐en "Creating Virtual Machine disk image......\t"
qemu‐img create ‐f qcow2 ‐b $IMG_DIR/.${BASEVM}.img $IMG_DIR/${NEWVM}.img &> /dev/null
echo ‐e "\e[32;1m[OK]\e[0m"
#virsh dumpxml ${BASEVM} > /tmp/myvm.xml
cat /var/lib/libvirt/images/.rhel7.xml > /tmp/myvm.xml
sed ‐i "/<name>${BASEVM}/s/${BASEVM}/${NEWVM}/" /tmp/myvm.xml
sed ‐i "/uuid/s/<uuid>.*<\/uuid>/<uuid>$(uuidgen)<\/uuid>/" /tmp/myvm.xml
sed ‐i "/${BASEVM}\.img/s/${BASEVM}/${NEWVM}/" /tmp/myvm.xml
#修改 MAC 地址,本例使用的是常量,每位使用该脚本的用户需要根据实际情况修改这些值
#最好这里可以使用便利,这样更适合于批量操作,可以克隆更多虚拟机
sed ‐i "/mac /s/a1/0c/" /tmp/myvm.xml
echo ‐en "Defining new virtual machine......\t\t"
virsh define /tmp/myvm.xml &> /dev/null
echo ‐e "\e[32;1m[OK]\e[0m"

24. 编写一个点名器脚本

#!/bin/bash
#该脚本,需要提前准备一个 user.txt 文件
#该文件中需要包含所有姓名的信息,一行一个姓名,脚本每次随机显示一个姓名
while :
do
#统计 user 文件中有多少用户
line=`cat user.txt |wc ‐l`
num=$[RANDOM%line+1]
sed ‐n "${num}p" user.txt
sleep 0.2
clear
done

25. 查看有多少远程的 IP 在连接本机(不管是通过 ssh 还是 web 还是 ftp 都统计)

#!/bin/bash
#使用 netstat ‐atn 可以查看本机所有连接的状态,‐a 查看所有,‐t 仅显示 tcp 连接的信息,‐n 数字格式显示
# Local Address(第四列是本机的 IP 和端口信息) 
#Foreign Address(第五列是远程主机的 IP 和端口信息)
#使用 awk 命令仅显示第 5 列数据,再显示第 1 列 IP 地址的信息
#sort 可以按数字大小排序,最后使用 uniq 将多余重复的删除,并统计重复的次数

netstat ‐atn | awk '{print $5}' | awk '{print $1}' | sort ‐nr | uniq ‐c

26. 对 100 以内的所有正整数相加求和(1+2+3+4…+100)

#!/bin/bash
#seq 100 可以快速自动生成 100 个整数
sum=0
for i in `seq 100`
do
    sum=$[sum+i]
done
echo "总和是:$sum"

27. 统计 13:30 到 14:30 所有访问 apache 服务器的请求有多少个

#!/bin/bash
#awk 使用‐F 选项指定文件内容的分隔符是/或者: 
#条件判断$7:$8 大于等于 13:30,并且要求,$7:$8 小于等于 14:30
#最后使用 wc ‐l 统计这样的数据有多少行,即多少个
awk ‐F "[ /:]" '$7":"$8>="13:30" && $7":"$8<="14:30"' /var/log/httpd/access_log |wc ‐l

28. 统计 13:30 到 14:30 所有访问本机 Aapche 服务器的远程 IP 地址是什么

#!/bin/bash
#awk 使用‐F 选项指定文件内容的分隔符是/或者: 
#条件判断$7:$8 大于等于 13:30,并且要求,$7:$8 小于等于 14:30
#日志文档内容里面,第 1 列是远程主机的 IP 地址,使用 awk 单独显示第 1 列即可
awk ‐F "[ /:]" '$7":"$8>="13:30" && $7":"$8<="14:30"{print $1}' /var/log/httpd/access_log

29. 打印国际象棋棋盘,效果如下图:

#!/bin/bash
#设置两个变量,i 和 j,一个代表行,一个代表列,国际象棋为 8*8 棋盘
#i=1 是代表准备打印第一行棋盘,第 1 行棋盘有灰色和蓝色间隔输出,总共为 8 列
#i=1,j=1 代表第 1 行的第 1 列;i=2,j=3 代表第 2 行的第 3 列 
#棋盘的规律是 i+j 如果是偶数,就打印蓝色色块,如果是奇数就打印灰色色块
#使用 echo ‐ne 打印色块,并且打印完成色块后不自动换行,在同一行继续输出其他色块
for i in {1..8}
do
for j in {1..8}
do
	sum=$[i+j]
	if [ $[sum%2] ‐eq 0 ];then
		echo ‐ne "\033[46m \033[0m"
		else
echo ‐ne "\033[47m \033[0m"
	fi
done
echo
done

30. 统计每个远程 IP 访问了本机 apache 几次?

#!/bin/bash
awk '{ip[$1]++}END{for(i in ip){print ip[i],i}}' /var/log/httpd/access_log

31. 统计当前 Linux 系统中可以登录计算机的账户有多少个

#!/bin/bash
#方法 1:
grep  "bash$" /etc/passwd | wc ‐l
#方法 2:
awk ‐f: '/bash$/{x++}end{print x}' /etc/passwd

32. 统计/var/log 有多少个文件,并显示这些文件名

#!/bin/bash
#使用 ls 递归显示所有,再判断是否为文件,如果是文件则计数器加 1
cd /var/log
sum=0
for  i  in  `ls ‐r *`
do
    if [ ‐f $i ];then
      let sum++
      echo "文件名:$i"
    fi
done
echo  "总文件数量为:$sum"

33. 自动为其他脚本添加解释器信息#!/bin/bash,如脚本名为 test.sh 则效果如下:

#!/bin/bash
#./test.sh abc.sh  
自动为 abc.sh 添加解释器信息
#./test.sh user.sh  
自动为 user.sh 添加解释器信息
#先使用 grep 判断对象脚本是否已经有解释器信息,如果没有则使用 sed 添加解释器以及描述信息
if ! grep ‐q "^#!" $1; then
sed '1i #!/bin/bash' $1
sed '2i #Description: '
fi
#因为每个脚本的功能不同,作用不同,所以在给对象脚本添加完解释器信息,以及 Description 后还希望
#继续编辑具体的脚本功能的描述信息,这里直接使用 vim 把对象脚本打开,并且光标跳转到该文件的第 2 行
vim +2 $1

34. 自动化部署 varnish 源码包软件

#!/bin/bash
#本脚本需要提前下载 varnish‐3.0.6.tar.gz 这样一个源码包软件,该脚本即可用自动源码安装部署软件

yum ‐y install gcc readline‐devel pcre‐devel
useradd ‐s /sbin/nologin varnish
tar ‐xf varnish‐3.0.6.tar.gz
cd varnish‐3.0.6

#使用 configure,make,make install 源码安装软件包
./configure ‐‐prefix=/usr/local/varnish
make && make install

#在源码包目录下,将相应的配置文件拷贝到 Linux 系统文件系统中
#默认安装完成后,不会自动拷贝或安装配置文件到 Linux 系统,所以需要手动 cp 复制配置文件
#并使用 uuidgen 生成一个随机密钥的配置文件

cp redhat/varnish.initrc /etc/init.d/varnish
cp redhat/varnish.sysconfig /etc/sysconfig/varnish
cp redhat/varnish_reload_vcl /usr/bin/
ln ‐s /usr/local/varnish/sbin/varnishd /usr/sbin/
ln ‐s /usr/local/varnish/bin/* /usr/bin
mkdir /etc/varnish
cp /usr/local/varnish/etc/varnish/default.vcl /etc/varnish/
uuidgen > /etc/varnish/secret

35. 编写 nginx 启动脚本

#!/bin/bash

#本脚本编写完成后,放置在/etc/init.d/目录下,就可以被 Linux 系统自动识别到该脚本
#如果是centos7以上的版本就是systemctl stop nginx,这种类型
#如果本脚本名为/etc/init.d/nginx,则 service nginx start 就可以启动该服务
#service nginx stop 就可以关闭服务
#service nginx restart 可以重启服务
#service nginx status 可以查看服务状态

program=/usr/local/nginx/sbin/nginx
pid=/usr/local/nginx/logs/nginx.pid
start(){
if [ ‐f  $pid ];then
    echo "nginx 服务已经处于开启状态"
else
    $program
fi
stop(){
if [ ‐! ‐f $pid ];then
    echo "nginx 服务已经关闭"
else
    $program ‐s stop
    echo "关闭服务 ok"
fi
}
status(){
if [ ‐f $pid ];then
	echo "服务正在运行…"
else
    echo "服务已经关闭"
fi
}
case  $1 in
start)
   start;;
stop)
   stop;;
restart)
   stop
   sleep 1
   start;;
status)
   status;;
*)
   echo "你输入的语法格式错误"
esac

36. 自动对磁盘分区、格式化、挂载

#!/bin/bash
#对虚拟机的 vdb 磁盘进行分区格式化,使用<<将需要的分区指令导入给程序 fdisk
#n(新建分区),p(创建主分区),1(分区编号为 1),两个空白行(两个回车,相当于将整个磁盘分一个区)
#注意:1 后面的两个回车(空白行)是必须的!
fdisk /dev/vdb << EOF
n
p
1


wq
EOF

#格式化刚刚创建好的分区
mkfs.xfs  /dev/vdb1

#创建挂载点目录
if [  ‐e /data ]; then
exit 
fi
mkdir /data

#自动挂载刚刚创建的分区,并设置开机自动挂载该分区
echo '/dev/vdb1   /data  xfs  defaults    1 2' >> /etc/fstab
mount ‐a

37. 自动优化 Linux 内核参数

#!/bin/bash
#脚本针对 RHEL7
cat >> /usr/lib/sysctl.d/00‐system.conf <<EOF
fs.file‐max=65535
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 5
net.ipv4.tcp_syn_retries = 5
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
#net.ipv4.tcp_keepalive_time = 120
net.ipv4.ip_local_port_range = 1024 65535
kernel.shmall = 2097152
kernel.shmmax = 2147483648
kernel.shmmni = 4096
kernel.sem = 5010 641280 5010 128
net.core.wmem_default=262144
net.core.wmem_max=262144
net.core.rmem_default=4194304
net.core.rmem_max=4194304
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_keepalive_time = 30
net.ipv4.tcp_window_scaling = 0
net.ipv4.tcp_sack = 0
EOF
sysctl –p

38. 切割 Nginx 日志文件(防止单个文件过大,后期处理很困难)

#!/bin/bash
#mkdir /data/scripts
#vim  /data/scripts/nginx_log.sh 

#!/bin/bash
logs_path="/usr/local/nginx/logs/"
mv ${logs_path}access.log ${logs_path}access_$(date ‐d "yesterday" +"%Y%m%d").log
kill ‐USR1 `cat /usr/local/nginx/logs/nginx.pid`
# chmod +x /data/scripts/nginx_log.sh
#crontab ‐e          #脚本写完后,将脚本放入计划任务每天执行一次脚本
0 1 * *  *  /data/scripts/nginx_log.sh

39. 检测 MySQL 数据库连接数量

#!/bin/bash
#本脚本每 2 秒检测一次 MySQL 并发连接数,可以将本脚本设置为开机启动脚本,或在特定时间段执行
#以满足对 MySQL 数据库的监控需求,查看 MySQL 连接是否正常
#本案例中的用户名和密码需要根据实际情况修改后方可使用 
log_file=/var/log/mysql_count.log
user=root
passwd=123456
while :
do
    sleep 2
    count=`mysqladmin ‐u "$user" ‐p "$passwd"  status | awk '{print $4}'`
    echo "`date +%Y‐%m‐%d` 并发连接数为:$count" >> $log_file
done

40. 根据 md5 校验码,检测文件是否被修改

#!/bin/bash

#本示例脚本检测的是/etc 目录下所有的 conf 结尾的文件,根据实际情况,您可以修改为其他目录或文件
#本脚本在目标数据没有被修改时执行一次,当怀疑数据被人篡改,再执行一次
#将两次执行的结果做对比,MD5 码发生改变的文件,就是被人篡改的文件
for i in $(ls /etc/*.conf)
do
md5sum "$i" >> /var/log/conf_file.log
done
  • 20
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值