虚拟机ftp服务器上发布文件,通过Shell脚本以FTP方式上传文件到虚拟主机实现Hexo博客自动发布...

通过Shell脚本以FTP方式上传文件到虚拟主机实现Hexo博客自动发布

夜月归途 • 2019 年 12 月 28 日

写这篇是因为最近将博客从服务器迁移到虚拟主机上了,我需要在Linux服务器上将我的Hexo博客编译后的静态页面上传至虚拟主机上,我的虚拟主机上传文件有且仅有一种方式:FTP。

先说下我想实现的自动部署流程,我在Jenkins上做了监听,一旦我的Hexo代码仓库有新的提交,会触发任务脚本执行发布操作。具体要做的事都写在Shell脚本上,主要流程如下:脚本配置,配置Hexo工作目录,静态文件上传目录,FTP配置信息等;

进入Hexo工作目录,更新代码,清除缓存,编译生成静态页面;

递归读取Hexo静态页面目录,上传博客静态页文件到FTP空间对应的目录;

执行Hexo deploy命令,发布静态页面,我这里配置的是发布到Github;

流程大概就是这样,Shell脚本好说,FTP工具命令是踩了不少坑。说实话这FTP工具很不友好,一些常用的功能不支持,比如不能一次创建多级目录,只能一级一级逐层创建。

那为什么不用Hexo集成的FTPSync上传插件?我试过了,怎么都上传不成功,要么卡在MKDIRs complete.上,要么卡在Committing这里,日志如下:# 初次发布,会先创建文件夹,文件夹创建成功后就卡主了不动了

...

- /htdocs/tags/随笔 created successfuly

- /htdocs/tags/隐式转换 created successfuly

MKDIRs complete.

# 到这里卡主不动,退出重新发布一次的话,前面文件夹已经创建了,这时候卡在提交文件这里了

...

Remove:[]

Consolidation complete.

Committing

-------------------------------------------------------------

# 再次卡在这里,FTP空间里目录创建成功了,文件一个没上传上去

FTPSync插件问题有待后续跟进,其实我做成现在这套流程也是有我自己的用处的,我可以在发布脚本中加入一些自定义操作,配合Jenkins能实现很多实用的功能。

部署流程有了,那么先安装FTP工具:yum install ftp -y

关于Linux上FTP工具命令详解文末有附上,这里先贴上我的发布脚本:#!/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 <

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 <

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工具的详细使用说明我找到了这篇博客:

这里引用一些常用的命令及参数:ftp(选项)(参数)

-d:详细显示指令执行过程,便于排错或分析程序执行的情况;

-i:关闭互动模式,不询问任何问题;

-g:关闭本地主机文件名称支持特殊字符的扩充特性;

-n:不使用自动登录;

-v:显示指令执行过程。

登录FTP实例后内部命令: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 写作需求。