写这篇是因为最近将博客从服务器迁移到虚拟主机上了,我需要在Linux服务器上将我的Hexo博客编译后的静态页面上传至虚拟主机上,我的虚拟主机上传文件有且仅有一种方式:FTP。
先说下我想实现的自动部署流程,我在Jenkins上做了监听,一旦我的Hexo代码仓库有新的提交,会触发任务脚本执行发布操作。具体要做的事都写在Shell脚本上,主要流程如下:
- 脚本配置,配置Hexo工作目录,静态文件上传目录,FTP配置信息等;
- 进入Hexo工作目录,更新代码,清除缓存,编译生成静态页面;
- 递归读取Hexo静态页面目录,上传博客静态页文件到FTP空间对应的目录;
- 执行Hexo deploy命令,发布静态页面,我这里配置的是发布到Github;
流程大概就是这样,Shell脚本好说,FTP工具命令是踩了不少坑。说实话这FTP工具很不友好,一些常用的功能不支持,比如不能一次创建多级目录,只能一级一级逐层创建。
那为什么不用Hexo集成的FTPSync上传插件?我试过了,怎么都上传不成功,要么卡在MKDIRs complete.上,要么卡在Committing这里,日志如下:
1 2 3 4 5 6 7 8 9 10 11 12
| # 初次发布,会先创建文件夹,文件夹创建成功后就卡主了不动了 ... - /htdocs/tags/随笔 created successfuly - /htdocs/tags/隐式转换 created successfuly MKDIRs complete. # 到这里卡主不动,退出重新发布一次的话,前面文件夹已经创建了,这时候卡在提交文件这里了 ... Remove:[] Consolidation complete. Committing ------------------------------------------------------------- # 再次卡在这里,FTP空间里目录创建成功了,文件一个没上传上去
|
FTPSync插件问题有待后续跟进,其实我做成现在这套流程也是有我自己的用处的,我可以在发布脚本中加入一些自定义操作,配合Jenkins能实现很多实用的功能。
部署流程有了,那么先安装FTP工具:
关于Linux上FTP工具命令详解文末有附上,这里先贴上我的发布脚本:
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
| #!/bin/bash # 博客工作目录 export BLOG_PATH=/develop/hexo # 待上传的博客静态文件目录 export UPLOAD_PATH=/develop/hexo/public
# FTP空间访问地址 export FTP_HOST=guitu18.com # FTP空间网站根路径 export FTP_ROOT_PATH=/htdocs # FTP用户名 export FTP_USERNAME=guitu18.com # FTP密码 export FTP_PASSWORD=guitu18.com
# 进入博客工作目录 cd $BLOG_PATH echo -e "\033[44;37m>>> 博客文件更新 >>>\033[0m" svn up echo -e "\033[44;37m>>> 清除缓存文件 >>>\033[0m" hexo cl echo -e "\033[44;37m>>> 编译生成静态页面 >>>\033[0m" hexo g
echo -e "\033[44;37m>>> 开始上传到FTP空间 >>>\033[0m" # 递归读取目录 read_dir(){ # 遍历文件夹 for file in `ls -a $1`; do # 当前文件完整路径 localFile=$1/$file # 截取掉本地路径 len=${#UPLOAD_PATH} # 截取当前文件所属目标文件夹 mdir=${1:$len} # 如果file存在且是一个目录 if [ -d $localFile ]; then # 排除.和..目录 if [[ $file != '.' && $file != '..' ]]; then # 登录FTP,在FTP空间创建对应的文件夹 ftp -n <<EOF open $FTP_HOST user $FTP_USERNAME $FTP_PASSWORD !echo '>>>mkdir: '$FTP_ROOT_PATH$mdir/$file mkdir $FTP_ROOT_PATH$mdir/$file close bye EOF read_dir $localFile fi else # 如果是文件,上传文件到FTP空间 ftp -n <<EOF open $FTP_HOST user $FTP_USERNAME $FTP_PASSWORD cd $FTP_ROOT_PATH$mdir lcd $1 binary hash prompt !echo '>>> upload: '$localFile put $file close bye EOF echo '>>> upload: '$localFile ' ===> 文件上传完成' fi done } # 执行 read_dir $UPLOAD_PATH
echo -e "\033[44;37m>>> 发布完成 >>>\033[0m" echo -e "\033[44;37m>>> 推送至GitHub >>>\033[0m" # 执行Hexo发布命令,发布到GitHub hexo d echo -e "\033[44;37m>>> 推送至GitHub完成 >>>\033[0m"
|
在脚本开头配置好相关参数就可以使用了,因为FTP是每次传输都需要握手,所以整个自动发布流程中最慢就是FTP上传了。
关于FTP工具的详细使用说明我找到了这篇博客:Linux文件传输FTP详解,每个命令说明讲的都比较详细了。
这里引用一些常用的命令及参数:
1 2 3 4 5 6
| ftp(选项)(参数) -d:详细显示指令执行过程,便于排错或分析程序执行的情况; -i:关闭互动模式,不询问任何问题; -g:关闭本地主机文件名称支持特殊字符的扩充特性; -n:不使用自动登录; -v:显示指令执行过程。
|
登录FTP实例后内部命令:
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
| ls: 显示服务器上的目录 get: 从服务器下载指定文件到客户端 put: 从客户端传送指定文件到服务器 open: 连接ftp服务器 quit: 断开连接并退出ftp服务器 cd directory: 改变服务器的当前目录为directory lcd directory: 改变本地的当前目录为directory bye: 退出ftp命令状态 ascii: 设置文件传输方式为ASCII模式 binary: 设置文件传输方式为二进制模式
cd: 切换远端ftp服务器上的目录 cdup: 上一层目录 close: 在不结束ftp进程的情况下,关闭与ftp服务器的连接 delete: 删除远端ftp服务器上的文件 get: 下载 hash: 显示#表示下载进度 mdelete: 删除文件,模糊匹配 mget: 下载文件,模糊匹配 mput: 上传文件,模糊匹配 mkdir: 在远端ftp服务器上,建立文件夹 newer: 下载时,检测是不是新文件 prompt: 关闭交互模式 put: 上传 pwd: 显示当前目录
|
各种各样的博客系统折腾多了,终究是要返璞归真,选择将工具和内容剥离的方式,回到最初始、最纯净的 Markdown 写作需求。
Hexo,你值得拥有。