add:git推送多个远程仓库
This commit is contained in:
parent
71c7007d7e
commit
bb55a70f51
@ -1,126 +1,126 @@
|
||||
---
|
||||
id: '2019-03-03-15-42'
|
||||
date: '2019-03-03 15:42:00'
|
||||
title: 'docker实现hexo博客自动部署,实时更新'
|
||||
tags: ['docker', 'hexo', 'next', 'webhook']
|
||||
categories:
|
||||
- '其他'
|
||||
---
|
||||
|
||||
## 一、背景
|
||||
|
||||
  你是否有过想要搭建一个 hexo 博客,但是看着那冗长的教程,唉声叹气?
|
||||
  你是否因为每次发布新的博文,都要重新构建,部署而逐渐放弃写博客?
|
||||
|
||||
  现在解决有了完美的解决办法了,一键构建,无需进行复杂的配置,开箱即用。同时支持 github 的 webhook 来实现实时构建,只需就行一次 push 操作,便能自动重新构建发布,无需手动操作。
|
||||
|
||||
  详见[hexoBlog 自动构建](https://github.com/FleyX/hexoBlog)
|
||||
|
||||
使用方法:
|
||||
|
||||
## 从 github 克隆本仓库
|
||||
|
||||
```bash
|
||||
git clone git@github.com:FleyX/hexoBlog.git
|
||||
```
|
||||
|
||||
## 基本配置
|
||||
|
||||
1. 修改`docker/docker-compose.yml`文件,指定博文所在 gihub 仓库和 webhook 密钥.
|
||||
|
||||

|
||||
|
||||
**github 配置 webhock 步骤如下:**
|
||||
  以我的博文仓库(technology-note)为例:
|
||||
|
||||
- 新增一个 webhook
|
||||

|
||||
|
||||
- 配置 webhook
|
||||

|
||||
|
||||
  将 url 的地址换为你的服务器地址,然后设置 secret 密钥,就 OK 了。再将密钥设置到 docker-compose.yml 中即可。
|
||||
|
||||
2. 博文 markdown 文件编写规范,详情参见[分布式事务.md](https://raw.githubusercontent.com/FleyX/technology-note/master/%E6%95%B0%E6%8D%AE%E5%BA%93/%E5%88%86%E5%B8%83%E5%BC%8F/%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1.md):
|
||||
|
||||
<!-- more -->
|
||||
|
||||
```yaml
|
||||
---
|
||||
id: '2018-10-03-10-58'
|
||||
date: '2018/10/03 10:58'
|
||||
title: '分布式事务'
|
||||
tags: ['分布式', 'sql', '2PC', 'TCC', '异步补偿']
|
||||
categories:
|
||||
- '数据库'
|
||||
- '分布式事务'
|
||||
---
|
||||
|
||||
```
|
||||
|
||||
参数含义如下:
|
||||
|
||||
- id:博文 id,博文链接也会使用这个值
|
||||
- date: 博文创建日志
|
||||
- title: 博文标题
|
||||
- tags: 文章标签
|
||||
- categories: 文章分类,支持多级分类,第一个最高级依次降低
|
||||
|
||||
  如果想实现首页概览,秩序在想要展现的部分下加上`<!-- more -->`,如下所示:
|
||||
|
||||

|
||||
|
||||
3. 在 docker 目录下,执行`docker-compose up -d`,完工,访问服务器 IP 或域名即可看到效果。(注意首次部署可能会很慢,取决于网络情况和服务器配置)。
|
||||
|
||||
## 详细配置
|
||||
|
||||
  上图只是基本配置,下面是常用的配置:
|
||||
|
||||
### 设置文章永久链接
|
||||
|
||||
  编辑`hexo/_config.yml`下 16,17
|
||||
|
||||

|
||||
|
||||
如果部署在根目录下,将 url 设置为`服务器域名`,root 设置为`/`
|
||||
如果部署在 test 路径下,将 url 设置为`服务器域名/test`,root 设置为`/test`
|
||||
|
||||
### 设置站点信息
|
||||
|
||||
  编辑`hexo/_config.yml`下 6-10 行,设置博客标题,子标题,关键词,作者等信息
|
||||
|
||||
```yaml
|
||||
title: Hexo
|
||||
subtitle: To strive, to seek, to find, and not to yield.
|
||||
description: To strive, to seek, to find, and not to yield.
|
||||
keywords: ['java', 'node', 'html', 'javascript']
|
||||
author: fleyX
|
||||
```
|
||||
|
||||
**注意下面的都是配置主题的配置文件,位置`themes/_config.yml`,本博客使用的 Next 主题,其他主题的配置可能不一样**
|
||||
|
||||
### 设置社交信息
|
||||
|
||||
  编辑第 178 行 social 下项目:
|
||||
|
||||

|
||||
|
||||
### 设置打赏
|
||||
|
||||
  编辑 327 行 reward 下属性,设置支付宝/微信收款图片,可将图片放到`hexo/source/static/img`目录下。
|
||||
|
||||

|
||||
|
||||
### 集成 gitalk 评论
|
||||
|
||||
  建议百度如何在 github 中配置 gitalk,这里默认你已经配置完毕,拥有 id 和 secret。编辑 570 行,设置 enable 为 true,然后加入你的信息:
|
||||
|
||||

|
||||
|
||||
### 集成 cnzz 统计
|
||||
|
||||
  设置 635 行,cnzz id 即可
|
||||
|
||||

|
||||
|
||||
其他更加详细配置参看官方文档。
|
||||
---
|
||||
id: '2019-03-03-15-42'
|
||||
date: '2019-03-03 15:42:00'
|
||||
title: 'docker实现hexo博客自动部署,实时更新'
|
||||
tags: ['docker', 'hexo', 'next', 'webhook']
|
||||
categories:
|
||||
- '其他'
|
||||
---
|
||||
|
||||
## 一、背景
|
||||
|
||||
  你是否有过想要搭建一个 hexo 博客,但是看着那冗长的教程,唉声叹气?
|
||||
  你是否因为每次发布新的博文,都要重新构建,部署而逐渐放弃写博客?
|
||||
|
||||
  现在解决有了完美的解决办法了,一键构建,无需进行复杂的配置,开箱即用。同时支持 github 的 webhook 来实现实时构建,只需就行一次 push 操作,便能自动重新构建发布,无需手动操作。
|
||||
|
||||
  详见[hexoBlog 自动构建](https://github.com/FleyX/hexoBlog)
|
||||
|
||||
使用方法:
|
||||
|
||||
## 从 github 克隆本仓库
|
||||
|
||||
```bash
|
||||
git clone git@github.com:FleyX/hexoBlog.git
|
||||
```
|
||||
|
||||
## 基本配置
|
||||
|
||||
1. 修改`docker/docker-compose.yml`文件,指定博文所在 gihub 仓库和 webhook 密钥.
|
||||
|
||||

|
||||
|
||||
**github 配置 webhock 步骤如下:**
|
||||
  以我的博文仓库(technology-note)为例:
|
||||
|
||||
- 新增一个 webhook
|
||||

|
||||
|
||||
- 配置 webhook
|
||||

|
||||
|
||||
  将 url 的地址换为你的服务器地址,然后设置 secret 密钥,就 OK 了。再将密钥设置到 docker-compose.yml 中即可。
|
||||
|
||||
2. 博文 markdown 文件编写规范,详情参见[分布式事务.md](https://raw.githubusercontent.com/FleyX/technology-note/master/%E6%95%B0%E6%8D%AE%E5%BA%93/%E5%88%86%E5%B8%83%E5%BC%8F/%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1.md):
|
||||
|
||||
<!-- more -->
|
||||
|
||||
```yaml
|
||||
---
|
||||
id: '2018-10-03-10-58'
|
||||
date: '2018/10/03 10:58'
|
||||
title: '分布式事务'
|
||||
tags: ['分布式', 'sql', '2PC', 'TCC', '异步补偿']
|
||||
categories:
|
||||
- '数据库'
|
||||
- '分布式事务'
|
||||
---
|
||||
|
||||
```
|
||||
|
||||
参数含义如下:
|
||||
|
||||
- id:博文 id,博文链接也会使用这个值
|
||||
- date: 博文创建日志
|
||||
- title: 博文标题
|
||||
- tags: 文章标签
|
||||
- categories: 文章分类,支持多级分类,第一个最高级依次降低
|
||||
|
||||
  如果想实现首页概览,秩序在想要展现的部分下加上`<!-- more -->`,如下所示:
|
||||
|
||||

|
||||
|
||||
3. 在 docker 目录下,执行`docker-compose up -d`,完工,访问服务器 IP 或域名即可看到效果。(注意首次部署可能会很慢,取决于网络情况和服务器配置)。
|
||||
|
||||
## 详细配置
|
||||
|
||||
  上图只是基本配置,下面是常用的配置:
|
||||
|
||||
### 设置文章永久链接
|
||||
|
||||
  编辑`hexo/_config.yml`下 16,17
|
||||
|
||||

|
||||
|
||||
如果部署在根目录下,将 url 设置为`服务器域名`,root 设置为`/`
|
||||
如果部署在 test 路径下,将 url 设置为`服务器域名/test`,root 设置为`/test`
|
||||
|
||||
### 设置站点信息
|
||||
|
||||
  编辑`hexo/_config.yml`下 6-10 行,设置博客标题,子标题,关键词,作者等信息
|
||||
|
||||
```yaml
|
||||
title: Hexo
|
||||
subtitle: To strive, to seek, to find, and not to yield.
|
||||
description: To strive, to seek, to find, and not to yield.
|
||||
keywords: ['java', 'node', 'html', 'javascript']
|
||||
author: fleyX
|
||||
```
|
||||
|
||||
**注意下面的都是配置主题的配置文件,位置`themes/_config.yml`,本博客使用的 Next 主题,其他主题的配置可能不一样**
|
||||
|
||||
### 设置社交信息
|
||||
|
||||
  编辑第 178 行 social 下项目:
|
||||
|
||||

|
||||
|
||||
### 设置打赏
|
||||
|
||||
  编辑 327 行 reward 下属性,设置支付宝/微信收款图片,可将图片放到`hexo/source/static/img`目录下。
|
||||
|
||||

|
||||
|
||||
### 集成 gitalk 评论
|
||||
|
||||
  建议百度如何在 github 中配置 gitalk,这里默认你已经配置完毕,拥有 id 和 secret。编辑 570 行,设置 enable 为 true,然后加入你的信息:
|
||||
|
||||

|
||||
|
||||
### 集成 cnzz 统计
|
||||
|
||||
  设置 635 行,cnzz id 即可
|
||||
|
||||

|
||||
|
||||
其他更加详细配置参看官方文档。
|
@ -1,30 +1,30 @@
|
||||
---
|
||||
id: "2018-09-20-10-58"
|
||||
date: "2018/09/20 10:58"
|
||||
title: "git crlf、lf自动转换问题"
|
||||
tags: ["git","crlf","lf","flyway"]
|
||||
categories:
|
||||
- "其他"
|
||||
- "踩坑"
|
||||
---
|
||||
|
||||
  项目组最近加了一个新功能到代码中,使用 flyway 记录数据库版本变更,该工具会记录每次数据库结构的修改并生成 sql 文件存在指定目录上(当然必须用它来变更数据库,外部的变更它是无法感知的),然后每次启动时 flyway 会检查使用的数据库和当前项目代码中的 sql 变更版本是否一致,一致正常启动,不一致中如果是数据库落后将会更新数据库(这样能够保证代码在任何地方运行数据库都是一致的),否则就报错了。数据库中有一张表记录版本信息,如下图:
|
||||
|
||||

|
||||
|
||||
同时本地代码中也有一个文件夹保存每次操作的 sql 语句,如下图:
|
||||
|
||||

|
||||
|
||||
通过对比 checksum 值来判断当前 sql 语句和生成数据库的执行语句是否一致,checksum 值由 CRC32 计算后处理得出。
|
||||
|
||||
  然后问题就来了,组中的其他人搭建好 flyway 后,项目文件生成了两个 sql 文件,我用 git 拉下来后启动报错,checkupsum 值对不上,,然后我又不懂这个 flyway 完全不知道咋回事,然后就根据报错的位置一点点找到 checkup 值生成的代码,发现是 CRC32 计算的,,(就这么搞了一两个小时才发现是文件不一致了),但是都是从 git 拉的怎么就我不一致呢???想到可能是文件换行符的问题,遂把那几个 sql 文件的文件换行符全换成了 crlf(windows 中的换行符),然后居然就能够运行。。。关于为啥都从 git 拉取的文件换行符会不一样原因是:他们都用的那个小乌龟的可视化,我用的命令行。可视化工具自动配置了文件换行符的自动转换(这是 git 的一个智能功能,上传时将文件换行符替换为 lf,,拉取时再替换为 crlf,,这样保证中心仓库使用 UNIX 风格的换行符,,本地能够根据运行环境使用相对应的换行符风格),但是命令行并没有配置。
|
||||
|
||||
  解决办法也很简单,开启 git 的自动转换。
|
||||
|
||||
```
|
||||
git config --global core.autocrlf true //开启换行符自动转换
|
||||
git config --global core.safecrlf true //禁止混用换行符
|
||||
```
|
||||
|
||||
ps:最好还是不要开自动切换,规定所有人必须使用lf就行了。
|
||||
---
|
||||
id: "2018-09-20-10-58"
|
||||
date: "2018/09/20 10:58"
|
||||
title: "git crlf、lf自动转换问题"
|
||||
tags: ["git","crlf","lf","flyway"]
|
||||
categories:
|
||||
- "其他"
|
||||
- "踩坑"
|
||||
---
|
||||
|
||||
  项目组最近加了一个新功能到代码中,使用 flyway 记录数据库版本变更,该工具会记录每次数据库结构的修改并生成 sql 文件存在指定目录上(当然必须用它来变更数据库,外部的变更它是无法感知的),然后每次启动时 flyway 会检查使用的数据库和当前项目代码中的 sql 变更版本是否一致,一致正常启动,不一致中如果是数据库落后将会更新数据库(这样能够保证代码在任何地方运行数据库都是一致的),否则就报错了。数据库中有一张表记录版本信息,如下图:
|
||||
|
||||

|
||||
|
||||
同时本地代码中也有一个文件夹保存每次操作的 sql 语句,如下图:
|
||||
|
||||

|
||||
|
||||
通过对比 checksum 值来判断当前 sql 语句和生成数据库的执行语句是否一致,checksum 值由 CRC32 计算后处理得出。
|
||||
|
||||
  然后问题就来了,组中的其他人搭建好 flyway 后,项目文件生成了两个 sql 文件,我用 git 拉下来后启动报错,checkupsum 值对不上,,然后我又不懂这个 flyway 完全不知道咋回事,然后就根据报错的位置一点点找到 checkup 值生成的代码,发现是 CRC32 计算的,,(就这么搞了一两个小时才发现是文件不一致了),但是都是从 git 拉的怎么就我不一致呢???想到可能是文件换行符的问题,遂把那几个 sql 文件的文件换行符全换成了 crlf(windows 中的换行符),然后居然就能够运行。。。关于为啥都从 git 拉取的文件换行符会不一样原因是:他们都用的那个小乌龟的可视化,我用的命令行。可视化工具自动配置了文件换行符的自动转换(这是 git 的一个智能功能,上传时将文件换行符替换为 lf,,拉取时再替换为 crlf,,这样保证中心仓库使用 UNIX 风格的换行符,,本地能够根据运行环境使用相对应的换行符风格),但是命令行并没有配置。
|
||||
|
||||
  解决办法也很简单,开启 git 的自动转换。
|
||||
|
||||
```
|
||||
git config --global core.autocrlf true //开启换行符自动转换
|
||||
git config --global core.safecrlf true //禁止混用换行符
|
||||
```
|
||||
|
||||
ps:最好还是不要开自动切换,规定所有人必须使用lf就行了。
|
@ -1,70 +1,70 @@
|
||||
---
|
||||
id: '2019-03-19-15-42'
|
||||
date: '2019-03-19 15:42:00'
|
||||
title: '纯html实现svg文件转png/jpg/bmp图片'
|
||||
tags: ['html', 'svg转换', 'png', 'jpg', 'bmp']
|
||||
categories:
|
||||
- '其他'
|
||||
---
|
||||
|
||||
|
||||
**源码存放于:**[github](https://github.com/FleyX/demo-project/blob/master/%E6%9D%82%E9%A1%B9/1.svg%E8%BD%ACpng%E3%80%81jpg.html)
|
||||
|
||||
  svg 文件实际上是一个 xml 文件,用于描述一个矢量图。可直接用浏览器打开,浏览器会自动解析为图片。但是有时候我们可能会需要将 svg 转成 png/jpeg 等图片格式,有什么简单易用的办法呢?
|
||||
|
||||
  最简单的就是通过 html 来进行转换操作。主要流程如下:
|
||||
|
||||
1. 使用`<input type='file'>`获取到文件信息
|
||||
|
||||
```javascript
|
||||
let files = document.getElementById('file').files;
|
||||
```
|
||||
|
||||
<!-- more -->
|
||||
|
||||
2. 使用 html5 中的`FileReader`将文件内容读取出来
|
||||
|
||||
```javascript
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
let reader = new FileReader();
|
||||
reader.readAsText(files[i]);
|
||||
reader.onload = function(e) {
|
||||
arr.push({
|
||||
name: files[i].name,
|
||||
content: this.result
|
||||
});
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
3. 使用`DOMParser`解析 svg 内容
|
||||
|
||||
```javascript
|
||||
let xml = new DOMParser().parseFromString(item.content, 'text/xml');
|
||||
let svgContent = xml.getElementsByTagName('svg')[0].outerHTML;
|
||||
```
|
||||
|
||||
4. 将 svg 内容放到一个`Image`中,然后再将该 img 写入到 canvas 中,最后将 canvas 画布转为 data 字符串,使用`a`标签下载下来。
|
||||
|
||||
```javascript
|
||||
let img = new Image();
|
||||
img.src = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(svgContent)));
|
||||
//这里要等img加载完毕再写到canvas中,否则canvas可能为空
|
||||
img.onload = function() {
|
||||
let canvas = document.getElementById('canvas');
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
let ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, img.width, img.height);
|
||||
//构建下载
|
||||
let a = document.createElement('a');
|
||||
a.href = canvas.toDataURL('image/' + postfix);
|
||||
a.download = item.name.substr(0, item.name.lastIndexOf('.')) + '.' + postfix;
|
||||
//调用点击开始下载
|
||||
a.click();
|
||||
};
|
||||
```
|
||||
|
||||
# 效果如下
|
||||
|
||||

|
||||
---
|
||||
id: '2019-03-19-15-42'
|
||||
date: '2019-03-19 15:42:00'
|
||||
title: '纯html实现svg文件转png/jpg/bmp图片'
|
||||
tags: ['html', 'svg转换', 'png', 'jpg', 'bmp']
|
||||
categories:
|
||||
- '其他'
|
||||
---
|
||||
|
||||
|
||||
**源码存放于:**[github](https://github.com/FleyX/demo-project/blob/master/%E6%9D%82%E9%A1%B9/1.svg%E8%BD%ACpng%E3%80%81jpg.html)
|
||||
|
||||
  svg 文件实际上是一个 xml 文件,用于描述一个矢量图。可直接用浏览器打开,浏览器会自动解析为图片。但是有时候我们可能会需要将 svg 转成 png/jpeg 等图片格式,有什么简单易用的办法呢?
|
||||
|
||||
  最简单的就是通过 html 来进行转换操作。主要流程如下:
|
||||
|
||||
1. 使用`<input type='file'>`获取到文件信息
|
||||
|
||||
```javascript
|
||||
let files = document.getElementById('file').files;
|
||||
```
|
||||
|
||||
<!-- more -->
|
||||
|
||||
2. 使用 html5 中的`FileReader`将文件内容读取出来
|
||||
|
||||
```javascript
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
let reader = new FileReader();
|
||||
reader.readAsText(files[i]);
|
||||
reader.onload = function(e) {
|
||||
arr.push({
|
||||
name: files[i].name,
|
||||
content: this.result
|
||||
});
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
3. 使用`DOMParser`解析 svg 内容
|
||||
|
||||
```javascript
|
||||
let xml = new DOMParser().parseFromString(item.content, 'text/xml');
|
||||
let svgContent = xml.getElementsByTagName('svg')[0].outerHTML;
|
||||
```
|
||||
|
||||
4. 将 svg 内容放到一个`Image`中,然后再将该 img 写入到 canvas 中,最后将 canvas 画布转为 data 字符串,使用`a`标签下载下来。
|
||||
|
||||
```javascript
|
||||
let img = new Image();
|
||||
img.src = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(svgContent)));
|
||||
//这里要等img加载完毕再写到canvas中,否则canvas可能为空
|
||||
img.onload = function() {
|
||||
let canvas = document.getElementById('canvas');
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
let ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, img.width, img.height);
|
||||
//构建下载
|
||||
let a = document.createElement('a');
|
||||
a.href = canvas.toDataURL('image/' + postfix);
|
||||
a.download = item.name.substr(0, item.name.lastIndexOf('.')) + '.' + postfix;
|
||||
//调用点击开始下载
|
||||
a.click();
|
||||
};
|
||||
```
|
||||
|
||||
# 效果如下
|
||||
|
||||

|
@ -1,59 +1,59 @@
|
||||
---
|
||||
id: "2018-09-30-10-58"
|
||||
date: "2018/09/30 10:58"
|
||||
title: "正则匹配之正向/反向预测先行搜索"
|
||||
tags: ["java","正则匹配","pattern","预测先行搜索"]
|
||||
categories:
|
||||
- "java"
|
||||
- "正则匹配"
|
||||
---
|
||||
|
||||
## 一、背景
|
||||
|
||||
  今天领导让我写几个正则表达式来对密码做强度验证,听到写正则表达式内心是这样的感觉(哈哈,三分钟搞定,今天又可以打鱼了)。需求如下:密码组成只能是**数字**,**字母**,**英文可见半角符号**,然后需要如下 4 个表达式:
|
||||
|
||||
- 长度 6 位及以上
|
||||
- 长度 6 位及以上,包含数字,包含字母
|
||||
- 长度 6 位及以上,包含数字,包含字母,包含半角符号
|
||||
- 长度六位及以上,包含数字,包含大写字母,包含小写字母,包含半角符号
|
||||
|
||||
  看完需求我就有点懵了,包含数字或者字母我会写,但是同时存在还要在一个表达式中就有点懵了。
|
||||
|
||||
## 二、解决方法
|
||||
|
||||
  以第三种为例,这个可以分解为如下需求:
|
||||
|
||||
- 存在数字
|
||||
- 存在字母
|
||||
- 存在半角符号
|
||||
- 长度六位及以上
|
||||
|
||||
关键是如何同时满足前三个条件,在我有限的知识里并不知道怎么搞,然后只好求助于万能的百度了,最终在找了几个小时后发现如下几个关键词,来源[菜鸟教程](http://www.runoob.com/java/java-regular-expressions.html) :
|
||||
|
||||
- (?=_pattern_) :正向预测先行搜索
|
||||
|
||||
名字看着高大上,不明所以,看完示例大概明白什么意思,这个表达式匹配从这个表达式起始的字符串(我也不知道咋解释),就是假设这样一个表达式 abc(?=[abc]) ,用它来匹配 abc123 字符串,(?=[abc])只会对作用于后面的 123,这个显然是不匹配的后整个就不匹配了,然后关键来了名字里有**预测**两个字,这两个字表名了这个表达式的特性:不占用字符,匹配后如果匹配成功就继续匹配了好像从来不存在这个东西一样,匹配失败就立即返回失败了。利用这个特性我们就可以给正则加限制条件了。
|
||||
|
||||
<!-- more -->
|
||||
|
||||
- (?!_pattern_) :反向预测先行搜索
|
||||
|
||||
概念和上面一样,但是效果是相反的,abc(?![abc]),对于 abc123 是匹配成功的,对于 abca 匹配失败,如下所示:
|
||||
|
||||
```javascript
|
||||
reg = /abc(?![abc])/;
|
||||
reg.test('abc123');
|
||||
//返回true
|
||||
reg.test('abca');
|
||||
//返回false
|
||||
```
|
||||
|
||||
  有了上面的知识就能搞定需求啦。
|
||||
|
||||
## 三、结果
|
||||
|
||||
  对于存在字母我们可以用这样的表达式`(?=.\*?[a-zA-Z]+.\*?),来检查是否存在至少一个字母,最后对于需求 3 的表达式如下:(半角字符我用的 ASCII 码里的 16 进制表示的)
|
||||
|
||||
```javascript
|
||||
^(?=.*?\d+.*?)(?=.*?[a-zA-Z]+.*?)(?=.*?[\x21-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]+.*?)[\da-zA-Z\x21-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]{6,}$
|
||||
```
|
||||
---
|
||||
id: "2018-09-30-10-58"
|
||||
date: "2018/09/30 10:58"
|
||||
title: "正则匹配之正向/反向预测先行搜索"
|
||||
tags: ["java","正则匹配","pattern","预测先行搜索"]
|
||||
categories:
|
||||
- "java"
|
||||
- "正则匹配"
|
||||
---
|
||||
|
||||
## 一、背景
|
||||
|
||||
  今天领导让我写几个正则表达式来对密码做强度验证,听到写正则表达式内心是这样的感觉(哈哈,三分钟搞定,今天又可以打鱼了)。需求如下:密码组成只能是**数字**,**字母**,**英文可见半角符号**,然后需要如下 4 个表达式:
|
||||
|
||||
- 长度 6 位及以上
|
||||
- 长度 6 位及以上,包含数字,包含字母
|
||||
- 长度 6 位及以上,包含数字,包含字母,包含半角符号
|
||||
- 长度六位及以上,包含数字,包含大写字母,包含小写字母,包含半角符号
|
||||
|
||||
  看完需求我就有点懵了,包含数字或者字母我会写,但是同时存在还要在一个表达式中就有点懵了。
|
||||
|
||||
## 二、解决方法
|
||||
|
||||
  以第三种为例,这个可以分解为如下需求:
|
||||
|
||||
- 存在数字
|
||||
- 存在字母
|
||||
- 存在半角符号
|
||||
- 长度六位及以上
|
||||
|
||||
关键是如何同时满足前三个条件,在我有限的知识里并不知道怎么搞,然后只好求助于万能的百度了,最终在找了几个小时后发现如下几个关键词,来源[菜鸟教程](http://www.runoob.com/java/java-regular-expressions.html) :
|
||||
|
||||
- (?=_pattern_) :正向预测先行搜索
|
||||
|
||||
名字看着高大上,不明所以,看完示例大概明白什么意思,这个表达式匹配从这个表达式起始的字符串(我也不知道咋解释),就是假设这样一个表达式 abc(?=[abc]) ,用它来匹配 abc123 字符串,(?=[abc])只会对作用于后面的 123,这个显然是不匹配的后整个就不匹配了,然后关键来了名字里有**预测**两个字,这两个字表名了这个表达式的特性:不占用字符,匹配后如果匹配成功就继续匹配了好像从来不存在这个东西一样,匹配失败就立即返回失败了。利用这个特性我们就可以给正则加限制条件了。
|
||||
|
||||
<!-- more -->
|
||||
|
||||
- (?!_pattern_) :反向预测先行搜索
|
||||
|
||||
概念和上面一样,但是效果是相反的,abc(?![abc]),对于 abc123 是匹配成功的,对于 abca 匹配失败,如下所示:
|
||||
|
||||
```javascript
|
||||
reg = /abc(?![abc])/;
|
||||
reg.test('abc123');
|
||||
//返回true
|
||||
reg.test('abca');
|
||||
//返回false
|
||||
```
|
||||
|
||||
  有了上面的知识就能搞定需求啦。
|
||||
|
||||
## 三、结果
|
||||
|
||||
  对于存在字母我们可以用这样的表达式`(?=.\*?[a-zA-Z]+.\*?),来检查是否存在至少一个字母,最后对于需求 3 的表达式如下:(半角字符我用的 ASCII 码里的 16 进制表示的)
|
||||
|
||||
```javascript
|
||||
^(?=.*?\d+.*?)(?=.*?[a-zA-Z]+.*?)(?=.*?[\x21-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]+.*?)[\da-zA-Z\x21-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]{6,}$
|
||||
```
|
@ -1,403 +1,403 @@
|
||||
---
|
||||
id: "2019-04-05"
|
||||
date: "2019/04/25 10:58"
|
||||
title: "最新ubuntu搭建公网个人邮件服务器(基于postfix,dovecot,mysql)"
|
||||
tags: ["smtp", "linux", "ubuntu", "邮件服务器", "postfix", "dovecot"]
|
||||
|
||||
categories:
|
||||
- "搭建服务"
|
||||
---
|
||||
|
||||
  最近做了一个应用,需要用邮件发通知,但是免费的邮箱每天发信数量是有限制的,所以呢就想着搭建一个自己的邮件服务器,能够实现邮件的发送和接收即可,其中大概花了一个星期找资料,测试,终于成功了,写个教程分享给大家。
|
||||
|
||||
  本教程基于 ubuntu 18.04(其他的 linux 理论上也是可以的,只是安装的软件包不一样)。用到的主要软件为:postfix,dovecot,mysql.废话不多说,下面是教程:
|
||||
|
||||
<!-- more -->
|
||||
|
||||
# 前置条件
|
||||
|
||||
- mysql 数据库。本教程中使用 mysql 存储域名,用户信息等。
|
||||
- 域名。需要有域名才能实现向公网发邮件/收邮件。这里以 test.com 为例。
|
||||
- ssl 证书。有不少免费的 ssl 证书提供商,或者使用自签证书,百度即可。
|
||||
|
||||
# 安装环境
|
||||
|
||||
## 安装软件
|
||||
|
||||
  切换到 root 用户下,执行以下命令:
|
||||
|
||||
```bash
|
||||
apt update
|
||||
apt install postfix postfix-mysql dovecot-core dovecot-pop3d dovecot-imapd dovecot-lmtpd dovecot-mysql
|
||||
```
|
||||
|
||||
安装过程中 postfix 会弹出提示:
|
||||
|
||||

|
||||
|
||||
这里我们选择第二项:Internet Site。
|
||||
接着会有如下提示:
|
||||
|
||||

|
||||
|
||||
这里填入:`test.com`
|
||||
|
||||
## 配置 mx 解析
|
||||
|
||||
  在域名提供商增加以下解析:
|
||||
|
||||
- MX 记录:`test.com` 指向 `服务器IP`
|
||||
- A 记录:`pop3.test.com` 指向 `服务器IP`
|
||||
- A 记录:`smtp.test.com` 指向 `服务器IP`
|
||||
|
||||
## 创建 mysql 数据库
|
||||
|
||||
  新建一个数据库 mailserver,管理账号为:admin/123456
|
||||
|
||||
  创建虚拟域表,作为认证域。该表是邮件服务器用以接收邮件的域名:
|
||||
|
||||
```sql
|
||||
-- 建立表
|
||||
CREATE TABLE `virtual_domains` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(50) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- 插入一条记录
|
||||
insert into virtual_domains values(1,'test.com')
|
||||
```
|
||||
|
||||
  创建用户表,用于用户身份认证。
|
||||
|
||||
```sql
|
||||
-- 创建用户表
|
||||
CREATE TABLE `virtual_users` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`domain_id` INT NOT NULL,
|
||||
`password` VARCHAR(106) NOT NULL,
|
||||
`email` VARCHAR(120) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `email` (`email`),
|
||||
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- 插入两个用户,以md5加密密码,实际应用中应该选择强度更高的算法,md5目前以及不安全了
|
||||
insert into virtual_users values(1,1,md5('123456'),'first@test.com');
|
||||
insert into virtual_users values(2,1,md5('123456'),'second@test.com');
|
||||
```
|
||||
|
||||
  创建别名表.该表作用相当于当 source 收到邮件时,该邮件会自动转发到 destination 上。
|
||||
|
||||
```sql
|
||||
-- 创建表
|
||||
CREATE TABLE `virtual_aliases` (
|
||||
`id` int(11) NOT NULL auto_increment,
|
||||
`domain_id` int(11) NOT NULL,
|
||||
`source` varchar(100) NOT NULL,
|
||||
`destination` varchar(100) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE)
|
||||
ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- 插入数据,所有发给first的邮件都会自动转发给second
|
||||
insert into virtual_aliases values(1,1,'first@test.com','second@test.com')
|
||||
|
||||
```
|
||||
|
||||
## 生成 ssl 证书
|
||||
|
||||
  生成 ssl 证书可参考这一篇[https://www.jianshu.com/p/b47d862bceeb](https://www.jianshu.com/p/b47d862bceeb).为 test.com 生成 ssl 证书,**假设**证书存放地址为:
|
||||
|
||||
- 公钥 /etc/letsencrypt/live/test.com/fullchain.pem;
|
||||
- 私钥 /etc/letsencrypt/live/test.com/privkey.pem;
|
||||
|
||||
# 配置 postfix
|
||||
|
||||
  首选备份 postfix 的默认配置文件,然后编辑`main.cf`
|
||||
|
||||
```bash
|
||||
cp /etc/postfix/main.cf /etc/postfix/main.cf.bak
|
||||
vim /etc/postfix/main.cf
|
||||
```
|
||||
|
||||
  注释下面的配置:
|
||||

|
||||
|
||||
然后加入如下的配置:
|
||||
|
||||
```properties
|
||||
# 使用自己的ssl证书
|
||||
smtpd_tls_cert_file=/etc/letsencrypt/live/test.com/fullchain.pem
|
||||
smtpd_tls_key_file=/etc/letsencrypt/live/test.com/privkey.pem
|
||||
smtpd_use_tls=yes
|
||||
smtpd_tls_auth_only = yes
|
||||
# 使用dovecot来做身份认证
|
||||
smtpd_sasl_type = dovecot
|
||||
smtpd_sasl_path = private/auth
|
||||
smtpd_sasl_auth_enable = yes
|
||||
smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination
|
||||
```
|
||||
|
||||
修改 myhostname,myorigin 为如下的值:
|
||||
|
||||
```properties
|
||||
myhostname = test.com
|
||||
myorigin = $myhostname
|
||||
```
|
||||
|
||||
修改 mydestination 值为 localhost,以启动 mysql 中的虚拟域。:
|
||||
|
||||
```properties
|
||||
mydestination = localhost
|
||||
```
|
||||
|
||||
在配置文件的最后加入以下行,确保将邮件投递给 mysql 表中列出的虚拟域。
|
||||
|
||||
```properties
|
||||
virtual_transport = lmtp:unix:private/dovecot-lmtp
|
||||
```
|
||||
|
||||
最后加入以下三项参数,告知 Postfix 配置虚拟域、用户和别名
|
||||
|
||||
```properties
|
||||
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
|
||||
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
|
||||
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf
|
||||
```
|
||||
|
||||
  接下来创建上面最后加入的三项参数对应的文件。
|
||||
|
||||
  创建`/etc/postfix/mysql-virtual-mailbox-domains.cf`,内容如下:
|
||||
|
||||
```properties
|
||||
user = admin
|
||||
password = 123456
|
||||
port = 3306
|
||||
hosts = 127.0.0.1
|
||||
dbname = mailserver
|
||||
query = SELECT 1 FROM virtual_domains WHERE name='%s'
|
||||
```
|
||||
|
||||
接着重启 postfix,并测试 postfix 能否找到域,如果成功返回 1:
|
||||
|
||||
```bash
|
||||
service postfix restart
|
||||
postmap -q test.com mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
|
||||
```
|
||||
|
||||
  创建`/etc/postfix/mysql-virtual-mailbox-maps.cf`,内容如下:
|
||||
|
||||
```properties
|
||||
user = admin
|
||||
password = 123456
|
||||
port = 3306
|
||||
hosts = 127.0.0.1
|
||||
dbname = mailserver
|
||||
query = SELECT 1 FROM virtual_users WHERE email='%s'
|
||||
```
|
||||
|
||||
接着重启 postfix,并测试其能否找到邮箱地址,成功返回 1:
|
||||
|
||||
```shell
|
||||
service postfix restart
|
||||
postmap -q first@test.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
|
||||
```
|
||||
|
||||
  最后创建`/etc/postfix/mysql-virtual-alias-maps.cf`,内容如下:
|
||||
|
||||
```properties
|
||||
user = admin
|
||||
password = 123456
|
||||
port = 3306
|
||||
hosts = 127.0.0.1
|
||||
dbname = mailserver
|
||||
query = SELECT destination FROM virtual_aliases WHERE source='%s'
|
||||
```
|
||||
|
||||
同样重启 postfix,验证能否正确找到别名,并返回:
|
||||
|
||||
```bash
|
||||
service postfix restart
|
||||
postmap -q first@test.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
|
||||
```
|
||||
|
||||
  如果响应使用 587 端口来进行俺的 smtp 通信,需修改/etc/postfix/master.cf 文件:
|
||||
取消以下行的注释:
|
||||

|
||||
|
||||
# 配置 dovecot
|
||||
|
||||
  postfix 配置完毕,现在来配置 dovecot,首先编辑主配置文件`/etc/dovecot/dovecot.conf`:
|
||||
|
||||
首先确保下面一行是启用的:
|
||||
|
||||
```conf
|
||||
!include conf.d/*.conf
|
||||
```
|
||||
|
||||
然后在配置文件的最后加入如下配置,启用各协议:
|
||||
|
||||
```
|
||||
protocols = imap lmtp pop3
|
||||
```
|
||||
|
||||
  修改`/etc/dovecot/conf.d/10-mail.conf`,确保存在以下两个配置:
|
||||
|
||||
```properties
|
||||
mail_location = maildir:/var/mail/vhosts/%d/%n
|
||||
mail_privileged_group = mail
|
||||
```
|
||||
|
||||
上面的配置将邮件存放目录设置在/var/mail 中,因此将该文件夹的所属人改为 vmail/vmail.命令如下:
|
||||
|
||||
```bash
|
||||
groupadd -g 5000 vmail
|
||||
useradd -g vmail -u 5000 vmail -d /var/mail
|
||||
chown -R vmail:vmail /var/mail
|
||||
```
|
||||
|
||||
  修改`/etc/dovecot/conf.d/10-auth.conf`。首先确保如下两个配置存在且值正确:
|
||||
|
||||
```properties
|
||||
disable_plaintext_auth = yes
|
||||
auth_mechanisms = plain login
|
||||
```
|
||||
|
||||
然后修改配置以禁用系统用户登陆,并开启 mysql 支持,如下图所示:
|
||||

|
||||
|
||||
  修改`/etc/dovecot/conf.d/auth-sql.conf.ext`文件,将内容改成下面的内容:
|
||||
|
||||
```ext
|
||||
passdb {
|
||||
driver = sql
|
||||
args = /etc/dovecot/dovecot-sql.conf.ext
|
||||
}
|
||||
userdb {
|
||||
driver = static
|
||||
args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
|
||||
}
|
||||
```
|
||||
|
||||
  修改`/etc/dovecot/dovecot-sql.conf.ext`:
|
||||
首选取消 driver 参数注释并设置为 mysql
|
||||
|
||||
```properties
|
||||
driver = mysql
|
||||
```
|
||||
|
||||
然后取消 connect 行注释并设置为如下内容:
|
||||
|
||||
```properties
|
||||
connect = host=127.0.0.1 port=3306 dbname=mailserver user=admin password=123456
|
||||
```
|
||||
|
||||
接着取消 default_pass_scheme 行的注释并改为 MD5
|
||||
|
||||
```properties
|
||||
default_pass_scheme = MD5
|
||||
```
|
||||
|
||||
接着取消 password_query 行的注释并设置为以下信息:
|
||||
|
||||
```properties
|
||||
password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';
|
||||
```
|
||||
|
||||
最后将`/etc/dovecot`的拥有者改为 vmail:dovecot
|
||||
|
||||
```bash
|
||||
chown -R vmail:dovecot /etc/dovecot
|
||||
chmod -R o-rwx /etc/dovecot
|
||||
```
|
||||
|
||||
  修改`/etc/dovecot/conf.d/10-master.conf`:
|
||||
|
||||
首先将 imap-login , pop3-login 下第一个的 port 设置为 0,以禁用非 ssl 加密的 imap 和 pop3 协议,如下图所示:
|
||||

|
||||
|
||||
然后找到`service lmtp`将其修改为如下:
|
||||
|
||||
```
|
||||
service lmtp {
|
||||
unix_listener /var/spool/postfix/private/dovecot-lmtp {
|
||||
mode = 0600
|
||||
user = postfix
|
||||
group = postfix
|
||||
}
|
||||
|
||||
# Create inet listener only if you can't use the above UNIX socket
|
||||
#inet_listener lmtp {
|
||||
# Avoid making LMTP visible for the entire internet
|
||||
#address =
|
||||
#port =
|
||||
#}
|
||||
}
|
||||
```
|
||||
|
||||
然后找到`service auth`将其内容修改为如下:
|
||||
|
||||
```
|
||||
service auth {
|
||||
unix_listener /var/spool/postfix/private/auth {
|
||||
mode = 0666
|
||||
user = postfix
|
||||
group = postfix
|
||||
}
|
||||
|
||||
unix_listener auth-userdb {
|
||||
mode = 0600
|
||||
user = vmail
|
||||
#group =
|
||||
}
|
||||
|
||||
user = dovecot
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
最后找到`service auth-worker`改为如下内容:
|
||||
|
||||
```
|
||||
service auth-worker {
|
||||
# Auth worker process is run as root by default, so that it can access
|
||||
# /etc/shadow. If this isn't necessary, the user should be changed to
|
||||
# $default_internal_user.
|
||||
user = vmail
|
||||
}
|
||||
```
|
||||
|
||||
  最后要改的就是`/etc/dovecot/conf.d/10-ssl.conf`,以开启 ssl 认证.
|
||||
|
||||
首先将 ssl 参数改为 required:
|
||||
|
||||
```properties
|
||||
ssl = required
|
||||
```
|
||||
|
||||
然后设置 ssl 证书路径就 ok 了,还是用之前的 ssl 证书:
|
||||
|
||||
```properties
|
||||
ssl_cert = </etc/letsencrypt/live/test.com/fullchain.pem
|
||||
ssl_key = </etc/letsencrypt/live/test.com/privkey.pem
|
||||
```
|
||||
|
||||
  到这里所有的配置都 OK,重启 postfix,dovecot 后就可以用邮箱客户端(比如 foxmail)连接了。
|
||||
|
||||
```
|
||||
service postfix restart
|
||||
service dovecot restart
|
||||
```
|
||||
|
||||
# 结束
|
||||
|
||||
  配合一个邮件客户端看似很简单,实际上还是有很多坑的,看看上面那么多的配置项就知道了,一定要耐心。
|
||||
|
||||
  如果无法登陆,可以看看 postfix 和 dovecot 的日志报错情况,再去修改。日志位置在`/var/log`
|
||||
|
||||
**注意**:
|
||||
被这个问题困扰了好几天,未找到解决办法,最后放弃.
|
||||
|
||||
  目前很多主机厂商都不支持和其他服务器的 25 端口通信,已知的有(谷歌云,阿里云),这样就导致在这些机器上搭建的 postfix 邮件服务器,无法向其他的外网邮箱发送邮件,因为无法和其他 smtp 服务器的 25 端口建立连接。貌似是为了避免有人恶意搭建邮件服务器向其他的邮件服务器发送大量的垃圾邮件,从而导致此服务器 IP 被反垃圾邮件组织列入 SML。
|
||||
|
||||
---
|
||||
id: "2019-04-05"
|
||||
date: "2019/04/25 10:58"
|
||||
title: "最新ubuntu搭建公网个人邮件服务器(基于postfix,dovecot,mysql)"
|
||||
tags: ["smtp", "linux", "ubuntu", "邮件服务器", "postfix", "dovecot"]
|
||||
|
||||
categories:
|
||||
- "搭建服务"
|
||||
---
|
||||
|
||||
  最近做了一个应用,需要用邮件发通知,但是免费的邮箱每天发信数量是有限制的,所以呢就想着搭建一个自己的邮件服务器,能够实现邮件的发送和接收即可,其中大概花了一个星期找资料,测试,终于成功了,写个教程分享给大家。
|
||||
|
||||
  本教程基于 ubuntu 18.04(其他的 linux 理论上也是可以的,只是安装的软件包不一样)。用到的主要软件为:postfix,dovecot,mysql.废话不多说,下面是教程:
|
||||
|
||||
<!-- more -->
|
||||
|
||||
# 前置条件
|
||||
|
||||
- mysql 数据库。本教程中使用 mysql 存储域名,用户信息等。
|
||||
- 域名。需要有域名才能实现向公网发邮件/收邮件。这里以 test.com 为例。
|
||||
- ssl 证书。有不少免费的 ssl 证书提供商,或者使用自签证书,百度即可。
|
||||
|
||||
# 安装环境
|
||||
|
||||
## 安装软件
|
||||
|
||||
  切换到 root 用户下,执行以下命令:
|
||||
|
||||
```bash
|
||||
apt update
|
||||
apt install postfix postfix-mysql dovecot-core dovecot-pop3d dovecot-imapd dovecot-lmtpd dovecot-mysql
|
||||
```
|
||||
|
||||
安装过程中 postfix 会弹出提示:
|
||||
|
||||

|
||||
|
||||
这里我们选择第二项:Internet Site。
|
||||
接着会有如下提示:
|
||||
|
||||

|
||||
|
||||
这里填入:`test.com`
|
||||
|
||||
## 配置 mx 解析
|
||||
|
||||
  在域名提供商增加以下解析:
|
||||
|
||||
- MX 记录:`test.com` 指向 `服务器IP`
|
||||
- A 记录:`pop3.test.com` 指向 `服务器IP`
|
||||
- A 记录:`smtp.test.com` 指向 `服务器IP`
|
||||
|
||||
## 创建 mysql 数据库
|
||||
|
||||
  新建一个数据库 mailserver,管理账号为:admin/123456
|
||||
|
||||
  创建虚拟域表,作为认证域。该表是邮件服务器用以接收邮件的域名:
|
||||
|
||||
```sql
|
||||
-- 建立表
|
||||
CREATE TABLE `virtual_domains` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(50) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- 插入一条记录
|
||||
insert into virtual_domains values(1,'test.com')
|
||||
```
|
||||
|
||||
  创建用户表,用于用户身份认证。
|
||||
|
||||
```sql
|
||||
-- 创建用户表
|
||||
CREATE TABLE `virtual_users` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`domain_id` INT NOT NULL,
|
||||
`password` VARCHAR(106) NOT NULL,
|
||||
`email` VARCHAR(120) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `email` (`email`),
|
||||
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- 插入两个用户,以md5加密密码,实际应用中应该选择强度更高的算法,md5目前以及不安全了
|
||||
insert into virtual_users values(1,1,md5('123456'),'first@test.com');
|
||||
insert into virtual_users values(2,1,md5('123456'),'second@test.com');
|
||||
```
|
||||
|
||||
  创建别名表.该表作用相当于当 source 收到邮件时,该邮件会自动转发到 destination 上。
|
||||
|
||||
```sql
|
||||
-- 创建表
|
||||
CREATE TABLE `virtual_aliases` (
|
||||
`id` int(11) NOT NULL auto_increment,
|
||||
`domain_id` int(11) NOT NULL,
|
||||
`source` varchar(100) NOT NULL,
|
||||
`destination` varchar(100) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE)
|
||||
ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- 插入数据,所有发给first的邮件都会自动转发给second
|
||||
insert into virtual_aliases values(1,1,'first@test.com','second@test.com')
|
||||
|
||||
```
|
||||
|
||||
## 生成 ssl 证书
|
||||
|
||||
  生成 ssl 证书可参考这一篇[https://www.jianshu.com/p/b47d862bceeb](https://www.jianshu.com/p/b47d862bceeb).为 test.com 生成 ssl 证书,**假设**证书存放地址为:
|
||||
|
||||
- 公钥 /etc/letsencrypt/live/test.com/fullchain.pem;
|
||||
- 私钥 /etc/letsencrypt/live/test.com/privkey.pem;
|
||||
|
||||
# 配置 postfix
|
||||
|
||||
  首选备份 postfix 的默认配置文件,然后编辑`main.cf`
|
||||
|
||||
```bash
|
||||
cp /etc/postfix/main.cf /etc/postfix/main.cf.bak
|
||||
vim /etc/postfix/main.cf
|
||||
```
|
||||
|
||||
  注释下面的配置:
|
||||

|
||||
|
||||
然后加入如下的配置:
|
||||
|
||||
```properties
|
||||
# 使用自己的ssl证书
|
||||
smtpd_tls_cert_file=/etc/letsencrypt/live/test.com/fullchain.pem
|
||||
smtpd_tls_key_file=/etc/letsencrypt/live/test.com/privkey.pem
|
||||
smtpd_use_tls=yes
|
||||
smtpd_tls_auth_only = yes
|
||||
# 使用dovecot来做身份认证
|
||||
smtpd_sasl_type = dovecot
|
||||
smtpd_sasl_path = private/auth
|
||||
smtpd_sasl_auth_enable = yes
|
||||
smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination
|
||||
```
|
||||
|
||||
修改 myhostname,myorigin 为如下的值:
|
||||
|
||||
```properties
|
||||
myhostname = test.com
|
||||
myorigin = $myhostname
|
||||
```
|
||||
|
||||
修改 mydestination 值为 localhost,以启动 mysql 中的虚拟域。:
|
||||
|
||||
```properties
|
||||
mydestination = localhost
|
||||
```
|
||||
|
||||
在配置文件的最后加入以下行,确保将邮件投递给 mysql 表中列出的虚拟域。
|
||||
|
||||
```properties
|
||||
virtual_transport = lmtp:unix:private/dovecot-lmtp
|
||||
```
|
||||
|
||||
最后加入以下三项参数,告知 Postfix 配置虚拟域、用户和别名
|
||||
|
||||
```properties
|
||||
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
|
||||
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
|
||||
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf
|
||||
```
|
||||
|
||||
  接下来创建上面最后加入的三项参数对应的文件。
|
||||
|
||||
  创建`/etc/postfix/mysql-virtual-mailbox-domains.cf`,内容如下:
|
||||
|
||||
```properties
|
||||
user = admin
|
||||
password = 123456
|
||||
port = 3306
|
||||
hosts = 127.0.0.1
|
||||
dbname = mailserver
|
||||
query = SELECT 1 FROM virtual_domains WHERE name='%s'
|
||||
```
|
||||
|
||||
接着重启 postfix,并测试 postfix 能否找到域,如果成功返回 1:
|
||||
|
||||
```bash
|
||||
service postfix restart
|
||||
postmap -q test.com mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
|
||||
```
|
||||
|
||||
  创建`/etc/postfix/mysql-virtual-mailbox-maps.cf`,内容如下:
|
||||
|
||||
```properties
|
||||
user = admin
|
||||
password = 123456
|
||||
port = 3306
|
||||
hosts = 127.0.0.1
|
||||
dbname = mailserver
|
||||
query = SELECT 1 FROM virtual_users WHERE email='%s'
|
||||
```
|
||||
|
||||
接着重启 postfix,并测试其能否找到邮箱地址,成功返回 1:
|
||||
|
||||
```shell
|
||||
service postfix restart
|
||||
postmap -q first@test.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
|
||||
```
|
||||
|
||||
  最后创建`/etc/postfix/mysql-virtual-alias-maps.cf`,内容如下:
|
||||
|
||||
```properties
|
||||
user = admin
|
||||
password = 123456
|
||||
port = 3306
|
||||
hosts = 127.0.0.1
|
||||
dbname = mailserver
|
||||
query = SELECT destination FROM virtual_aliases WHERE source='%s'
|
||||
```
|
||||
|
||||
同样重启 postfix,验证能否正确找到别名,并返回:
|
||||
|
||||
```bash
|
||||
service postfix restart
|
||||
postmap -q first@test.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
|
||||
```
|
||||
|
||||
  如果响应使用 587 端口来进行俺的 smtp 通信,需修改/etc/postfix/master.cf 文件:
|
||||
取消以下行的注释:
|
||||

|
||||
|
||||
# 配置 dovecot
|
||||
|
||||
  postfix 配置完毕,现在来配置 dovecot,首先编辑主配置文件`/etc/dovecot/dovecot.conf`:
|
||||
|
||||
首先确保下面一行是启用的:
|
||||
|
||||
```conf
|
||||
!include conf.d/*.conf
|
||||
```
|
||||
|
||||
然后在配置文件的最后加入如下配置,启用各协议:
|
||||
|
||||
```
|
||||
protocols = imap lmtp pop3
|
||||
```
|
||||
|
||||
  修改`/etc/dovecot/conf.d/10-mail.conf`,确保存在以下两个配置:
|
||||
|
||||
```properties
|
||||
mail_location = maildir:/var/mail/vhosts/%d/%n
|
||||
mail_privileged_group = mail
|
||||
```
|
||||
|
||||
上面的配置将邮件存放目录设置在/var/mail 中,因此将该文件夹的所属人改为 vmail/vmail.命令如下:
|
||||
|
||||
```bash
|
||||
groupadd -g 5000 vmail
|
||||
useradd -g vmail -u 5000 vmail -d /var/mail
|
||||
chown -R vmail:vmail /var/mail
|
||||
```
|
||||
|
||||
  修改`/etc/dovecot/conf.d/10-auth.conf`。首先确保如下两个配置存在且值正确:
|
||||
|
||||
```properties
|
||||
disable_plaintext_auth = yes
|
||||
auth_mechanisms = plain login
|
||||
```
|
||||
|
||||
然后修改配置以禁用系统用户登陆,并开启 mysql 支持,如下图所示:
|
||||

|
||||
|
||||
  修改`/etc/dovecot/conf.d/auth-sql.conf.ext`文件,将内容改成下面的内容:
|
||||
|
||||
```ext
|
||||
passdb {
|
||||
driver = sql
|
||||
args = /etc/dovecot/dovecot-sql.conf.ext
|
||||
}
|
||||
userdb {
|
||||
driver = static
|
||||
args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
|
||||
}
|
||||
```
|
||||
|
||||
  修改`/etc/dovecot/dovecot-sql.conf.ext`:
|
||||
首选取消 driver 参数注释并设置为 mysql
|
||||
|
||||
```properties
|
||||
driver = mysql
|
||||
```
|
||||
|
||||
然后取消 connect 行注释并设置为如下内容:
|
||||
|
||||
```properties
|
||||
connect = host=127.0.0.1 port=3306 dbname=mailserver user=admin password=123456
|
||||
```
|
||||
|
||||
接着取消 default_pass_scheme 行的注释并改为 MD5
|
||||
|
||||
```properties
|
||||
default_pass_scheme = MD5
|
||||
```
|
||||
|
||||
接着取消 password_query 行的注释并设置为以下信息:
|
||||
|
||||
```properties
|
||||
password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';
|
||||
```
|
||||
|
||||
最后将`/etc/dovecot`的拥有者改为 vmail:dovecot
|
||||
|
||||
```bash
|
||||
chown -R vmail:dovecot /etc/dovecot
|
||||
chmod -R o-rwx /etc/dovecot
|
||||
```
|
||||
|
||||
  修改`/etc/dovecot/conf.d/10-master.conf`:
|
||||
|
||||
首先将 imap-login , pop3-login 下第一个的 port 设置为 0,以禁用非 ssl 加密的 imap 和 pop3 协议,如下图所示:
|
||||

|
||||
|
||||
然后找到`service lmtp`将其修改为如下:
|
||||
|
||||
```
|
||||
service lmtp {
|
||||
unix_listener /var/spool/postfix/private/dovecot-lmtp {
|
||||
mode = 0600
|
||||
user = postfix
|
||||
group = postfix
|
||||
}
|
||||
|
||||
# Create inet listener only if you can't use the above UNIX socket
|
||||
#inet_listener lmtp {
|
||||
# Avoid making LMTP visible for the entire internet
|
||||
#address =
|
||||
#port =
|
||||
#}
|
||||
}
|
||||
```
|
||||
|
||||
然后找到`service auth`将其内容修改为如下:
|
||||
|
||||
```
|
||||
service auth {
|
||||
unix_listener /var/spool/postfix/private/auth {
|
||||
mode = 0666
|
||||
user = postfix
|
||||
group = postfix
|
||||
}
|
||||
|
||||
unix_listener auth-userdb {
|
||||
mode = 0600
|
||||
user = vmail
|
||||
#group =
|
||||
}
|
||||
|
||||
user = dovecot
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
最后找到`service auth-worker`改为如下内容:
|
||||
|
||||
```
|
||||
service auth-worker {
|
||||
# Auth worker process is run as root by default, so that it can access
|
||||
# /etc/shadow. If this isn't necessary, the user should be changed to
|
||||
# $default_internal_user.
|
||||
user = vmail
|
||||
}
|
||||
```
|
||||
|
||||
  最后要改的就是`/etc/dovecot/conf.d/10-ssl.conf`,以开启 ssl 认证.
|
||||
|
||||
首先将 ssl 参数改为 required:
|
||||
|
||||
```properties
|
||||
ssl = required
|
||||
```
|
||||
|
||||
然后设置 ssl 证书路径就 ok 了,还是用之前的 ssl 证书:
|
||||
|
||||
```properties
|
||||
ssl_cert = </etc/letsencrypt/live/test.com/fullchain.pem
|
||||
ssl_key = </etc/letsencrypt/live/test.com/privkey.pem
|
||||
```
|
||||
|
||||
  到这里所有的配置都 OK,重启 postfix,dovecot 后就可以用邮箱客户端(比如 foxmail)连接了。
|
||||
|
||||
```
|
||||
service postfix restart
|
||||
service dovecot restart
|
||||
```
|
||||
|
||||
# 结束
|
||||
|
||||
  配合一个邮件客户端看似很简单,实际上还是有很多坑的,看看上面那么多的配置项就知道了,一定要耐心。
|
||||
|
||||
  如果无法登陆,可以看看 postfix 和 dovecot 的日志报错情况,再去修改。日志位置在`/var/log`
|
||||
|
||||
**注意**:
|
||||
被这个问题困扰了好几天,未找到解决办法,最后放弃.
|
||||
|
||||
  目前很多主机厂商都不支持和其他服务器的 25 端口通信,已知的有(谷歌云,阿里云),这样就导致在这些机器上搭建的 postfix 邮件服务器,无法向其他的外网邮箱发送邮件,因为无法和其他 smtp 服务器的 25 端口建立连接。貌似是为了避免有人恶意搭建邮件服务器向其他的邮件服务器发送大量的垃圾邮件,从而导致此服务器 IP 被反垃圾邮件组织列入 SML。
|
||||
|
@ -1,53 +1,53 @@
|
||||
---
|
||||
id: '2019-04-02-10-58'
|
||||
date: '2019/04/02 10:58'
|
||||
title: '免费frp内网穿透'
|
||||
tags: ['frp', '免费', '内网穿透']
|
||||
categories:
|
||||
- '其他'
|
||||
---
|
||||
|
||||
**此网站已经挂了,需要内网穿透功能的可在下方留言,如果需要的人较多,我会搭建一个内网穿透服务供大家使用**
|
||||
|
||||
  公司调试需要公网 IP,遂在网上找了个免费的内网穿透--[http://ku2.kerwin.cn/](http://ku2.kerwin.cn/)。延迟还行一百多毫秒。
|
||||
|
||||
# 使用方法
|
||||
|
||||
## 下载软件
|
||||
|
||||
  首先下载 frp,下载地址:[https://github.com/fatedier/frp/releases](https://github.com/fatedier/frp/releases),选择对应的平台和版本,主要版本一定要和网站上的一致。
|
||||
|
||||
<!-- more -->
|
||||
|
||||
## 编写配置文件
|
||||
|
||||
  解压压缩包后编辑 frpc.ini
|
||||
|
||||
```properties
|
||||
[common]
|
||||
server_addr = frp.kerwin.cn
|
||||
server_port = 7000
|
||||
token = kerwin.cn
|
||||
# 名称随意,只是一个标识
|
||||
user = fleyx
|
||||
[web]
|
||||
type = http
|
||||
# 本地ip地址
|
||||
local_ip = 127.0.0.1
|
||||
# 要穿透的端口
|
||||
local_port = 8082
|
||||
# 可以将自己的域名cname到ku2.kerwin.cn
|
||||
# 如果没有自己的域名那也是可以的,可以在frp页面看别人的域名,然后在定义locations,就可以将此路径下的请求发送到本机
|
||||
# 下面这个域名就是别人的,然后我顺便借用下
|
||||
custom_domains = ck1.ck2014.win
|
||||
# 穿透路径
|
||||
locations = /fleyx
|
||||
```
|
||||
|
||||
## 启动
|
||||
|
||||
  启动命令如下:
|
||||
|
||||
```bash
|
||||
./frpc -c frpc.ini
|
||||
```
|
||||
---
|
||||
id: '2019-04-02-10-58'
|
||||
date: '2019/04/02 10:58'
|
||||
title: '免费frp内网穿透'
|
||||
tags: ['frp', '免费', '内网穿透']
|
||||
categories:
|
||||
- '其他'
|
||||
---
|
||||
|
||||
**此网站已经挂了,需要内网穿透功能的可在下方留言,如果需要的人较多,我会搭建一个内网穿透服务供大家使用**
|
||||
|
||||
  公司调试需要公网 IP,遂在网上找了个免费的内网穿透--[http://ku2.kerwin.cn/](http://ku2.kerwin.cn/)。延迟还行一百多毫秒。
|
||||
|
||||
# 使用方法
|
||||
|
||||
## 下载软件
|
||||
|
||||
  首先下载 frp,下载地址:[https://github.com/fatedier/frp/releases](https://github.com/fatedier/frp/releases),选择对应的平台和版本,主要版本一定要和网站上的一致。
|
||||
|
||||
<!-- more -->
|
||||
|
||||
## 编写配置文件
|
||||
|
||||
  解压压缩包后编辑 frpc.ini
|
||||
|
||||
```properties
|
||||
[common]
|
||||
server_addr = frp.kerwin.cn
|
||||
server_port = 7000
|
||||
token = kerwin.cn
|
||||
# 名称随意,只是一个标识
|
||||
user = fleyx
|
||||
[web]
|
||||
type = http
|
||||
# 本地ip地址
|
||||
local_ip = 127.0.0.1
|
||||
# 要穿透的端口
|
||||
local_port = 8082
|
||||
# 可以将自己的域名cname到ku2.kerwin.cn
|
||||
# 如果没有自己的域名那也是可以的,可以在frp页面看别人的域名,然后在定义locations,就可以将此路径下的请求发送到本机
|
||||
# 下面这个域名就是别人的,然后我顺便借用下
|
||||
custom_domains = ck1.ck2014.win
|
||||
# 穿透路径
|
||||
locations = /fleyx
|
||||
```
|
||||
|
||||
## 启动
|
||||
|
||||
  启动命令如下:
|
||||
|
||||
```bash
|
||||
./frpc -c frpc.ini
|
||||
```
|
@ -1,48 +1,48 @@
|
||||
---
|
||||
id: "20190430"
|
||||
date: "2019/04/30 10:58"
|
||||
title: "安利一个PS4游戏折扣查询的小工具"
|
||||
tags: ["PS4", "折扣", "提醒"]
|
||||
categories:
|
||||
- "其他"
|
||||
---
|
||||
|
||||
几个月前经受不住诱惑买了 PS4,港服的账号,发现商店不是那么的好用,遂想找一个查价格/折扣的小程序,但是呢没发现很好用的(switch 的主掌中宝就做的很不错),所以就自己做了一个。
|
||||
|
||||

|
||||
|
||||
断断续续开发了一个多月,基本功能都已实现。
|
||||
|
||||
<!-- more -->
|
||||
已实现功能如下:
|
||||
|
||||
- ps4,港服 游戏折扣信息以及已近全部收录
|
||||
- 支持关键词搜索
|
||||
- 支持按照语言、游戏类别等分类查询,按照游戏发现时间、热度等排序
|
||||
- 支持关注游戏折扣提醒
|
||||
|
||||
- 微信消息通知。需要在折扣发生的七天内使用过本小程序才能推送微信通知(微信的限制)
|
||||
- 邮件提醒。需要绑定自己的游戏,并把发验证码的那个邮箱地址加入到白名单中(可能会被某些邮件服务商当成垃圾邮件)
|
||||
|
||||
正在开发功能如下:
|
||||
|
||||
- 查看游戏的奖杯信息
|
||||
- 绑定PSN ID,查看自己的基本信息和奖杯信息
|
||||
|
||||
# 界面截图
|
||||
|
||||
## 主界面
|
||||
|
||||

|
||||
|
||||
## 详情页面
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## 关注页面
|
||||
|
||||

|
||||
|
||||
**PS**有兴趣一起开发的邮件我:fanxb.tl@gmail.com
|
||||
---
|
||||
id: "20190430"
|
||||
date: "2019/04/30 10:58"
|
||||
title: "安利一个PS4游戏折扣查询的小工具"
|
||||
tags: ["PS4", "折扣", "提醒"]
|
||||
categories:
|
||||
- "其他"
|
||||
---
|
||||
|
||||
几个月前经受不住诱惑买了 PS4,港服的账号,发现商店不是那么的好用,遂想找一个查价格/折扣的小程序,但是呢没发现很好用的(switch 的主掌中宝就做的很不错),所以就自己做了一个。
|
||||
|
||||

|
||||
|
||||
断断续续开发了一个多月,基本功能都已实现。
|
||||
|
||||
<!-- more -->
|
||||
已实现功能如下:
|
||||
|
||||
- ps4,港服 游戏折扣信息以及已近全部收录
|
||||
- 支持关键词搜索
|
||||
- 支持按照语言、游戏类别等分类查询,按照游戏发现时间、热度等排序
|
||||
- 支持关注游戏折扣提醒
|
||||
|
||||
- 微信消息通知。需要在折扣发生的七天内使用过本小程序才能推送微信通知(微信的限制)
|
||||
- 邮件提醒。需要绑定自己的游戏,并把发验证码的那个邮箱地址加入到白名单中(可能会被某些邮件服务商当成垃圾邮件)
|
||||
|
||||
正在开发功能如下:
|
||||
|
||||
- 查看游戏的奖杯信息
|
||||
- 绑定PSN ID,查看自己的基本信息和奖杯信息
|
||||
|
||||
# 界面截图
|
||||
|
||||
## 主界面
|
||||
|
||||

|
||||
|
||||
## 详情页面
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## 关注页面
|
||||
|
||||

|
||||
|
||||
**PS**有兴趣一起开发的邮件我:fanxb.tl@gmail.com
|
76
其他/git推送多个远程仓库.md
Normal file
76
其他/git推送多个远程仓库.md
Normal file
@ -0,0 +1,76 @@
|
||||
---
|
||||
id: "20220223"
|
||||
date: "2022/02/23 10:38:05"
|
||||
title: "git配置多个远程地址"
|
||||
tags: ["git", "私有仓库", "gitlab", "gogs"]
|
||||
hide: false
|
||||
index_img: https://qiniupic.fleyx.com/blog/202202231638624.png?imageView2/2/w/200
|
||||
banner_img: https://qiniupic.fleyx.com/blog/202202231638624.png
|
||||
categories:
|
||||
- "其他"
|
||||
---
|
||||
|
||||
天下苦 github 久已,鉴于国内网络环境对 github 的种种限制,导致 github 的使用体验比较差,于是考虑搭建一个私有的 git 代码管理平台。对比了多种方案最后选择了[gogs](https://gogs.io/),主要优点如下:
|
||||
|
||||
- 底层基于 go,运行速度很快,资源消耗低
|
||||
- 功能简介,没有各种花里胡哨的功能
|
||||
- 代码开源
|
||||
|
||||
<!-- more -->
|
||||
|
||||
具体部署过程不在这里展开,官网有详细的中文文档。
|
||||
|
||||
**PS:不要使用 gogs 自带的 ssh 服务,支持的协议比较少。如果物理机部署直接用物理机的 ssh 就行了,如果 docker 部署可将其它端口映射到 docker 容器的 ssh 端口(22)**
|
||||
|
||||
那么问题就产生了,如果有些项目需要推送到 github 怎么办?
|
||||
|
||||
配置多个远程地址即可,按需推送到远程。方法如下:
|
||||
|
||||
## 支持多个远程地址,实现默认拉取,推送操作私有地址
|
||||
|
||||
1. 先将 github 的 remote 名改为 github
|
||||
|
||||
```bash
|
||||
git remote rename origin github
|
||||
```
|
||||
|
||||
2. 再增加私有平台的 ssh 地址
|
||||
|
||||
```bash
|
||||
git remote add origin ssh://xxxxxxxxxxxxxxxxx.git
|
||||
```
|
||||
|
||||
3. 拉取私有平台的 master 地址
|
||||
|
||||
```bash
|
||||
git pull origin master
|
||||
```
|
||||
|
||||
4. 将本地 master 和私有平台 master 关联起来,实现操作操作私有平台
|
||||
|
||||
```bash
|
||||
git branch --set-upstream-to=origin/master master
|
||||
```
|
||||
|
||||
关联后,执行 git push,git pull 命令默认都是操作的 origin(也就是私有平台)
|
||||
|
||||
## 拉取推送 github
|
||||
|
||||
操作非默认分支时需要指定远程地址
|
||||
|
||||
```bash
|
||||
# 表示拉取远程 master 分支
|
||||
git pull github master
|
||||
# 表示推送到 github 上
|
||||
git push github
|
||||
```
|
||||
|
||||
## 进行分支切换
|
||||
|
||||
当切换到一个远程分支时需要指定远程地址,比如下面命令切换到 origin/dev 分支:
|
||||
|
||||
```bash
|
||||
git checkout --track origin/dev
|
||||
```
|
||||
|
||||
**PS:在进行 push 操作前最后先 pull 一次。**
|
Loading…
x
Reference in New Issue
Block a user