[转帖]自动化运维:一键自动化脚本-shell

自动化,一键,脚本,shell · 浏览次数 : 0

小编点评

内容生成时需要带简单的排版,以下内容生成时需要带简单的排版: 1. **使用**符号将代码块分组,方便阅读和理解。 2. **使用**符号将代码块嵌套,方便控制代码块的顺序。 3. **使用**符号将代码块标签,方便代码块的分类。 4. **使用**符号将代码块格式,方便代码块的清晰。 5. **使用**符号将代码块标题,方便代码块的清晰。 6. **使用**符号将代码块格式,方便代码块的清晰。

正文

https://www.cnblogs.com/luoahong/articles/8456203.html

 

shell函数

1、分别在服务器和客户端上创建www用户

1
2
useradd www
id wwww
  1. 所有的web服务,都应该使用普通用户,所有的web服务都不应该监听80端口,除非负载均衡。8080
  2. 普通用户能启动80端口吗?通过和科技,比如给命令设置suid
  3. 生产指定uid

2、保证www用户登录其他的节点都不要输入密码

服务器端:

1
2
3
4
5
6
7
8
9
10
[root@node1 ~]# useradd www
[root@node1 ~]# id www
[root@node1 ~]# passwd www
[root@node1 ~]# su www
[root@node1 ~]# cd /home/www/
[www@node1 ~]$ ssh-copy-id -i .ssh/id_rsa.pub www@172.16.14.116
[www@node1 ~]$ ssh 172.16.14.116
Last failed login: Sat Jan 13 09:56:41 CST 2018 from 172.16.14.115 on ssh:notty
There were 3 failed login attempts since the last successful login.
Last login: Sat Jan 13 09:23:02 2018

客户端:

1
2
3
4
5
6
7
8
9
10
[root@node2 ~]# useradd www
[root@node2 ~]# id www
[root@node2 ~]# passwd www
[root@node2 ~]# su www
[root@node2 ~]# cd /home/www/
[www@node2 ~]$ ssh-copy-id -i .ssh/id_rsa.pub www@172.16.14.115
[www@node2 ~]$ ssh 172.16.14.115
Last failed login: Sat Jan 13 09:56:41 CST 2018 from 172.16.14.115 on ssh:notty
There were 3 failed login attempts since the last successful login.
Last login: Sat Jan 13 09:23:02 2018

3、写一个复杂的脚本

先把框架写出来,使用echo来测试框架的流程是否正确

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/bin/bash
 
    # Shell Env
    SHELL_NAME="deploy.sh"
    SHELL_DIR="/home/www"
    SHELL_LOG="{SHELL_DIR}/${SHELL_NAME}.log"
 
    # Code Env
    CODE_DIR="/deploy/code/deploy/"
    TMP_DIR="/deploy/config"
    TAR_DIR="/deploy/tar"
    LOCK_FILE="/tmp/deploy.lock"
 
 
    usage(){
            echo $"Usage: $0[ deploy|rollback]"
    }
 
    shell_lock(){
            touch ${LOCK_FILE}
    }
 
    shell_unlock(){
            rm -f  ${LOCK_FILE}
    }
 
    code_get(){
            echo code_get;
            sleep 2;
    }
 
    code_build(){
            echo code_build;
            sleep 2;
    }
 
    code_config(){
            echo code_config;
            sleep 2;
 
    }
 
    code_tar(){
            echo code_tar;
            sleep 2;
    }
 
    code_scp(){
            echo code_scp;
            sleep 1;
 
    }
 
    cluster_node_remove(){
            echo cluster_node_remove;
            sleep 1;
 
    }
 
    code_deploy(){
            echo code_deploy;
    }
 
    config_diff(){
            echo config__diff;
    }
 
    code_test(){
            echo code_test;
    }
 
    cluster_node_in(){
            echo cluster_node_in;
    }
 
    main(){
       if [ -f $LOCK_FILE ];then
             echo "Deploy is running"&& exit;
       fi
       DEPLOY_METHOD=$1
       case $DEPLOY_METHOD in
          deploy)
                   shell_lock;
                   code_get;
                   code_build;
                   code_config;
                   code_tar;
                   code_scp;
                   cluster_node_remove;
                   code_deploy;
                   config_diff;
                   code_test;
                   cluster_node_in;
                   shell_unlock;
                   ;;
          rollback)
                   shell_lock;
                   rollback;
                   shell_unlock;
                   ;;
           *)
                   usage;
        esac
    }

4、什么也没提示?在末尾添加 man $1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
main(){
   DEPLOY_METHOD=$1
   case $DEPLOY_METHOD in
      deploy)
               shell_lock;
               ;;
      rollback)
               shell_lock;
               ;;
       *)
               usage;
    esac
}
main $1

本节小结:

1、凡是不记录日志的脚本就是耍流氓

2、这个脚本能不能多个人同时执行?

1、最好不要,但是运维团队有很多人,我如何知道别人有没有执行?

答:我写一个锁文件


1、锁文件放那?

答:放在/tmp/deploy.lock" 因为放在下www没有权限

2、系统的锁文件放哪里?
1
/var/run/lock

3、看不出来?


答:sleep60秒

 

4、不是脚本的$1匙函数的$1

 5、在两台电脑上都要用到所以定义为变量

 

2、功能实现

1、日志函数

1
2
3
4
5
6
7
8
9
10
11
#Date/Time Veriables
LOG_DATE='date "+%Y-%m-%d"'
LOG_TIME='date "+%H-%M-%S"'
 
CDATE=$(date "+%Y-%m-%d")
CTIME=$(date "+%H-%M-%S")
....
writelog(){
    LOGINFO=$1
    echo "${CDATE} ${CTIME}: ${SHELL_NAME}: ${LOGINFO}" >> ${SHELL_LOG}
}

 

1、希望在很多地方记录日志

echo一行,写到一个文件里,记日志还要记时间

方法1:写一个日志的函数,每次调用这个函数

方法2:在每一个函数里写一个echo,然后写在那个位置,还要记时间

2、日志函数的好处?

  1. 这个函数可以复制,以后写别的脚本直接改改就可以
  2. 每一个函数里都写一个函数

3、shell是如何解析的?

从上倒下逐行执行

4、遇到函数怎么办?

先加载不执行

5、日志的内容从哪来?

从参数来:$1

6、脚本名称:

当前日期+脚本名称+日志内容 

难保你以后会写在一起所以要区分开

7、时间是不是不能变?

我就不需要它变:

1、打包的时候不能变,包里有有日期和时间包名不能变
2、打包如何命名?

是scp时间不对,包就找不着了

1
2
LOG_DATE='date "+%Y-%m-%d"'
LOG_TIME='date "+%H-%M-%S"'
  1. 一个是让执行 记日志用的
  2. 一个不让执行 做别的用处
  3. 已经执行了,在后面就不变了

2、get代码函数

1
2
3
4
5
6
7
8
9
10
11
12
13
#Code Env
PRO_NAME="web-demo"
CODE_DIR="/deploy/code/web-demo"
CONFIG_DIR="/deploy/config/web-demo"
TMP_DIR="/deploy/tmp"
LOCK_FILE="/tmp/deploy.lock"
.......
code_get(){
        writelog "code_get";
        cd $CODE_DIR && echo "git pull"
        cp -r ${CODE_DIR} ${TMP_DIR}/
        API_VERL=$(git show |grep commit | cut -d ' ' -f2)
        API_VER=$(echo ${API_VERL:0:6})

1、代码应该放在那?

放在CODE_DIR="/deploy/code/web-demo"目录下

2、配置文件能直接放CODE_DIR这吗?

不能,专门用于git更新的目录
如果你把文件拷贝到这里,所有的包里面都有这个文件
一不小心多放了一个,那个可不会pull

3、怎样区分是仓库的还是我copy过来的?

也能区分 看git状态,本地状态 正常区分不了
更新完之后copy走,放着也行出故障了你就知道是什么意思了!

4、复制到哪?

TMP_DIR

5、为什么对web-demo要重命名?

  1. 复制过去要重命名
  2. 打包的时候还要重命名
  3. 每次都覆盖那就乱了

6、要怎样重命名?

时间+版本号?

1、svn怎样获取版本号?
2、git如何获取版本号?

API_VERL=$(git show |grep commit | cut -d ' ' -f2)

3、配置文件函数

1
2
3
4
5
6
7
8
9
10
11
12
13
#Code Env
PRO_NAME="web-demo"
CODE_DIR="/deploy/code/web-demo"
CONFIG_DIR="/deploy/config/web-demo"
TMP_DIR="/deploy/tmp"
LOCK_FILE="/tmp/deploy.lock"
......
code_config(){
        writelog "code_config"
        /bin/cp -r ${CONFIG_DIR}/base/* ${TMP_DIR}/"${PRO_NAME}"
        PKG_NAME="${PKG_NAME}"_"$API_VER"_"${CDATE}-${CTIME}"
        cd ${TMP_DIR} && mv ${PKG_NAME} ${PKG_NAME}}
}

1、我是哪个项目的配置文件?

1
CONFIG_DIR="/deploy/config/web-demo"

2、为什么加/bin/cp -r?

1
/bin/cp -r ${CONFIG_DIR}/base/* ${TMP_DIR}/"${PRO_NAME}"

1、有可能我文件下还有目录呢!
2、我拷贝的那个目录下有那个配置文件

有一测试有权限,犯二提交了一个相同的配置文件 你没有覆盖连到测试库了
大家打开的都是测试的库
开发可以错,测试可以错,运维不可以错 为什么你上线的时候也没发现?
每一个小细节都是有意义不是瞎写

3、复制和打包可以放在一个里面,为什么把包名做成一个变量?

  1. 很多地方都用到
  2. 包名很长
  3. 包名本身也包含变量

4、为什么要全写成变量

因为不只为这一个脚本,写别的脚本改改就可以啦!

5、为什么tmp需要定期进行清理?

部署几个月可以,时间久磁盘就满了

有时间了就好删除了,解决了各种方式
只有版本号你怎样删?把15年的全删了

4、打包函数

1
2
3
4
5
code_tar(){
        writelog "code_tar"
        cd ${TMP_DIR} && tar czf ${PKG_NAME}.tar.gz ${PKG_NAME}
        writelog "${PKG_NAME}.tar.gz"
}

1、为什么要写&&?

函数和函数之间可不知道上一级目录是什么!!!
不单独搞一行,如果目录不存在进去了可能不是你想要的

5、scp到目标服务器

1
2
3
4
5
6
7
code_scp(){
        writelog "code_scp"
        for node in $PRE_LIST;do
        for node in $GROUP1_LIST;do
                scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot/
        done
}

1、统一用一个包的好处?

完全可以写一个for循环
我要加机器 在列表里加一行
减机器 在列表里减去一行
标准化的好处

2、为什么不能直接写在/opt?

  1. 没有权限
  2. 在opt创建一个/opt/webroot/复制到这

6、部署函数

1
2
3
4
5
6
7
8
group1_deploy(){
        writelog "remove from cluster"
        for node in $GROUP1_LIST;do
            ssh $node "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz"
            ssh $node "rm -f /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
        done
        scp ${CONFIG_DIR}/other/192.168.56.12.crontab.xml 192.168.56.12:/webroot/web-demo/crontab.xml
}

1、项目之间应该保持独立才对

2、你的目录放在那?

所有生产的web服务器的家目录都写在/webroot的项目名称下

3、为什么先创建软链接然后在复制差异文件?

路径写的少,要不然你写到解压后的路径下
如果没有生成我就不复制
生产部署的时候,没部署成功结果scp复制过去了


4、第一次手动创建一个因为 没有会报错。

1
2
3
4
su -www
cd /webroot/
touch web-demo
用salt就要先touch文件

5、&&不能去掉,因为以后部署时候我要先删除才能软链接

6、一个软连接连一毫秒都花不了

3、脚本扩展

1、每个节点上各装一个apache

1
yum install httpd -y

2、修改配置文件以下两处

1
vim /etc/httpd/conf/httpd.conf

1、测试函数

1
2
3
4
5
6
7
8
url_test(){
        URL=$1
        curl -s --head $URL |grep '200 ok'
        if [ $? -ne 0 ];then
                shell_unlock;
                echo "test error" && exit;
        fi
}

1、测试一能访问就加入集群不能访问就移除集群

2、部署一个测一个通了才能加到集群里

生产是一个组一个组测试
并行和串行相结合
每一个组一个预生产节点
直接部署第二个节点

2、主函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
main(){
    if [ -f $LOCK_FILE ]; then
        echo "Deploy is running" && exit;
    fi
    DEPLOY_METHOD=$1
    ROLLBACK_VER=$2
    case $DEPLOY_METHOD in
        deploy)
                shell_lock;
                code_get;
                code_build;
                code_config;
                code_tar;
                code_scp;
                pre_deploy;
                pre_test;
                group1_deploy;
                group1_test;
                shell_unlock;
                ;;
        rollback)
                shell_lock;
                rollback $ROLLBACK_VER;
                shell_unlock;
                ;;
        *)
                usage;
    esac
}
main $1 $2

1、先判断是否有文件,存在说明有人在执行直接退出

2、你是要部署还是要回滚,要是是部署先锁住脚本

从git上获取文件
进行编译
复制配置文件进去
打包并重命名
scp到所有机器(不分组)
晚上要做一个不算停机维护,所有机器都需要同时重启
涉及到数据一致性
组一部署集群
测试组一集群

4、秒级回滚

 


在某个地方记住上一个版本是啥,部署把版本写在一个文件里(紧急回滚的一个函数),然后读这个文件

1
2
3
4
5
6
7
8
9
10
11
12
13
rollback(){
if [ -z $1 ];then
    shell_unlock;
    echo "please input rollback version" && exit;
fi
    case $1 in
        list)
                ls -l /opt/webroot/*.tar.gz
                ;;
        *)
                rollback_fun $1
    esac
}
  1. 部署还是回滚$1,回滚到那个版本是$2

  2. 传list的我就列出来,不传我就回滚

  3. 我可以只部署预生产,我部署机肯定有我其他的节点没有

1
2
3
4
rollback_fun(){
        for node in $ROLLBACK_LIST;do
        ssh $node "rm -f /webroot/web-demo && ln -s /opt/webroot/$1 /webroot/web-demo"
        done

1、如果list存在我就执行,不存在就结束for循环
2、远程ssh执行命令,引起来才能当成一个,因为中间还有空格

3、脚本的$2传到回滚函数里就是$1

 

5、gitlab部署和回滚


安装gitlab私有仓库,地址见运维社区gitlab

1、登陆修改root密码


2、备份:每天备份每小时也行

越频繁越好
分布式每个人的本地都有

6、完整脚本构造

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#!/bin/bash
 
#Dir List
mkdir -p /deploy/code/web-demo
mkdir -p /deploy/config/web-demo/base
mkdir -p /deploy/config/web-demo/other
mkdir -p /deploy/tar
mkdir -p /deploy/tmp
mkdir -p /opt/webroot
mkdir /webroot
chown -R www.www /deploy
chown -R www.www /opt/webroot
chown -R www.www /webroot
 
#Node List
PRE_LIST="192.168.56.11"
GROUP1_LIST="192.168.56.12"
ROLLBACK_LIST="192.168.56.11 192.168.56.12"
 
#Date/Time Veriables
LOG_DATE='date "+%Y-%m-%d"'
LOG_TIME='date "+%H-%M-%S"'
 
CDATE=$(date "+%Y-%m-%d")
CTIME=$(date "+%H-%M-%S")
 
#Shell Env
SHELL_NAME="deploy_all.sh"
SHELL_DIR="/home/www/"
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"
 
#Code Env
PRO_NAME="web-demo"
CODE_DIR="/deploy/code/web-demo"
CONFIG_DIR="/deploy/config/web-demo"
TMP_DIR="/deploy/tmp"
LOCK_FILE="/tmp/deploy.lock"
 
usage(){
        echo $"Usage: $0{deploy|rollback[ list|version ]}"
}
 
writelog(){
    LOGINFO=$1
    echo "${CDATE} ${CTIME}: ${SHELL_NAME}: ${LOGINFO}" >> ${SHELL_LOG}
}
 
shell_lock(){
        touch ${LOCK_FILE}
}
 
url_test(){
        URL=$1
        curl -s --head $URL |grep '200 ok'
        if [ $? -ne 0 ];then
                shell_unlock;
                echo "test error" && exit;
        fi
}
 
shell_unlock(){
        rm -f ${LOCK_FILE}
}
 
code_get(){
        writelog "code_get";
        cd $CODE_DIR && echo "git pull"
        cp -r ${CODE_DIR} ${TMP_DIR}/
        API_VERL=$(git show |grep commit | cut -d ' ' -f2)
        API_VER=$(echo ${API_VERL:0:6})
}
 
code_build(){
        echo code_Build
}
 
code_config(){
        writelog "code_config"
        /bin/cp -r ${CONFIG_DIR}/base/* ${TMP_DIR}/"${PRO_NAME}"
        PKG_NAME="${PKG_NAME}"_"$API_VER"_"${CDATE}-${CTIME}"
        cd ${TMP_DIR} && mv ${PKG_NAME} ${PKG_NAME}}
}
 
code_tar(){
        writelog "code_tar"
        cd ${TMP_DIR} && tar czf ${PKG_NAME}.tar.gz ${PKG_NAME}
        writelog "${PKG_NAME}.tar.gz"
}
 
code_scp(){
        writelog "code_scp"
        for node in $PRE_LIST;do
        for node in $GROUP1_LIST;do
                scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot/
        done
}
 
pre_deploy(){
        writelog "remove from cluster"
        ssh $PRE_LIST "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz"
        ssh $PRE_LIST "rm -f /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
}
 
pre_test(){
        url_test "http://${PRE_LIST}/index.html"
        echo "add to cluster"
}
 
group1_deploy(){
        writelog "remove from cluster"
        for node in $GROUP1_LIST;do
            ssh $node "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz"
            ssh $node "rm -f /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
        done
        scp ${CONFIG_DIR}/other/192.168.56.12.crontab.xml 192.168.56.12:/webroot/web-demo/crontab.xml
}
 
group1_test(){
        url_test "http://192.168.56.12/index.html"
        echo "add to cluster"
}
 
rollback_fun(){
        for node in $ROLLBACK_LIST;do
        ssh $node "rm -f /webroot/web-demo && ln -s /opt/webroot/$1 /webroot/web-demo"
        done
}
 
rollback(){
if [ -z $1 ];then
    shell_unlock;
    echo "please input rollback version" && exit;
fi
    case $1 in
        list)
                ls -l /opt/webroot/*.tar.gz
                ;;
        *)
                rollback_fun $1
    esac
}
 
main(){
    if [ -f $LOCK_FILE ]; then
        echo "Deploy is running" && exit;
    fi
    DEPLOY_METHOD=$1
    ROLLBACK_VER=$2
    case $DEPLOY_METHOD in
        deploy)
                shell_lock;
                code_get;
                code_build;
                code_config;
                code_tar;
                code_scp;
                pre_deploy;
                pre_test;
                group1_deploy;
                group1_test;
                shell_unlock;
                ;;
        rollback)
                shell_lock;
                rollback $ROLLBACK_VER;
                shell_unlock;
                ;;
        *)
                usage;
    esac
}
main $1 $2

转载地址:https://github.com/unixhot/deploy-shell

作者:罗阿红 出处:http://www.cnblogs.com/luoahong/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。

与[转帖]自动化运维:一键自动化脚本-shell相似的内容:

[转帖]自动化运维:一键自动化脚本-shell

https://www.cnblogs.com/luoahong/articles/8456203.html shell函数 1、分别在服务器和客户端上创建www用户 1 2 useradd www id wwww 所有的web服务,都应该使用普通用户,所有的web服务都不应该监听80端口,除非负载

[转帖]别让运维太忙,一文详解 Ansible 的自动化运维

https://zhuanlan.zhihu.com/p/270655214 一、Ansible 概述 Ansible 是近年来越来越火的一款开源运维自动化工具,通过Ansible可以实现运维自动化,提高运维工程师的工作效率,减少人为失误。 Ansible 通过本身集成的非常丰富的模块可以实现各种管

[转帖]收藏!系统运维中网络知识实用总结

http://blog.itpub.net/70024420/viewspace-2929070/ 【摘要】运维是一门艺术,也是一门苦差事,每个人对此均有不同的理解,正所谓一千个人眼中有一千个哈姆雷特。干一行就要爱一行,既然选择了这个行业,最好是能把它做到最好,发挥自己最大的价值。本文来聊聊在日常运

[转帖]MSE注册配置中心和自建注册配置中心对比

https://help.aliyun.com/document_detail/469154.html?spm=a2c4g.11186623.0.0.1a2779a6aPjzic 本文从运维、性能、高可用、监控告警等维度进行分析,介绍MSE注册配置中心和自建注册配置中心的差异。 MSE Nacos和

[转帖]自动化测试分层

https://www.jianshu.com/p/3bea28840a74 2012年5月1日,Martin Fowler在他的博客(https://martinfowler.com/bliki/TestPyramid.html)上发表了著名的自动化测试金字塔。 Martin认为,基于用户接口(如

[转帖]自动化回归测试工具 —— AREX 上手实践

https://my.oschina.net/arextest/blog/8589156 AREX 是一款开源的自动化测试工具平台,基于 Java Agent 技术与比对技术,通过流量录制回放能力实现快速有效的回归测试。同时提供了接口测试、接口比对测试等丰富的自动化测试功能,无需编程能力也可快速上手

[转帖]自动化配置SSH免密登录和取消SSH免密配置脚本

1. 前文 搭建了一套有多台主机的局域网环境,不完全考虑安全性的情况下,为方便管理局域网内主机,配置SSH免密登录,因主机较多,前阵子针对配置ssh免密和取消ssh免密功能单独写了脚本来自动化批量部署,现把两个功能封装在一起做成交互式程序 2.实现代码 #!/bin/bash #Author:cos

[转帖]【翻译】curl自动化http操作

https://cizixs.com/2014/05/14/curl-automate-http/ HTTP 脚本 背景 这篇文档假定读者熟悉HTML和简单的网络知识。 大量应用转到网络使得HTTP 脚本被大量使用,自动化地从网络获取信息、伪装成用户、上传数据到网络服务器也变得至关重要。 curl是

[转帖]acme.sh-实现自动化部署SSL证书

https://cloud.tencent.com/developer/article/2055254 前言 ; acme 我一直使用的都是Let's Encrypt免费的证书,昨天看到群里的大佬发出了一个测试的证书申请的脚本命令,我才接触到acme.sh,于是我查阅了很多大佬的博文了解这个脚本的使

[转帖]如何在本地编译安装部署自动化回归测试平台 AREX

https://zhuanlan.zhihu.com/p/613877597 AREX 官方 QQ 交流群:656108079 本文将详细为大家介绍一下自动化回归测试平台 AREX 以及如何在本地进行编译安装部署。 背景 AREX 是一款开源的自动化回归测试工具, 基于 Java Agent 技术,