前几天刚把博客迁移了过来,顺便更了两篇文章。想着每次写完文章(或者对原来的文章作改动)就要手动部署下有点麻烦,尝试寻找自动更新博客方案。
fswatch
实现自动更新博客关键在于检测文件变动,根据这个思路我找到了fswatch
。
fswatch
是一个跨平台的文件更改监视器,在指定的文件或目录的内容被改变或修改时会做出通知。man fswatch
得到的描述如下:
fswatch -- Ask for notification when the contents of the specified files or directory hierarchies are modified.
用brew安装好后,简单使用一下,fswatch的用法是:
fswatch (option)* path+
下面demo包含了fswatch
监控文件创建,修改与删除操作:
display dialog
若终端脚本在后台运行时出现异常(自动部署失败),不能只是写入日志还需要主动提醒(例如弹窗),在macOS下我找到了AppleScript。
Applescript是适用于macOS的一种脚本语言,可以用于直接控制macOS上的应用程序,来实现macOS的自动化。这里我用AppleScript中的display dialog来实现弹窗功能:
#!/usr/bin/env osascript
tell app "System Events"
display dialog "required dialog text" buttons {"optional button text 1", "optional button text 2"} with title "optional dialog title text"
get the button returned of the result
end tell
运行上面这个脚本将弹出一个dialog,窗口内容为”required dialog text”,窗口内有两个按钮”optional button text 1”和”optional button text 2”,窗口名为”optional dialog title text”,点击按钮后脚本返回所选按钮的文本。
AppleScript需要用osascript命令来运行:
# 方式一:
osascript applescript.scpt
# 方式二:
osascript -e 'script command'
# 方式三: 使用heredoc: http://www.tldp.org/LDP/abs/html/here-docs.html, 这种方式可以很好地解决bash到AppleScript的参数传递问题
osascript <<-'END'
script command
END
自动部署博客脚本
利用fswatch
和display dialog
可以得到如下auto-blog-submit.sh脚本:
BLOG_PATH=/Users/barriery/Blog/ # your blog root path
LOG_PATH=${BLOG_PATH}/auto-blog-submit.log
ARTICLE_PATH=${BLOG_PATH}/source/_posts
function showDialog(){
osascript -e 'tell app "System Events"
display dialog "[ERROR] Hexo deploy failed." buttons {"View Log", "Cancel"} default button "View Log" with title "auto-blog-submit.sh"
get the button returned of the result
end tell'
}
cd ${BLOG_PATH} # Otherwise the script will run in the home path
if [ ! -f ${LOG_PATH} ]; then
touch ${LOG_PATH}
fi
nohup fswatch -o ${ARTICLE_PATH} -l 900 | while read
do
date "+%Y-%m-%d %H:%M:%S" >> ${LOG_PATH}
hexo g -d >/dev/null 2>> ${LOG_PATH}
if [ $? -ne 0 ]; then
echo "\033[31m[ERROR]\033[0m Hexo deploy failed." >> ${LOG_PATH}
say "自动部署博客脚本出现异常"
botton_returned=$(showDialog)
echo "\033[33m[INFO]\033[0m You choose \033[33m${botton_returned}\033[0m" >> ${LOG_PATH}
# ${botton_returned} 加引号防止变量中空格造成影响
if [ "${botton_returned}" = "Cancel" ]; then
: # Do nothing beyond expanding arguments and performing redirections. The return status is zero.
elif [ "${botton_returned}" = "View Log" ]; then
open -a Sublime\ Text ${LOG_PATH} # Using Sublime to open log file.
fi
fi
done &
其中,fswatch
的-o
参数是仅输出监控到的事件数;-l
参数指定了潜伏时间,这里结束一次监控后潜伏900秒(默认为1秒)做下一次监控。
该脚本放监控${BLOG_PATH}/source/_posts
中的文件(也就是自己写的文章放置的位置),当文件变动时会将log写入${BLOG_PATH}/auto-blog-submit.log
中,并重新部署博客。当脚本出现异常的时候,语音播报”自动部署博客脚本出现异常”,并弹出窗口提示脚本出现异常。
开机自动运行脚本
需要开机运行脚本才能使得博客能够一直更新。
Mac上设置开机自动运行如下:
系统偏好设置 -> 用户与群组 -> 当前用户 -> 登录项 -> 添加脚本
同时设置脚本默认打开方式(iTerm或Terminal)并需要给予脚本root权限:
chmod 777 auto-blog-submit.sh
About
刚开始测试脚本的时候,发现开机自动运行会保留终端窗口,所以需要挂在后台运行,用到nohup
。
nohup
可以让程序始终在后台执行,即使关闭当前的终端或退出账户也能继续执行(而用&
关闭终端则会停止运行)。用法:
nohup command &
关闭终端后,在另一个终端用jobs
已经无法看到后台跑的程序了,此时利用ps进程查看命令:
ps -Ao pid,user,start,command | grep "auto-blog-submit.sh" # Linux: ps -aux | grep "auto-blog-submit.sh"
找到进程号后,开源用kill
杀进程:
kill -9 进程号