SHELL编程

Ubuntu默认使用的shell解析是dash,dash只有bash一部分的功能因此我们需要进行修改

(1)执行

sudo dpkg-reconfigure dash

(2)在弹出的对话框中选择No

1、变量的定义

(1)由字母、数字、下划线组成,数字不能作为开头。
(2)通过 “=” 来定义一个变量的值

myname='galley'  # 字符串类型,不解析任何字符
courses="math"  # 双引号内部会解析$和反斜杠特殊字符
sum=100;price=1.2544  
now_date=`date`  # 反引号执行系统命令

shell的变量类型只有字符串类型,所以当你不使用引号引起来的时候,就要保证变量的值不包含特殊的符号,如空格、$、&符。

2、变量的引用

(1)变量的引用,使用$加变量名,来引用一个变量的值

# 定义变量
programe_name="httpd"
# 引用变量
echo $programe_name
echo ${programe_name}

(2)变量名外的花括号是可选的,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况。

#!/bin/sh
for skill in php java linux db2
	do
		# 帮助shell解释器识别边界
		echo "I am good at ${skill}Script"
	done
ubantu@ubantu-virtual-machine:~$ sh test.sh
I am good at phpScript
I am good at javaScript
I am good at linuxScript
I am good at db2Script

(3)如果不加{},运行结果如下:

#!/bin/sh
for skill in php java linux db2
	do
		# 帮助shell解释器识别边界
		echo "I am good at $skillScript"
	done
ubantu@ubantu-virtual-machine:~$ sh test.sh
I am good at 
I am good at 
I am good at 
I am good at 
  • 不加花括号,系统将会误认为skillScript是一个整体,而在我们的代码中找不到该变量

3、变量值的特殊符号引用

关于单引号和双引号以及反引号的引用方法演示

(1)单引号的引用(不解析任何字符)

ubantu@ubantu-virtual-machine:~$ sh
sh-4.3$ testvar=100
sh-4.3$ echo 'The testvalue is $testvar'
The testvalue is $testvar

(2)双引号的引用(会解析$和反斜杠特殊字符)

ubantu@ubantu-virtual-machine:~$ sh
sh-4.3$ testvar=100             
sh-4.3$ echo "The testvalue is $testvar"
The testvalue is 100

(3)反引号的引用(执行系统命令)

ubantu@ubantu-virtual-machine:~$ sh
sh-4.3$ now_date = `date`
sh: 6: now_date: not found
sh-4.3$ now_date=`date`
sh-4.3$ echo $now_date
Wed Feb 27 13:51:28 CST 2019
sh-4.3$ 

环境变量

(1)定义:

环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:PATH、PWD、USER、当前使用的SHELL名称等

(2)常见环境变量:

PATH:系统路径
HOME:当前用户家目录
HISTSIZE:保存历史记录的条数
LOGNAME:当前登录用户用户名
HOSTNAME:主机名称,若应用程序要用到主机名的话,一般是从这个环境变量中取得的
SHELL:当前用户用的是那种shell
LANG/LANGUGE:和语言相关的环境变量,使用多种语言的用户可以修改次环境变量
MAIL:当前用户的邮件存放目录

(3)查看环境变量

env:显示所有环境变量
echo $PATH:显示某一个环境变量的值

局部变量

(1)定义:

在Shell脚本中由用户自定义的变量,其作用域是从变量被定义的地方开始,到shell结束为止,其作用域为脚本,离开本脚本,则变量无效
  • 动手操作
(1)编写一个脚本,定义一个变量,并输出其结果
#!/bin/sh
mystr=abcd
echo $mystr
~   

ubantu@ubantu-virtual-machine:~/myshell$ sh test1.sh 
abcd
    
(2)退出脚本再输出这个变量看看有没有结果
ubantu@ubantu-virtual-machine:~/myshell$ echo $mystr

ubantu@ubantu-virtual-machine:~/myshell$  

(2)在用户登录的shell中定义的变量,重新登录后改变量消失

  • 动手操作
(1)登录到shell脚本,给一个变量赋值,显示该变量的结果
ubantu@ubantu-virtual-machine:~/myshell$ sh
sh-4.3$ var2=12345
sh-4.3$ echo $var2
12345
sh-4.3$ exit
(2)退出当前shell,重新登录,再输出这个变量,看看有无结果
ubantu@ubantu-virtual-machine:~/myshell$ sh
sh-4.3$ echo $var2

sh-4.3$ 

预定义变量

(1)定义:

预定义变量和环境变量相类似,也是在Shell一开始就定义了的变量,所不同的是,用户只能根据Shell的定义来使用这些变量,而不能重新定义它,所以预定义变量都是由$符合另一个符号组成的

(2)常用的Shell预定义变量有以下:

$#:位置参数的数量
$*:所有位置参数的内容
$?:命令执行后返回的状态,0表示成功,1表示失败
$$:当前进程的进程号
$!:后台运行的最后一个进程号,很少用
$0:当前执行的进程名

(3)示例:

#!/bin/sh
echo "这个进程的名字是:$0"
echo "参数的数量是:$#"
echo "所有的参数:$*"
echo "当前进程的进程号:$$"
echo "命令执行的返回状态:$?"
echo "后台运行的最后一个进程号:$!"
~                                                                              
~    

ubantu@ubantu-virtual-machine:~/myshell$ sh test2.sh 
这个进程的名字是:test2.sh
参数的数量是:0
所有的参数:
当前进程的进程号:2648
命令执行的返回状态:0
后台运行的最后一个进程号:
        

ubantu@ubantu-virtual-machine:~/myshell$ sh test2.sh 1 2 3 4
这个进程的名字是:test2.sh
参数的数量是:4
所有的参数:1 2 3 4
当前进程的进程号:2656
命令执行的返回状态:0
后台运行的最后一个进程号:
fatpuffer@ubuntu:~/mybash$             

脚本输入输出

(1)echo命令发送数据到标准的输出设备,数据采用的是字符串的方式,echo命令可以输出一个变量

ubantu@ubantu-virtual-machine:~/myshell$ sh
sh-4.3$ myprograme="myprograme is : mysql monitor script"
sh-4.3$ echo $myprograme 
myprograme is : mysql monitor script
sh-4.3$ 

(2)echo两个重要参数

  • -e:识别输出内容里的转义序列
sh-4.3$ echo -e 'hello\tworld'
hello	world
  • -n:忽略结尾的换行
sh-4.3$ echo -e -n 'hello\tworld'
hello	world$

(3)printf输出,和echo功能类似,也可以输出变量,printf还可以按照格式输出变量,需要注意的是:

  • printf的默认输出没有换行,需要自己加 “\n”
sh-4.3$ mystr="hello,world"
sh-4.3$ printf $mystr
hello,world$ 


sh-4.3$ mystr="hello,world"
sh-4.3$ printf "%s\n" $mystr  # 使用占位符时$符和前引号内的字符串之间必须要有空格
hello,world
sh-4.3$ 
  • printf支持格式化输出
#!/bin/sh
name=zhangsan
age=22
address="beijing"
printf "name:%s,age:%s,address:%s\n" $name $age $address


ubantu@ubantu-virtual-machine:~/myshell$ sh test3.sh 
name:zhangsan,age:22,address:beijing
ubantu@ubantu-virtual-machine:~/myshell$

(4)read命令读取标准输入设备的下一行,标准输入 中的新的一行到换行符前的所有字符会被读取,并赋值给变量(可以结合echo一起实现读取并输出的功能)。

  • -p:添加提示信息
#!/bin/sh
# 接受输入并输出IP地址
echo "please input your ipaddress"
read ipaddr
echo "my ip address is $ipaddr"


ubantu@ubantu-virtual-machine:~/myshell$ sh test4.sh 
please input your ipaddress
192.16.0.13
my ip address is 192.16.0.13
#!/bin/sh
# 接受输入并输出
now_time=`date +%F,%H:%M:%S`
read -p "please input your username:" username
read -p "please input your password:" password
# awk是用来提取列的主要工具
# {print $1}就是将某一行中以空格为分割符的第一个字段打印出来
password_md5=$(echo $password|md5sum|awk "{print $1}")
echo "$now_time,系统为您生成的用户密码为:$username/$password_md5"


ubantu@ubantu-virtual-machine:~/shell$ sh test.sh 
please input your username:fatpuffer
please input your password:admin
2019-03-04,13:53:50,系统为您生成的用户密码为:fatpuffer/456b7016a916a4b178dd72b947c152b7  -
ubantu@ubantu-virtual-machine:~/shell$ 

SHELL程序中的运算和比较操作

shell运算操作

(1)let整数运算

  • let命令让BASH shell执行算数值操作,使用let,可以比较两个值或执行加减乘除等这样的算数操作,这种操作经常用于shell程序中的控制流程结构或执行需要的运算,注意let命令只能执行整数的相关运算,运算结果也只能保存整数。
  • let 变量名 = 变量1 运算符 变量2
  • 常见的算数操作分类
  • ( + - * / %)
  • 注意:和 C 语言类似,let i=$i+1也可以写成let i++,从而简化书写
  • 示例:
#!/bin/sh
# let执行算数操作经常使用的方法演示
i=10
j=20
k=3
# 执行算数运算
let res1=$i+$j+$k
let res2=$j-$i-$k
let res3=$i*$j*$k
let res4=$i*$j/$k
# 输出结果
echo "i+j+k=$res1"
echo "j-i-k=$res2"
echo "i*j*k=$res3"
echo "i*j/k=$res4"  # let会将整数运算得到的结果保留整数,将小数部分截取


ubantu@ubantu-virtual-machine:~/myshell$ sh test.sh 
i+j+k=33
j-i-k=7
i*j*k=600
i*j/k=66
ubantu@ubantu-virtual-machine:~/myshell
  • let方法来控制流程结构(此处不得不强调一下,[ ] 左右必须有空格,在此被坑了很久)
#!/bin/sh
# 使用let方法来控制流程结构
i=1
n=3
while [ 1 ]
	do
		if [ $i -le $n ]  # 小于等于
			then
				echo "$i"
			else
				break
		fi
		let i=$i+1   # 用let进行+1操作,此处也可以写成let i++
	done

(2)expr整数运算

  • expr在linux中是一个功能非常强大的命令,和let功能类似,它做算数运算时,只能进行整数类型运算,不能保存小数结果,除了进行算数运算,expr 还可以进行字符串的操作,因此 expr 功能非常强大。
  • expr expression1 操作符 expression2
  • 操作符*前必须加'\'用于转义,并且操作符和两个expression之间必须有空格(这一点与let不同)
  • expr不适合于小数的运算
sh-4.3$ expr 1 + 1
2

sh-4.3$ expr 1.1 + 1
expr: non-integer argument
sh-4.3$ 
  • 常见的算数操作分类: ( + - * / %)
  • expr命令使用方法举例:
(1)常见的算数运算操作
#!/bin/sh
# expr 执行算数操作经常使用的方法演练
i=10
j=20
k=3

# 执行算数运算
echo "i:$i;j:$j;k:$k"
res1=`expr $i + $j + $k`  # expr作为外部命令要用反引号引起来。
res2=`expr $j - $i - $k`
res3=`expr $i \* $j \* $k`
res4=`expr $i \* $j / $k`

# 输出运算结果
echo "i+j+k=$res1"
echo "j-i-k=$res2"
echo "i*j*k=$res3"
echo "i*j\k=$res4"


ubantu@ubantu-virtual-machine:~/shell$ sh test.sh 
i:10;j:20;k:3
i+j+k=33
j-i-k=7
i*j*k=600
i*j\k=66
ubantu@ubantu-virtual-machine:~/shell$

(2)expr方法来控制流程结构
#!/bin/sh
# expr 控制流程结构
i=1
n=5
# 用expr来控制输出,连续输出i变量的值
while [ 1 ]
	do
		if [ $i -le $n ]
			then
				echo "$i"
			else
				break
		fi
		i=`expr $i + 1`  # expr操作符左右两端必须有空格
	done


ubantu@ubantu-virtual-machine:~/shell$ sh test.sh 
1
2
3
4
5
ubantu@ubantu-virtual-machine:~/shell$

(3)bc浮点运算

  • letexpr不能处理浮点运算,并且缺乏特定的一些重要的精确操作,但是bc可以进行浮点运算,是一个多功能的灵活的工具,提供精确的复杂计算功能,他是linux一个重要的工具,bc经常使用在管道里。
  • scale作为 bc 一个最重要的选项,用来是定输出小数的位数。
variable=`echo "OPTIONS; OPTIONS" | bc`  

ubantu@ubantu-virtual-machine:~/shell$ sh
sh-4.3$ n=`echo "scale=3;13 / 2" | bc`
sh-4.3$ echo $n
6.500
sh-4.3$
  • 常用的浮点运算操作演练
#!/bin/sh
# expr 执行算数操作经常使用的方法演练
# bc 执行浮点运算方法演练
i=10
j=20
k=3
# 执行算数运算
echo "i:$i;j:$j;k:$k"
res1=`expr $i + $j + $k`  # expr作为外部命令要用反引号引起来。
res2=`expr $j - $i - $k`
res3=`expr $i \* $j \* $k`
res4=`expr $i \* $j / $k`

# 执行浮点运算
res5=`echo "scale=5; $i * $j / $k" | bc`  # 注意此处乘法不需要用转义

# 输出运算结果
echo "i+j+k=$res1"
echo "j-i-k=$res2"
echo "i*j*k=$res3"
echo "expr:i*j\k=$res4"
echo "bc:i*j\k=$res5"


ubantu@ubantu-virtual-machine:~/shell$ sh test.sh 
i:10;j:20;k:3
i+j+k=33
j-i-k=7
i*j*k=600
expr:i*j\k=66
bc:i*j\k=66.66666
ubantu@ubantu-virtual-machine:~/shell$

(4)expr字符串的运算

  • shell中字符串操作也是常见的运算之一 ,expr除了算数运算之外,还可以进行字符串相关的运算,以下简单介绍使用expr进行的常用字符串操作
  • 输出字符串的长度
ubantu@ubantu-virtual-machine:~/shell$ sh
sh-4.3$ str1="asds1223"
sh-4.3$ echo ${#str1}
8
sh-4.3$ expr length $str1
8
sh-4.3$
  • 取字符串的操作
  • expr substr $string $position $length # 注意位置编号从1开始
  • echo $ {string: $pos: $length} # 注意位置编号从0开始
sh-4.3$ string="asdjbsakdjff12342434"
sh-4.3$ expr substr $string 1 3
asd
sh-4.3$ echo ${string:0:3}
asd
sh-4.3$
  • 字符串连接的操作
  • expr命令没有字符串连接的操作,但其也是很常见的
sh-4.3$ str1=abc
sh-4.3$ str2=123
sh-4.3$ str3="${str1}$str2"  # 这个地方可以定义字符串连接的分隔符
sh-4.3$ echo $str3
sh-4.3$ str3="${str1};$str2"  # 这个地方可以定义字符串连接的分隔符
sh-4.3$ echo $str3
abc;123
sh-4.3$
  • 字符串的替换操作
  • expr命令没有字符串替换的操作,但其也是很常见的
sh-4.3$ string='hello world hello python'
sh-4.3$ echo ${string/hello/Hello}  # 替换一次
Hello world hello python
sh-4.3$ echo ${string//hello/Hello}  # 替换全部
Hello world Hello python
sh-4.3$ 

test比较操作

(1)test比较两个值

  • 测试比较两个值是linux中常用的比较运算,test命令可以进行对两个值得比较,如果比较成功则返回值为0,否则为非0。
  • 常用的比较方法:整数比较、字符串比较、逻辑比较(与、或、非)、文件比较
  • test的命令语法:test value1 -option value2
  • option:lt、gt、eq
  • 如果比较成功则$?为0,否则返回非0,此处用于判断操作。

(2)test整数比较的方法

|---------------------------------------|
|	大于					  	-gt         |           
|	小于                   	-lt         |            
|	大于等于                	-ge         |         
|	小于等于               	-le         |         
|	等于                     -eq			|       
|	不等于                   -ne         |      
|---------------------------------------|
#!/bin/sh
# test 整数比较方法熟练演练
a=100
b=200
c=100
d=300
# 输出a,b,c,d的值
echo -e "a:$a\t b:$b\t c:$c\t d:$d"
# 大于比较
test $b -gt $a  # 成功则 $? 返回 0
if [ $? -eq 0 ]
	then
		echo "b>a"
	else
		echo "a
fi
# 大于等于比较
test $c -ge $a
if [ $? -eq 0 ]
	then
		echo "c>=a"
	else
		echo "a
fi
# 等于比较
test $c -eq 100
if [ $? -eq 0 ]
	then 
		echo "c==100"
	else
		echo "c!=100"
fi
# 不等于比较
test $d -ne 400
if [ $? -eq 0 ]
	then
		echo "d!=400"
	else
		echo "d==400"
fi



ubantu@ubantu-virtual-machine:~/shell$ sh test.sh 
a:100	 b:200	 c:100	 d:300
b>a
c>=a
c==100
d!=400
ubantu@ubantu-virtual-machine:~/shell$

(3)test字符串比较方法

|-----------------------------------------------------------|
|	测试空字符串                               -z				|
|	测试字符串的长度为非零                       -n				|
|	等于某一个字符串                            = 				|     
|	不等于某一个字符串                          !=             |
|-----------------------------------------------------------|
#!/bin/sh
# test 字符串比较方法
str1="abc"
str2="abc"
str3="123"
str4=""

# 输出字符串的值
echo -e "str1: ${str1}\t str2: ${str2}\t str3: ${str3}\t str4: ${str4}\t"

# 长度是否为0
test -n $str1  # 长度不为0,则程序执行返回值为0(即非空字符串返回0)
if [ $? -eq 0 ]
	then
		echo "the length of str1 is not zero"
	else
		echo "the length of str1 is zero"
fi

# 字符串是否为空
test -z $str4  # 字符串长度为0,则程序返回0(空字符串返回0)
if [ $? -eq 0 ]
	then
		echo "the length of str4 is zero"
	else
		echo "the length of str4 is not zero"
fi

# 字符串相等
test str1=str2
if [ $? -eq 0 ]
	then
		echo "str1 equal str2"
	else
		echo "str1 not equal str2"
fi

# 字符串不相等
test str1!=str3
if [ $? -eq 0 ]
	then
		echo "str1 not equal str3"
	else
		echo "str1 equal str3"
fi


ubantu@ubantu-virtual-machine:~/shell$ sh test.sh 
str1: abc	 str2: abc	 str3: 123	 str4: 	
the length of str1 is not zero
the length of str4 is zero
str1 equal str2
str1 not equal str3
ubantu@ubantu-virtual-machine:~/shell$

(4)test逻辑比较方法

|--------------------------|
|	逻辑与		-a		   |
|	逻辑或		-o  	   |
|	逻辑非		 !		   |
|--------------------------|
#!/bin/sh
# test 逻辑比较方法熟练演练
basepath=$(pwd)
filename=$0  # 程序名

echo "$basepath目录下的$filename与或非运算演练....."

# 与运算( $#: 位置参数的数量   $1:第一个参数 )
test $# -eq 1 -a $1 -eq 100   # 输入的参数个数为1且第一个参数为100
if [ $? -eq 0 ]
	then
		echo "参数个数为1且参数值为100"
	else
		echo "不满足与运算的输入要求"
fi

# 或运算
test $# -ge 1 -o $1 -eq 100   # 输入的参数个数大于等于1或第一个参数为100
if [ $? -eq 0 ]
	then
		echo "参数个数为大于等于1,,或参数值为100"
	else
		echo "不满足或运算的输入要求"
fi

ubantu@ubantu-virtual-machine:~/shell$ sh test.sh 200 200
/home/ubantu/shell目录下的test.sh与或非运算演练.....
不满足与运算的输入要求
参数个数为大于等于1,,或参数值为100
ubantu@ubantu-virtual-machine:~/shell$ 

(5)test文件比较的方法

|-------------------------------------------|
|	文件存在并且是一个常规文件		-f			|
|	文件不为空					-s			|
|	文件可读						-r			|
|	文件可写						-w			|
|	文件可运行					-x			|
|	文件是一个目录名				-d			|
|	文件是一个符号链接				-h			|
|	文件名引用一个字符设备			-c			|
|	文件名引用一个块文件			-b			|
|-------------------------------------------|

常规文件:-rw-rw-r--
目录文件:drwxrwxr-x
字符设备或块设备文件:crw--w----
块设备文件:brw-rw----      			
套接口文件:srwxrwxrwx      	    socket套接字文件
符号链接文件:lrwxrwxrwx          软连接文件
#!/bin/sh
# test文件比较方法演练
basepath=$(pwd)
filename=$0
filename2="./noneexist.txt"
dir_name="pythonShell"
echo "$basename目录下的$filename文件比较方法演练"

# 文件存在且为常规文件与运算
test -f $filename
if [ $? -eq 0 ]
	then
		echo "$filename文件存在且为常规文件"
	else
		echo "$filename文件不存在或不为常规文件"
fi

test -f $filename2
if [ $? -eq 0 ]
	then 
		echo "$filename2 存在且为常规文件"
	else
		echo "$filename2 不存在或不为常规文件"
fi

test -d $dir_name
if [ $? -eq 0 ]
	then 
		echo "$dir_name 是一个文件夹"
	else
		echo "$dir_name 不是一个文件夹"
fi		

test -r $filename
if [ $? -eq 0 ]
	then 
		echo "$filename 可读"
	else
		echo "$filename 不可读"
fi	

test -w $filename
if [ $? -eq 0 ]
	then 
		echo "$filename 可写"
	else
		echo "$filename 不可写"
fi	

test -x $filename
if [ $? -eq 0 ]
	then 
		echo "$filename 可执行"
	else
		echo "$filename 不可执行"
fi	


ubantu@ubantu-virtual-machine:~/shell$ touch noneexist.txt
ubantu@ubantu-virtual-machine:~/shell$ mkdir pythonShell
ubantu@ubantu-virtual-machine:~/shell$ sh test.sh
test.sh文件存在且为常规文件
./noneexist.txt 存在且为常规文件
pythonShell 是一个文件夹
test.sh 可读
test.sh 可写
test.sh 不可执行


ubantu@ubantu-virtual-machine:~/shell$ ls -la
total 52
-rw-rw-r--  1 ubantu ubantu     0 Mar  4 11:29 noneexist.txt
drwxrwxr-x  2 ubantu ubantu  4096 Mar  4 11:29 pythonShell
-rw-rw-r--  1 ubantu ubantu  6116 Mar  4 11:29 test.sh

SHELL程序中的三大结构

  • 顺序结构
  • 选择结构
  • 循环结构

(1)顺序结构

  • 顺序结构的程序设计是最简单的一种结构,他的执行顺序是自上而下执行,因此,我们只要按照解决问题思路依次编程即可。
			#!/bin/sh
				|
			  语句块1
			  	|
			  语句块2
			  	|
			  语句块N
  • 常用系统变量的含义
变量名 说明
$# 不包括命令在内的命令行参数的数目
$* 命令行所有参数组成的字符串
$@ 命令行所有参数组成的字符串
$n n为数字,$0表示命令名称,$1表示命令第一个参数,以此类推
$? 上一个命令的返回值,如果正常退出则返回0,反之返回非0值
$$ 当前的进程PID号
$! 后台运行的最后一个进程的进程号
  • 常用环境变量的含义
变量名 说明
HOME 当前用户的主目录
PATH 命令搜索路径
LOGNAME 用户登录名
PS1 第一命令提示符,是#或$
PS2 第二命令提示符,默认是>
PWD 用户的当前目录
UID 当前用户标识
TERM 终端类型
SHELL 用户shell类型
HISFILE 存储历史命令的文件

(2)选择结构

  • if-then
(1)单分支 if 结构,此类单分支结构,当条件满足的时候,就会执行 then 后面的语句,不满足时,就直接退出。

if [ 条件 ];
	then
		语句1...
	else
		语句2...
fi



(2)双分支 if 结构,当条件满足时就会运行 then 后面的语句,条件不满足时就运行 else 后面的语句。

if [ 条件 ];
	then
		语句...
fi

  1 #!/bin/sh
  2 # if-then双分支结构演练
  3 
  4 # 获取对应用户UID
  5 id=$(id -u $1)
  6 if [ $? -eq 0 ]
  7     then
  8         # 存在该用户则直接输出该用户id
  9         echo "$1 user alreday exist, uid is $id"
 10     else
 11         # 用户不存在则创建这个用户
 12         useradd $1
 13         id=$(id -u $1)
 14         echo "$1 user is created, and uid is $id"
 15 fi                                               

ubantu@ubantu-virtual-machine:~/shell$ sh test.sh ubantu
ubantu user alreday exist, uid is 1000

ubantu@ubantu-virtual-machine:~/shell$ sudo sh test.sh ubuntu
[sudo] password for ubantu: 
id: ‘ubuntu’: no such user
ubuntu user is created, and uid is 1001


(3)嵌套 if 结构,当条件满足条件1时,则执行 then 后面的语句,当条件再满足条件2,则执行 then 后面的语句,不满足条件2,则退出,当条件不满足条件1,则执行 else 后面的语句。

if [ 条件1 ];
	then
		if [ 条件2 ];
			then
				语句1...
			else
				语句2...
		fi
	else
		语句...
fi

demo:首先判断运行脚本的系统参数有多少个,如果参数个数不等于1,则提示参数输入错误,否则,判断输入的用户是否存在,存在则输出该用户的UID,不存在则创建该用户,并且输出这个用户的UID

  1 #!/bin/sh
  2 # if嵌套结构
  3 
  4 # 获取对应用户UID
  5 if [ $# -ne 1 ]
  6     then
  7         echo "参数输入有误,只能输入一个参数..."
  8     else
  9         id=$(id -u $1)
 10         if [ $? -eq 0 ]
 11             then                                                                                                      
 12                 echo "$1 user already exist, uid is $id"
 13             else
 14                 useradd $1
 15                 id=$(id -u $1)
 16                 echo "$1 is created, and uid is $id"
 17 
 18         fi
 19 fi


ubantu@ubantu-virtual-machine:~/shell$ sh test.sh ubantu
ubantu user already exist, uid is 1000

ubantu@ubantu-virtual-machine:~/shell$ sudo sh test.sh fatpuffer
[sudo] password for ubantu: 
id: ‘fatpuffer’: no such user
fatpuffer is created, and uid is 1002
ubantu@ubantu-virtual-machine:~/shell$
  • case-esac
case 语句适用于需要进行多重分支的应用情况,它也是选择结构中常用的一种控制结构

case $变量名 in   # 严格掌握其语法 
	模式1)       # 右括号不能省
	命令序列1
	;;           # 两分号不能省
	模式2)
	命令序列2
	;;
	*)
	默认执行的命令序列
	;;
esac             # 结尾反写case表示结束

demo:用户从键盘输入一个字符,判断该字符时字母还是其他字符,并给出提示信息。

#!/bin/sh
# case-esac分支结构演练

read -p "请输入内容(按回车结束):" data
case $data in 
	[0-9])
		echo "你输入的时数字"
		echo "数字是:$data"
		;;
	[a-z]|[A-Z])
		echo "你输入的是字符"
		echo "字符是:$data"
		;;
	*)
		echo "你输入的是特殊字符"
		echo "特殊字符是:$data"
		;;
esac


ubantu@ubantu-virtual-machine:~/shell$ sh test.sh
请输入内容(按回车结束):s
你输入的是字符
字符是:s
ubantu@ubantu-virtual-machine:~/shell$ sh test.sh
请输入内容(按回车结束):4
你输入的时数字
数字是:4
ubantu@ubantu-virtual-machine:~/shell$ sh test.sh
请输入内容(按回车结束)&
你输入的是特殊字符
特殊字符是:&
ubantu@ubantu-virtual-machine:~/shell$

(3)循环结构

  • for循环结构
1、遍历/列表式循环结构
for cariable in list
	do
		statement
	done

(1)用seq产生一个序列范围,来控制遍历的次数
  1 #!/bin/sh                                                                                                             
  2 
  3 read -p "请输入一个数字:" num
  4 for i in $(seq $num)
  5     do
  6         echo $i
  7     done
  8         break


ubantu@ubantu-virtual-machine:~/shell$ sh test.sh
请输入一个数字:10
1
2
3
4
5
6
7
8
9
10

(2)命令序列不是连续的情况,可以自定义来处理

  1 #!/bin/sh                                                                                                             
  2 
  3 for mydir in A B C E G
  4     do
  			# -v 打印提示信息
  			# -m 指定权限
  5         mkdir -v -m 755 $mydir
  6     done


ubantu@ubantu-virtual-machine:~/shell$ sh test.sh
mkdir: created directory 'A'
mkdir: created directory 'B'
mkdir: created directory 'C'
mkdir: created directory 'E'
mkdir: created directory 'G'

2、C语言风格的循环结构

for ((expr1;expr2;expr3))
	do
		statement
	done


demo:创建一年中1月至12月所使用的数据库,将统计结果插入到相应的月份中

  1 #!/bin/sh                                                                                                             
  2 
  3 for ((month=1;$month<=12;month++))
  4     do
  5         echo "create databases analyse_$month"
  6         sleep 1
  7         # mysql -e "create database analyse_$month"
  8         # 统计结果入相应的月份库中
  9         # ...
 10     done


ubantu@ubantu-virtual-machine:~/shell$ sh test.sh
create databases analyse_1
create databases analyse_2
create databases analyse_3
create databases analyse_4
create databases analyse_5
create databases analyse_6
create databases analyse_7
create databases analyse_8
create databases analyse_9
create databases analyse_10
create databases analyse_11
create databases analyse_12
ubantu@ubantu-virtual-machine:~/shell$
  • while循环结构
1、语法结构

while expression
	do
		statement
	done
(1)while [] 结构,此时while后面要跟空格,否则报错
(2)while(())结构,不需要空格

demo1:用while []结构控制循环的次数,输出相关的变量

  1 #!/bin/sh
  2 
  3 i=1
  4 while [ $i -le 10 ]
  5     do
  6         echo $i
  7         let i++
  8     done

ubantu@ubantu-virtual-machine:~/shell$ sh test.sh
1
2
3
4
5
6
7
8
9
10
ubantu@ubantu-virtual-machine:~/shell$



demo2:用while(())结构控制循环的次数,输出相关的变量

  1 #!/bin/sh
  2 
  3 i=1
  4 while((i<=10))                                                                                                        
  5     do     
  6         echo $i
  7         let i++
  8     done

ubantu@ubantu-virtual-machine:~/shell$ sh test.sh
1
2
3
4
5
6
7
8
9
10
ubantu@ubantu-virtual-machine:~/shell$ 

demo3:用while循环实现一个无限循环,每隔3秒调用一次程序,再解决队列一类的问题的时候会经常用到。

  1 #!/bin/sh
  2 
  3 while [ 1 ]
  4     do
  5         echo "the script is runing..."
  6         sleep 3                                                                                                       
  7     done

  1 #!/bin/sh
  2 
  3 while [ 1 ]
  4     do
  5         echo "the script is runing..."
  6         sleep 3                                                                                                       
  7     done

ubantu@ubantu-virtual-machine:~/shell$ sh test.sh
the script is runing...
the script is runing...
the script is runing...
the script is runing...
the script is runing...
the script is runing...
the script is runing...

  • continue、break循环结构
break:退出当前循环,并且将控制权传递到本循环后面的第一个命令。
continue:当程序执行过程中遇到这个命令,就会忽略本次循环剩余的命令,将控制权交给循环的顶部。

demo:break程序演示:循环从键盘读入一个字符,输出该字符,当输入的字符为 'x''X'时,退出当前循环。

  1 #!/bin/sh                                                                                                             
  2 
  3 while [ 1 ]
  4     do
  5         read -p '请输入字符(输入'x'或'X'退出):' str
  6         test $str = x -o $str = X
  7         if [ $? -eq 0 ]
  8             then
  9                 break
 10             else
 11                 echo "你输入的内容是:$str"
 12         fi
 13     done



ubantu@ubantu-virtual-machine:~/shell$ sh test.sh
请输入字符(输入x或X退出):r
你输入的内容是:r
请输入字符(输入x或X退出):h
你输入的内容是:h
请输入字符(输入x或X退出):b
你输入的内容是:b
请输入字符(输入x或X退出):s
你输入的内容是:s
请输入字符(输入x或X退出):x
ubantu@ubantu-virtual-machine:~/shell$



demo:continue程序演示:循环从键盘读入一个字符,输出该字符,当输入的字符为 'x''X'时,进行下一次循环,当输入 'q''Q'时退出程序。

  1 #!/bin/sh
  2 
  3 while [ 1 ]
  4     do
  5         read -p '请输入字符(输入'x'或'X'退出):' str
  6         test $str = x -o $str = X
  7         if [ $? -eq 0 ]
  8             then
  9                 continue
 10             else
 11                 test $str = q -o $str = Q
 12                 if [ $? -eq 0 ]
 13                     then
 14                         break
 15                     else
 16                         echo "你输入的内容是:$str"
 17                 fi                                                                                                    
 18         fi     
 19     done

ubantu@ubantu-virtual-machine:~/shell$ sh test.sh
请输入字符(输入q或Q退出):d
你输入的内容是:d
请输入字符(输入q或Q退出):f
你输入的内容是:f
请输入字符(输入q或Q退出):5
你输入的内容是:5
请输入字符(输入q或Q退出):x
请输入字符(输入q或Q退出):F
你输入的内容是:F
请输入字符(输入q或Q退出):Q
ubantu@ubantu-virtual-machine:~/shell$
  • while read循环
while read line 可以按行读入,一直到所有行都读完,才退出循环,再实际工作中,经常会采用这种循环结构,进行数据处理。

语法格式:
cat file.txt | while read line  # 此处的cat也可以时一个产生若干行的命令,如find
	do
		...
	done


  1 #!/bin/sh
  2 
  3 sum_line=0
  4 cat ./noneexist.txt | while read ipline
  5     do
  6         let sum_line=sum_line+1
  7         # -n忽略行尾的换行
  8         echo -n "第$sum_line行....."
  9         # awk是用来提取列的主要工具
 10         # {print $1}就是将某一行中以空格为分割符的第一个字段打印出来                                                  
 11         from=`echo $ipline|awk '{print $1}'`
 12         ip=`echo $ipline|awk '{print $2}'`
 13         echo "$from-----------$ip"
 14         sleep 1
 15     done
 16 echo "这个文件的行数为:$sum_line"


ubantu@ubantu-virtual-machine:~/shell$ cat noneexist.txt
111111111 1111111111
2222222222222222222
3333333333333333333
4444444444444444444
5555555555555555555

ubantu@ubantu-virtual-machine:~/shell$ sh test.sh 
第1行.....111111111-----------1111111111
第2行.....2222222222222222222-----------
第3行.....3333333333333333333-----------
第4行.....4444444444444444444-----------
第5行.....5555555555555555555-----------
第6行.....-----------
这个文件的行数为:0
ubantu@ubantu-virtual-machine:~/shell$


我们看到最后显示文件行数为0,这明显是不对的,那么原因是什么?
	while read line 循环体中的变量,当退出循环后,会被销毁,所以若要二次使用循环体中的变量,则要采用其他办法。
	因为管道后的 while loop 是 sub shell,所以里面的变量自执行完成后,需要销毁。


demo:编写一个程序,读取一个带有IP地址的文件,该文件内容为:
	192.168.1.31
	192.168.1.32
	192.168.1.33
	....
	192.168.1.100
要球:(1)在9:00-18:00不允许访问QQ服务器(218.17.209.23)的80端口
	 (2)在非上述时间段允许访问QQ服务器的(218.17.209.23)的80端口
	 (3)公司内部网络上采用linux iptable nat功能,上网服务器为一台PC机
	 (4)添加防火墙规则的命令:
	 	/sbin/iptables -I FORWARD -p tcp -s 192.168.1.31 -d 218.17.209.23 --destination-port 80 -j DROP
	 (5)删除防火墙规则的命令:
	 	/sbin/iptables -D FORWARD -p tcp -s 192.168.1.31 -d 218.17.209.23 --destination-port 80 -j DROP
	 (6)定时任务采用crontab实现

shell中函数和数组的使用

函数

(1)linux shell 函数

  • 将一组命令集或语句形成一个可用的块,这些语句块称为函数

(2)shell 函数的组成

  • 函数名:函数名字,注意一个脚本中函数名要唯一,否则会引起调用函数紊乱。
  • 函数体:函数内部命令的集合,实现一个业务的功能

(3)shell 函数定义的格式

  • function 函数名() # function可以省略,注意 ( ) 内部不带任何参数。
  • {
  • 命令1
  • 命令2
  • ....
  • }

(4)函数定义及引用实例一:最简单的定义及引用

  1 #!/bin/sh
  2 
  3 function print_welcome()
  4 {
  5     echo "练习函数的定义及引用方法"
  6     echo "welecome,now time is `date`"
  7 }
  8 print_welcome

ubantu@ubantu-virtual-machine:~/shell$ sh func_1.sh 
练习函数的定义及引用方法
welecome,now time is Tue Mar  5 17:05:26 CST 2019
ubantu@ubantu-virtual-machine:~/shell$

(5)函数定义及引用实例二:向函数传递参数

  • 向函数传递参数就像在一般脚本中使用特殊变量 $1,$2,$3,…一样。
  • 函数取得所传参数后最好先在函数内重新设置变量保存所传的参数。
  1 #!/bin/sh
  2 
  3 sum()
  4 {
  5     echo "演练函数内部参数的传递方法"
  6     if [ $# -eq 2 ]
  7         then
  8             echo "符合函数要求的参数"
  9             a1=$1
 10             a2=$2
 11             let sum=a1+a2
 12         else
 13             echo "函数要求的参数个数不符,请重新输入"
 14     fi
 15     echo "$a1+$a2=$sum"
 16 }
 17 sum 10 90


ubantu@ubantu-virtual-machine:~/shell$ sh func_2.sh 
演练函数内部参数的传递方法
符合函数要求的参数
10+90=100
ubantu@ubantu-virtual-machine:~/shell$

(6)函数文件和脚本文件不在同一个文件中,该如何调用该函数。

  • 输入一个文件的路径,然后打印出这个文件的MD5摘要信息
  1 #!/bin/sh
  2 
  3 file_md5()
  4 {
  5     if [ $# -ne 1 ]
  6         then
  7             echo "函数参数有误,请重新输入一个参数"
  8         else
  9             filename=$1
 10             md5=$(md5sum $filename)
 11             echo "$filename 的md5摘要为:$md5"
 12     fi
 13 }   


  1 #!/bin/sh                                                                                                             
  2 
  3 . ./func_3.sh
  4 while [ 1 ]
  5     do
  6         read -p "请输入一个文件名:" filename
  7         file_md5 $filename
  8     done


ubantu@ubantu-virtual-machine:~/shell$ sh func_call.sh 
请输入一个文件名:func_1.sh
func_1.sh 的md5摘要为:51822847a3c837c5d90a4d86a822f942  func_1.sh
请输入一个文件名:func_2.sh
func_2.sh 的md5摘要为:26e72857e283d33635867d9bb7aa6e85  func_2.sh
请输入一个文件名:func_5.sh
md5sum: func_5.sh: No such file or directory
func_5.sh 的md5摘要为:
请输入一个文件名:

数组

(1)数组的定义

  • 在程序设计中,为了处理方便,把具有相同类型的若干变量按有序的形式组织起来,这些按序排列的同类数据元素的集合称为数组。
数组的定义
数组名=(元素1 元素2 元素n)    # 一对括号表示是数组,数组元素用 "空格" 符号分割开来
如:myarray=(1 2 3 4 5)    # 注意定义的方法,小括号、逗号

(2)数组常用操作

定义一个数组:myarray=(1 2 3 4 5)
读取数组的某一个元素:echo ${myarray[下标值]}     # 注意数组名称必须使用{}括起来,下标取值从0开始编号。
数组元素的赋值:myarray[下标值] = xxx
显示数组的所有元素:echo ${myarray[*]}
获得数组的长度(元素的个数):echo ${#myarray[@]}  或者 echo ${#myarray[*]}
删除一个数组元素:unset myarray[下标值]

(3)数组常用操作实践

  1 #!/bin/sh
  2 
  3 myarray=(1 2 3 4 5 6 7 8)
  4 
  5 echo "数组myarray初始的所有元素是:${myarray[*]}"
  6 echo "数组myarray第一个元素的值是myarray[0]:${myarray[0]}"
  7 echo "数组myarray的长度是:${#myarray[*]}"
  8 echo "数组myarray的长度是:${#myarray[@]}"
  9 
 10 # 修改第一个元素的值
 11 myarray[0]=100
 12 echo "修改第一个元素后,数组myarray的所有元素是:${myarray[*]}"
 13 
 14 # 删除myarray[0]
 15 unset myarray[0]
 16 echo "删除第一个元素后,数组myarrsy的所有元素是:${myarray[*]}"


ubantu@ubantu-virtual-machine:~/shell$ sh array_1.sh 
数组myarray初始的所有元素是:1 2 3 4 5 6 7 8
数组myarray第一个元素的值是myarray[0]:1
数组myarray的长度是:8
数组myarray的长度是:8
修改第一个元素后,数组myarray的所有元素是:100 2 3 4 5 6 7 8
删除第一个元素后,数组myarrsy的所有元素是:2 3 4 5 6 7 8
ubantu@ubantu-virtual-machine:~/shell$

(4)循环数组

  • ${myarray[*]}直接输出的所有元素的个数,对数组元素进行独立操作的时候,不太方便,所以有必要对其循环处理。
  1 #!/bin/sh
  2 
  3 myarray=(1 2 3 4 5 6 7)
  4 
  5 len=${#myarray[@]}                                                                                                    
  6 echo "数组长度:$len"
  7 echo "数组的元素依次为:"
  8 
  9 for ((i=0;$i<$len;i++))
 10 do  
 11     echo ${myarray[$i]}
 12     sleep 1
 13 done


ubantu@ubantu-virtual-machine:~/shell$ sh array_2.sh 
数组长度:7
数组的元素依次为:
1
2
3
4
5
6
7
ubantu@ubantu-virtual-machine:~/shell$

(5)数组长度的动态扩展

  • 有时候不知道数组中元素的个数,因此数组的长度事先是不知道的,因此,此时需要动态的扩展数组长度与空间。
  1 #!/bin/sh
  2 
  3 # 循环读取数组列表演示
  4 # 功能:在授权期内形成机器可信任的列表
  5 # 执行方法:脚本名 有效期 server1 server2 server3 server...
  6 
  7 # 获得所有数组参数存入
  8 list=(*)
  9 len=${#list[@]}
 10 
 11 # 第一个元素为有效期
 12 echo ${list[0]} > ./trustip.txt
 13 
 14 for ((i=1;$i<$len;i++))
 15     do
 16         echo "${list[$i]}" >> ./trustip.txt
 17     done
 18 
 19 # 显示这个时间可信任的IP列表
 20 cat ./trustip.txt


ubantu@ubantu-virtual-machine:~/shell$ sh array_3.sh 2019-03-05 192.168.17.23/24 192.168.17.24/24 192.168.17.25/24 192.168.17.26/24 
2019-03-05
192.168.17.23/24
192.168.17.24/24
192.168.17.25/24
192.168.17.26/24
ubantu@ubantu-virtual-machine:~/shell$ cat trustip.txt 
2019-03-05
192.168.17.23/24
192.168.17.24/24
192.168.17.25/24
192.168.17.26/24
ubantu@ubantu-virtual-machine:~/shell$

使用脚本完成网站数据的备份

(1)程序备份之前需要注意什么?

  • 程序运行的环境说明(操作系统、版本、内核、32/64、jdk、tomcat/webblogic/jboss、DB环境、是否有特殊环境要求?)
  • 程序存放路径?
  • 程序的配置文件是否在程序路径之中?
  • 程序是否有日志文件?
  • 程序运行日志需不需要备份

(2)数据库备份需要注意什么?

  • 数据库运行的环境(操作系统、版本、内核、32/64位、是否有特殊的环境要求?)
  • 核心的配置文件
  • 数据库运行日志是否需要保留?日志包括哪些?
  • 数据库运行binlog是否需要保留?
  • 数据库分配的用户账号是否需要保留?

(3)运行环境的备份需要注意什么?

  • 操作系统的自启动文件:/etc/rc.local
  • 语言设置配置文件:/etc/sysconfig/i18n
  • 环境变量配置文件:/etc/profile
  • 特殊的运行参数:进程最打开最大的文件数、用户开启的最大进程数、内核允许的断楼开启范围、防火墙状态连接表的尺寸等。

(4)定期备份

  • 计划任务使用crontab
  • 可以按照每分、每小时、每天、每周、每月进行定期备份
  • 如:
  • */5 * * * * /uer/local/qcloud/stargate/admin/start.sh
  • 第一列表示:分钟1~59,每分钟用*或者*/1表示
  • 第二列表示:小时1~23,(0表示0点)
  • 第三列表示:日期1~31
  • 第四列表示:月份1~12
  • 第五列表示:星期0~6(0表示星期日)
  • 第六列表示:要运行的命令
  • http://www.cnblogs.com/peida/archive/2013/01/08/2850483.html(更详细信息见)

(5)自动化备份脚本

  • 数据库的备份脚本
  1 #!/bin/sh                                                                                                                                                                                                    
  2 
  3 ## modified by xiaoming 2019-01-20
  4 
  5 # -------参数定义---------
  6 # 备份目录
  7 dst_mysql_back_dir="/app/mysql_backup"
  8 # 日期
  9 today=`date +%Y-%m-%d:%H:%M:%S`
 10 # 备份保存时间(单位天)
 11 datenum=5
 12 # -------定义结束---------
 13 
 14 read -p "请输入用户密码:" password
 15 
 16 # 列出需要备份的数据库名称
 17 for db_name in ctfd2 CTFd
 18     do
 19         # do not exist
 20         if test ! -e $dst_mysql_back_dir/$db_name/$db_name.$today
 21             then
 22                 echo "建立数据库 ${db_name}备份的文件夹...."
 23                 mkdir -p $dst_mysql_back_dir/$db_name/
 24                 chmod -R 777 $dst_mysql_back_dir/$db_name/
 25         fi
 26         echo "backup $db_name....."
 27         # /usr/bin/mysqldump -uroot -p$password -R $db_name > $dst_mysql_back_dir/$db_name/${db_name}${today}_pf.sql
 28         # 由于备份文件可能过大,我们可以使用gzip对其进行压缩处理
 29         /usr/bin/mysqldump -uroot -p$password $db_name | gzip > $dst_mysql_back_dir/$db_name/${db_name}${today}_pf.sql.zip
 30     done
 31         #  /usr/bin/mysqldump --opt -uroot -p$password -R $db_name --skip-lock-tables| gzip > $dst_mysql_back_dir/$db_name/${db_name}${today}_pf.sql.zip
 32         # --opt是quick,add-drop-table,add-locks,extended-insert,lock-tables几个参数的合称,一般都要使用,具体意思自行搜索;
 33         # 如果该数据库的用户没有分配 锁表 的权限,则备份会报错 when using LOCK TABLES 。那是因为mysqldump命令默认在导出时是要锁定表的,所以解决方式有两个。一个是给该用户开放 锁表 的权限;另一个是在命令中加
    上  --skip-lock-tables 这个参数
 34 
 35 # 将备份的数据库打包压缩
 36 # cd $dst_mysql_back_dir/$db_name
 37 # 解压缩
 38 # gunzip ${db_name}${today}_pf.sql.zip
 39 
 40 # 删除datenum天内的备份数据
 41 find $dst_mysql_back_dir -name "*.zip" -mtime +$datenum -type f | xargs rm -rf
 42 
 43 # 同上
 44 # find $dst_mysql_back_dir -name "*.zip" -mtime +$datenum -exec rm -rf {} \;


ubantu@ubantu-virtual-machine:~/shell$ sudo sh backup_db.sh 
请输入用户密码:123456
建立数据库 ctfd2备份的文件夹....
backup ctfd2.....
mysqldump: [Warning] Using a password on the command line interface can be insecure.
建立数据库 CTFd备份的文件夹....
backup CTFd.....
mysqldump: [Warning] Using a password on the command line interface can be insecure.
ubantu@ubantu-virtual-machine:~/shell$



ubantu@ubantu-virtual-machine:/app/mysql_backup$ pwd
/app/mysql_backup
ubantu@ubantu-virtual-machine:/app/mysql_backup$ ls
CTFd  ctfd2
ubantu@ubantu-virtual-machine:/app/mysql_backup$ cd CTFd/
ubantu@ubantu-virtual-machine:/app/mysql_backup/CTFd$ ls
CTFd2019-03-06:13-41-34_pf.sql.zip
ubantu@ubantu-virtual-machine:/app/mysql_backup/CTFd$ cd ../ctfd2/
ubantu@ubantu-virtual-machine:/app/mysql_backup/ctfd2$ ls
ctfd22019-03-06:13-41-34_pf.sql.zip
ubantu@ubantu-virtual-machine:/app/mysql_backup/ctfd2$
  • 使用crontab 建立定时任务
ubantu@ubantu-virtual-machine:~$ crontab -e
no crontab for ubuntu - using an empty one

Select an editor.  To change later, run 'select-editor'.
  1. /bin/ed
  2. /bin/nano        <---- easiest
  3. /usr/bin/vim.basic
  4. /usr/bin/vim.tiny

Choose 1-4 [2]: 3
# 第一次使用该命令来创建定时任务时会让你选择一个编辑器:一般大都使用第三个 vim 编辑器


  1 # Edit this file to introduce tasks to be run by cron.                                                                                                                                                       
  2 # 
  3 # Each task to run has to be defined through a single line
  4 # indicating with different fields when the task will be run
  5 # and what command to run for the task
  6 # 
  7 # To define the time you can provide concrete values for
  8 # minute (m), hour (h), day of month (dom), month (mon),
  9 # and day of week (dow) or use '*' in these fields (for 'any').# 
 10 # Notice that tasks will be started based on the cron's system
 11 # daemon's notion of time and timezones.
 12 # 
 13 # Output of the crontab jobs (including errors) is sent through
 14 # email to the user the crontab file belongs to (unless redirected).
 15 # 
 16 # For example, you can run a backup of all your user accounts
 17 # at 5 a.m every week with:
 18 # 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
 19 # 
 20 # For more information see the manual pages of crontab(5) and cron(8)
 21 # 
 22 # m h  dom mon dow   command
 23 # 每天早上 5:00am 执行(根据项目实际情况来设定)
 24 00 05 *   * * /bin/sh /home/ubantu/shell/backup_db.sh
 25 



查看任务是否创建成功

ubantu@ubantu-virtual-machine:~$ crontab -l
# Edit this file to introduce tasks to be run by cron.
# 
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
# 
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').# 
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
# 
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
# 
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
# 
# For more information see the manual pages of crontab(5) and cron(8)
# 
# m h  dom mon dow   command
# 每天早上 5:00am 执行(根据项目实际情况来设定)
00 05 * * * /bin/sh /home/ubantu/shell/backup_db.sh

ubantu@ubantu-virtual-machine:~$

  • 程序和环境的备份脚本
注意几个要素的备份

(1)运行环境的备份
(2)应用程序的备份
(3)tomcat的备份
(4)apache的备份

使用脚本监控网站的核心服务

(1)监控的内容

  • 监控web服务器的状态
  • 监控数据库服务器的工作状态
  • 监控网络的工作状态
  • 监控服务器的资源使用状态
  • 监控其他需要关注的服务状态

(2)通知和报警机制

  • 邮件报警
  • 短信报警
  • 页面状态报警

(3)监控任务的部署

  • 监控网络的运行情况:定期获取监控服务器到被监控服务器的平均响应时间及丢包率,如果这两个指标超过我们设定的阈值,将触发报警。

你可能感兴趣的:(Shell编程)