shell中的脚本程序(三)(数据库备份,论坛自动部署,自动连接别的虚拟机)

1.编写一个shell脚本自动连接其他的虚拟机

[root@shenzhen mnt]# vim file1.sh	##编辑脚本
[root@shenzhen mnt]# sh file1.sh 172.25.254.228 redhat	##尝试执行脚本并写入想要连接的ip和密码
[root@xiaan ~]# exit	##退出连接的虚拟机

在这里插入图片描述在这里插入图片描述
脚本中写入的内容如下:

#!/bin/bash	##运行环境可以使用which查看
/usr/bin/expect <<EOF	##在EOF内的命令都会被定义在/usr/bin/expect中
spawn ssh root@$1	
expect {
"yes/no" { send "yes\r";exp_continue }
"password" { send "$2\r" }
}
expect eof 
EOF

在这里插入图片描述

说明:
在执行过程中可能会出现以下情况,因为无法保留expect的交互界面,所以无法在连接的虚拟机中输入命令,而且其会自动退出,如下所示:

<1>在连接的虚拟机中输入的命令会进行延续

[root@shenzhen mnt]# sh file1.sh 172.25.254.228 redhat
[root@xiaan ~]# ls
[root@shenzhen mnt]# ls

在这里插入图片描述
<2>在连接的虚拟机中输入的命令会进行延续

[root@shenzhen mnt]# sh file1.sh 172.25.254.228 redhat
[root@xiaan ~]# exit
[root@shenzhen mnt]# exit

在这里插入图片描述
<3>在连接的虚拟机中如果不输入任何命令,会自动退出

[root@shenzhen mnt]# sh file1.sh 172.25.254.228 redhat	
[root@xiaan ~]# [root@shenzhen mnt]# 

在这里插入图片描述

分析:
1.#!/bin/bash这一行告诉操作系统脚本里的代码使用哪一个shell来执行,这里的expect其实和linux下的bash,windows下的cmd是一类东西
2.set timeout 30 指设置超时时间
3.spawn是进入expect环境后才可以执行的expect内部命令,如果没有装expect或者直接在默认的shell下执行是找不到spawn命令的。所以不要用“which spawn”之类的命令去赵spawn命令。好比windows里的dir就是一个内部命令,这个命令由shell自带,你无法找到一个dir.com或dir.exe可执行文件。它只要的功能就是给ssh运行进程加个壳,用来传递交互指令
4.expect “password:”:这里的expect也是expect的一个内部命令,expect的shell命令和内部命令是一样的,但不是一个功能。这个命令的意思是判断上次输出结果里是否包含”password:“色字符串,如果有则立即返回,否则就等待一段时间后返回,这里等待时间就是前面的超时设置
5.send “ispass\r”:这里就是执行交互动作,与手工输入密码的动作等效,如果出现异常等待可以查看一下
6.interact:执行完成之后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了,如果没有这一句登陆完成后会自动退出,而不是留在远程终端上
7.expext在做系统管理时,我们很多时候需要输入密码,例如:连接ssh/ftp,当我们使用expect时,就能代替我们实现与终端的交互,不用守在电脑旁边输出密码,或是根据系统的输出再运行相应的命令。
8.expect是一种脚本语言
9.一个脚本的运行环境只能是一个(如#!/bin/bash)
10.在EOF内的命令都会被定义在/usr/bin/expect中
11.可以使用$1,因为运行环境是shell,最终的结果会倒到expect中
12.不会保留环境,因为会自动退出
13.shell和expect的混合之后是不能用的,运行成功后也无法使用,因为无法保留expect的交互界面
14.批量执行命令的时候用shell和expect结合

2.编写一个脚本使其可以自动连接别的虚拟机,并且将成功连接好的虚拟机的主机名保存到一个某一个为文件中

[root@shenzhen mnt]# vim auto_ssh.sh	##编写脚本
[root@shenzhen mnt]# sh auto_ssh.sh heihei	##执行脚本并将其可以连接成功的的ip的主机名放至名称为heihei的文件中
[root@shenzhen mnt]# vim heihei		##查看文件heihei中是否有连接成功的主机名

在这里插入图片描述
脚本中的内容如下:

#!/bin/bash
Auto_ssh()
{
/usr/bin/expect <<EOF
spawn ssh [email protected].$1 $2
expect {
"yes/no" { send "yes\r";exp_continue }
"password" { send "redhat\r" }
}
expect eof 
EOF
}
for IP_ID in {225..229}		##设置的ip范围为172.25.254.225-172.25.254.229
do
        ping -c1 -w1 172.25.254.$IP_ID &> /dev/null	##尝试连接ip并将其可能出现的报错或其他提示信息放至垃圾箱中
        if
        [ "$?" -eq "0" ]	##如果命令的退出值等于0
        then
                Auto_ssh $IP_ID hostname | grep "password:" -A1 | tail -n 1 >>$1	##调用函数Auto_ssh,并且“$IP_ID”为函数中的第一串字符(即$1),hostname为函数的第二串字符(即$2);-A1表示下一行;并将最后一行内容放到执行脚本时写的文件中
        fi
done

在这里插入图片描述
运行后的结果如下:
在这里插入图片描述

注意:
1.脚本中实现了自动登陆,自动检测
2.脚本中一个是函数的$1,一个是脚本的$1

3.编写一个shell脚本使论坛自动部署

要求:
服务自动部署示例:
执行脚本 lamp.sh
脚本执行后部署好论坛,并设定apache的网络接口为8080
实验:
首先查看/mnt目录下是否有论坛的安装包,并编写脚本lamp.sh

[root@shenzhen mnt]# ls
[root@shenzhen mnt]# vim lamp.sh

在这里插入图片描述
脚本的内容如下:

#!/bin/bash
unzip /mnt/Discuz_X3.2_SC_UTF8.zip -d /tmp &> /dev/null	##解压论坛安装包并将其放至/tmp目录下
Install_APP()	##设置安装过程为一个函数
{	
yum list $1 &> /dev/null	##查看yum列表是否有其软件包
[ "$?" = "0" ]&&{	##如果退出值是0的话说明系统有该软件,进行以下操作
        yum install $1 -y &> /dev/null	##安装其软件
}||{
        echo $1 is can not find from yumstore	##如果退出值不是0的话进行报错,说明输入的软件名出现了错误
        exit 1
}
}
for APP in httpd mariadb-server.x86_64 php php-mysql	##将要安装的软件写进for循环中
do
        Install_APP $APP	##执行函数
done
cp -r /tmp/upload /var/www/html	##将upload移至共享目录下
#chmod 777 -R /var/www/html/upload	##更改upload下所有文件的权限为777,不太安全,所以不建议
chmod 777 -R /var/www/html/upload/config	##依次更改安装说明中需要更改的目录的权限,-R表示递归
chmod 777 -R /var/www/html/upload/data
chmod 777 -R /var/www/html/upload/uc*
sed "/^Listen/cListen 8080" /etc/httpd/conf/httpd.conf -i /etc/httpd/conf/httpd.conf	##改变httpd的端口为8080,“^"表示以什么开头
systemctl restart httpd mariadb	##设置完毕后,重新启动httpd服务和mariadb服务
systemctl stop firewalld	##保险起见,可关闭防火墙
setenforce 0	##设置其selinux状态为Permission
firefox http://172.25.254.166:8080/upload	##打开防火墙,注意要写入8080,因为端口号已经发生了改变

在这里插入图片描述
测试,运行脚本后,会发现可以成功安装

[root@shenzhen mnt]# sh lamp.sh

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.数据库备份

执行auto.sh westos(数据库密码)
脚本执行后会备份数据库中的所有库到/mnt/mysqldump目录中
备份文件名称为“库名称.sql”,当此文件存在时报错并询问动作
输入“S”跳出备份,当输入“B”时备份“库名称.sql”文件为“库名称_backup.sql“,当输入”O“时,覆盖源文件

分解讲解:
<1>编写脚本,在脚本中写入其如果没有开启数据库服务,则会出现报错,并进行测试

[root@shenzhen mnt]# vim auto.sh

脚本中的内容如下:

#!/bin/bash
mysql -uroot -p$1 -e "show databases;" &> /dev/null
[ "$?" != 0 ] && {
        echo ERROR:connect databases failed
        exit 1
}

在这里插入图片描述
测试:
没有开启mariabd服务时,会出现脚本中的报错信息

[root@shenzhen mnt]# sh auto.sh westos

在这里插入图片描述
开启mariadb服务后,再次执行脚本,没有出现报错

[root@shenzhen mnt]# systemctl start mariadb
[root@shenzhen mnt]# sh auto.sh westos

在这里插入图片描述
<2>编写脚本查看是否输入密码,如果输入,则正常进行,如果没有输入,会出现报错

[root@shenzhen mnt]# vim auto.sh

脚本中的内容如下:

#!/bin/bash
[ -z "$1" ] && {
        echo please input password for databases
        exit 2
        }
mysql -uroot -p$1 -e "show databases;" &> /dev/null
[ "$?" != 0 ] && {
        echo ERROR:connect databases failed
        exit 1
}

在这里插入图片描述
没有输入密码时,执行脚本,会出现脚本中的报错信息,查看其退出值,会发现是2,说明没有写密码

[root@shenzhen mnt]# sh auto.sh 
[root@shenzhen mnt]# echo $?

在这里插入图片描述
输入密码后,不会报错,查看其退出值,会发现是1

[root@shenzhen mnt]# sh auto.sh westos
[root@shenzhen mnt]# echo $?

在这里插入图片描述
<3>在脚本中首先查看是否存在/mnt/mysqldump目录,如果有,先删除目录并将重新创建/mnt/mysqldump目录。然后在mysql中写入内容(使用EOF重定向即可)

[root@shenzhen mnt]# vim auto.sh

脚本中的内容如下:

#!/bin/bash
[ -z "$1" ] && {
        echo please input password for databases
        exit 2
        }
mysql -uroot -p$1 -e "show databases;" &> /dev/null
[ "$?" != 0 ] && {
        echo ERROR:connect databases failed
        exit 1
}
[ ! -d "/mnt/mysqldump" ] && {
        rm -rf /mnt/mysqldump
        mkdir -p /mnt/mysqldump
}
for DATABASE in `mysql -uroot -p$1 <<EOF | grep -E "Database|schema$" -v
show databases;
EOF`
do
echo $DATABASE
done

在这里插入图片描述
运行脚本并输入密码,发现会输出自己想要的数据库

[root@shenzhen mnt]# sh auto.sh westos

在这里插入图片描述
查看/mnt下是否有新建的mysqldump目录,并查看其下是否有内容

[root@shenzhen mnt]# ls
[root@shenzhen mnt]# cd mysqldump
[root@shenzhen mysqldump]# ls

在这里插入图片描述
<4>编写完整的脚本(添加题目中要求的选项并设置函数方便查使用

[root@shenzhen mnt]# vim auto.sh

脚本中的内容如下:

#!/bin/bash
DB_BACKUP()
{
                read -p "Please input action: " ACTION
                case $ACTION in
                        S)
                        ;;
                        B)
                        mv /mnt/mysqldump/${DATABASE}.sql /mnt/mysqldump/${DATABASE}_backup.sql
                        mysqldump -uroot -p$1 $DATABASE > /mnt/mysqldump/${DATABASE}.sql
                        ;;
                        O)
                        mysqldump -uroot -p$1 $DATABASE > /mnt/mysqldump/${DATABASE}.sql
                        ;;
                        *)
                        echo error action
                        DB_BACKUP
                esac
}
[ -z "$1" ] && {
        echo please input password for databases
        exit 2
        }
mysql -uroot -p$1 -e "show databases;" &> /dev/null
[ "$?" != 0 ] && {
        echo ERROR:connect databases failed
        exit 1
}
[ ! -d "/mnt/mysqldump" ] && {
        rm -rf /mnt/mysqldump
        mkdir -p /mnt/mysqldump
}
for DATABASE in `mysql -uroot -p$1 <<EOF | grep -E "Database|schema$" -v
show databases;
EOF`
do
        if
        [ -e "/mnt/mysqldump/${DATABASE}.sql" ]
        then
                echo "${DATABASE}.sql is exist and what do you want?
        [S]kip [B]ack [O]verwrite"
        DB_BACKUP $1
        fi
        mysqldump -uroot -p$1 $DATABASE > /mnt/mysqldump/${DATABASE}.sql
done

在这里插入图片描述
测试:
第一次运行脚本:

[root@shenzhen mnt]# sh auto.sh westos	##运行脚本并输入数据库的密码
[root@shenzhen mnt]# ls		##查看/mnt目录下是否有新生成的mysqldump
[root@shenzhen mnt]# cd mysqldump	##进入mysqldump目录
[root@shenzhen mysqldump]# ls	##查看目录下是否有文件且文件名都加了后缀.sql

在这里插入图片描述
第二次运行脚本(即mysqldump中已经存在了.sql文件,所以再次执行脚本时会出现选项):

[root@shenzhen mnt]# sh auto.sh westos

在这里插入图片描述

报错:
如果出现以下错误(mysqldump: Got error: 1049: “Unknown database ‘Database’” ),原因是因为书写格式有错误(即可能将 grep -E “Database|schema &quot; v g r e p E &quot; D a t a b a s e s c h e m a &quot; -v书写成 grep -E &quot;Database | schema ” -v)
出现的报错信息:
在这里插入图片描述
脚本中的错误写法:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_39376481/article/details/88753031
今日推荐