iOS14搭配快捷指令在手机上写hexo博客

这次研究的课题是用iOS快捷指令通过ssh执行远程服务器上的操作,如果你没有服务器也没有iOS设备,那么你可以图一乐。

起因

最近工作忙/天冷/吃饱了撑的,导致睡眠不怎么规律,昨天下班到家就睡着了,结果8点多醒了,这就导致了半夜睡不太着觉。突然想起博客年久失修,生活博客半年没更,技术博客半年内倒是更了两个,但都是写了标题没写多少内容。不玩lol了之后是越来越懒得动电脑,家里的台式机也就是在吃饭的时候才打开20分钟用B站下饭。由于博客使用hexo搭建,不开电脑的话更新的几率就很小。所以我就想,我能不能在手机上写博客,再用一种快捷的方式推送到服务器上

之前的操作

对于技术博客,通常就是学习到了新东西或者有一些阿妹子嘤的新发现,趁着兴奋劲在电脑上就写了;对于另一个生活博客,通常是在手机上用zine写完,再等有空(划水)的时候在电脑上同步一下。

对于hexo,通常是用

1
hexo new postname

创建一个markdown文件,写好内容后使用

1
2
hexo clean
hexo g

生成静态页,再复制到nginx配置中对应的网站目录,这一番操作过后,新的创作就对外显示了。

由于这一番操作太复杂,我还搭建了jenkins,配合git来了一波自动部署。这样每次写完内容,只需要push到git上,就可以等待jenkins帮我把后续工作处理好了。这一番操作被我记录在了搭建jenkins配合gitee实现自动部署里。

新的想法

我可以不可以在手机上编写好内容,然后通过app的分享,把内容分享给iOS的快捷指令,然后拜托快捷指令帮我把内容上传到服务器,顺便同步到git,再自动部署呢?

打开快捷指令app,发现是有ssh功能的

这样思路基本就清晰了

  • 用app分享文件给快捷指令
  • 通过ssh传到服务器
  • 服务器把文件内容保存下来
  • 从git下载仓库
  • 用yarn安装hexo
  • 把博文内容移动到hexo目录下
  • 构建hexo
  • 复制hexo静态文件到网站目录
  • 输出成功

开始实操

接受来自分享的数据

在快捷指令的设置里,可以设置当前快捷指令接受哪些消息,顺便我们用“显示结果”把获取到的内容显示出来以供调试。

需要注意的是,显示结果时需要选择“作为文件”。

打开备忘录,随便分享一个文件进来,可以看到快捷指令已经接收到了分享过来的备忘录,并显示了内容。

选择仓库

由于有两个博客,所以每次推送的时候需要手动选择要推送的博客。这里用到了快捷指令的列表从列表选取的功能。

增加了这一步骤,顺便我们让它们一起展示出来。

编码传输

在实际操作过程中,我发现如果是用简单的echo markdown_content >> markdown_file.md的方式来保存文件内容是不可行的,原因有二:

  1. echo内容的时候会被markdown里不可预料的字符截断。
  2. 使用echo的话还需要处理换行等特殊字符。

可能还有其他麻烦事我没遇到,仅仅是这两个麻烦的问题就够我麻烦半天了。在友人Hermit的建议下,我决定使用base64传输博文数据。这样就算是换行都能处理在里边了。


可以看到,原文里不管是有换行还是特殊符号,一律转码成奇怪的人类看不懂的字符了。这边转成了base64,就肯定要在某个地方转换回来。我们只有指望服务器那边的shell能解码了。由于博客是在完成了之后才写的,所以我知道shell肯定能解码。

快捷指令连接服务器

在连接服务器的时候我们有两个选择,一个是用密码连接,一个是用SSH密钥连接。

由于我在电脑上一直是用SSH连接,所以这次也直接就想到用SSH连接了。生成密钥-上传到服务器一气呵成之后,出现了一个奇怪的问题。在快捷指令app里直接点击快捷指令运行时可以用SSH连接到服务器,脚本也都正常运行,也能正常输出结果,但是通过分享触发快捷指令时,服务器就会连接失败。调试了很多次之后放弃了SSH连接,改为密码登录了。

本来后续的文件处理、构建、同步git等操作都准备在快捷指令写的,转念一想,好像操作挺多的。决定在服务器上写个脚本执行后续操作,快捷指令只负责传值就好了。

在这一步,我们只需要把这几个参数

  • 博客名
  • 文件名
  • 博文内容(base64)

传过去就可以了。

编写脚本

由于之前没怎么写过shell脚本,这一步可是费了好大的劲。但写博客就简单了,我直接复制过来就可以了。注释写得很全,就不多写别的了。

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
# 文件名,用在hexo new {filename}
postname="$3.md"

# 分类 blog_tech blog_life
category=$1

# 博客内容
content=$2

echo 文件名是
echo $postname

echo 分类是
echo $category

echo 内容长度
echo ${#content}


# 写入本地文件
echo $content | base64 -d > $postname
echo 写入本地文件成功
# 上传到git
rm -rf blog_$category
git clone -b $category git@gitee.com:xtzero/blog.git blog_$category
mv $postname blog_$category/source/_posts
cd blog_$category
git add source/_posts/$postname
git commit -m 'write by phone'
git push
echo 已经上传到git

# 生成hexo静态文件
yarn install
hexo clean
hexo g

# 转移到网站目录
cd ..
rm -rf /data/www/blog/$category
cp -R blog_$category /data/www/blog/$category

echo 🍺全部完成~!

调试

为了写这篇博客,我又传上去了一篇测试文章。从步骤和结果来看,是生效了。

在分享中点击快捷指令

进度条的速度取决于脚本的运行时间,由于涉及了git、hexo的操作,进度条还是挺慢的。

进度条转完了之后会显示运行结果,由于想看完整的输出,我就把全部输出都搞出来了。

由于想让各位也看看都输出了啥,我决定把图片上没显示完全的东西给复制出来。

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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
文件名是
writebyphone20201231151624.md
分类是
tech
内容长度
72
写入本地文件成功
Cloning into 'blog_tech'...
[tech 4bc2ca3] write by phone
1 file changed, 5 insertions(+)
create mode 100644 source/_posts/writebyphone20201231151624.md
已经上传到git
yarn install v1.21.1
info No lockfile found.
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@2.1.3: The platform "linux" is incompatible with this module.
info "fsevents@2.1.3" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
Done in 4.71s.
INFO Start processing
INFO
------------------------------------------------
| |
| ________ __ _ __ |
| |_ __ |[ | (_) | ] |
| | |_ \_| | | __ _ __ .--.| | |
| | _| | |[ | | | [ |/ /'`\' | |
| _| |_ | | | \_/ |, | || \__/ | |
| |_____| [___]'.__.'_/[___]'.__.;__] |
| |
| Thank you for using Fluid theme ! |
| Docs: https://hexo.fluid-dev.com/docs/en/ |
| |
------------------------------------------------

Version 9 of Highlight.js has reached EOL and is no longer supported.
Please upgrade or ask whatever dependency you are using to upgrade.
https://github.com/highlightjs/highlight.js/issues/2877
INFO Files loaded in 2.14 s
INFO Generated: xtblog_rss.xml
INFO Generated: local-search.xml
INFO Generated: 404.html
INFO Generated: index.html
INFO Generated: about/index.html
INFO Generated: children/index.html
INFO Generated: client/index.html
INFO Generated: features/index.html
INFO Generated: friends/index.html
INFO Generated: index/index.html
INFO Generated: me/shortWorks.html
INFO Generated: archives/index.html
INFO Generated: tags/index.html
INFO Generated: categories/index.html
INFO Generated: links/index.html
INFO Generated: teapot/index.html
INFO Generated: me/skills.html
INFO Generated: me/index.html
INFO Generated: me/inSchool.html
INFO Generated: me/old20200513.html
INFO Generated: img/avatar.png
INFO Generated: xml/local-search.xml
INFO Generated: me/me202005.docx
INFO Generated: img/favicon.png
INFO Generated: img/default.png
INFO Generated: img/loading.gif
INFO Generated: img/police_beian.png
INFO Generated: archives/page/2/index.html
INFO Generated: archives/2017/12/index.html
INFO Generated: archives/2018/01/index.html
INFO Generated: archives/2019/03/index.html
INFO Generated: archives/2020/02/index.html
INFO Generated: page/2/index.html
INFO Generated: archives/page/3/index.html
INFO Generated: archives/page/4/index.html
INFO Generated: archives/2018/02/index.html
INFO Generated: archives/2018/04/index.html
INFO Generated: archives/2018/05/index.html
INFO Generated: archives/2018/08/index.html
INFO Generated: archives/2018/10/index.html
INFO Generated: archives/2019/07/index.html
INFO Generated: archives/2019/08/index.html
INFO Generated: archives/2019/11/index.html
INFO Generated: archives/2019/12/index.html
INFO Generated: archives/2020/03/index.html
INFO Generated: archives/2020/04/index.html
INFO Generated: archives/2020/11/index.html
INFO Generated: archives/2020/12/index.html
INFO Generated: categories/技术学习/index.html
INFO Generated: categories/技术吹逼/index.html
INFO Generated: tags/php/index.html
INFO Generated: tags/小程序/index.html
INFO Generated: tags/javascript/index.html
INFO Generated: tags/xss/index.html
INFO Generated: tags/散装技术/index.html
INFO Generated: tags/composer-php/index.html
INFO Generated: tags/布朗熊与可妮兔/index.html
INFO Generated: tags/屏保/index.html
INFO Generated: tags/域名-网站/index.html
INFO Generated: tags/github-hosts/index.html
INFO Generated: tags/laravel-php/index.html
INFO Generated: archives/2017/index.html
INFO Generated: archives/2018/index.html
INFO Generated: archives/2019/index.html
INFO Generated: archives/2020/index.html
INFO Generated: tags/markdown/index.html
INFO Generated: tags/es6-promise-javascript/index.html
INFO Generated: tags/bash-shell/index.html
INFO Generated: tags/shell/index.html
INFO Generated: tags/swift/index.html
INFO Generated: tags/yapi-接口管理/index.html
INFO Generated: page/3/index.html
INFO Generated: page/4/index.html
INFO Generated: me/me202005.pdf
INFO Generated: css/gitalk.css
INFO Generated: js/boot.js
INFO Generated: js/color-schema.js
INFO Generated: js/debouncer.js
INFO Generated: js/events.js
INFO Generated: js/lazyload.js
INFO Generated: js/leancloud.js
INFO Generated: js/local-search.js
INFO Generated: js/plugins.js
INFO Generated: js/utils.js
INFO Generated: css/main.css
INFO Generated: lib/hint/hint.min.css
INFO Generated: archives/2019/page/2/index.html
INFO Generated: categories/技术学习/page/2/index.html
INFO Generated: 2020/12/31/writebyphone20201231151624/index.html
INFO Generated: 2019/12/27/brown/index.html
INFO Generated: 2018/10/25/181025/index.html
INFO Generated: 2017/12/17/171217/index.html
INFO Generated: 2019/11/27/domaincandowhat/4.jpg
INFO Generated: 2020/04/15/jenkins202004/Xnip2020-04-15_21-49-11.png
INFO Generated: 2019/08/03/pleaseusemarkdown/sendbyaxios.jpg
INFO Generated: 2020/02/15/makepostcard2020/Xnip2020-02-16_14-37-46.png
INFO Generated: 2019/07/07/190707/2.png
INFO Generated: 2020/03/14/autohealthy202003/Xnip2020-03-14_11-35-35.png
INFO Generated: 2020/11/16/macnopower202011/index.html
INFO Generated: 2019/03/31/190331/index.html
INFO Generated: 2018/08/28/180828/index.html
INFO Generated: 2018/05/23/180523-2/index.html
INFO Generated: 2018/04/17/180417/index.html
INFO Generated: 2018/02/18/180218/index.html
INFO Generated: 2018/01/04/180104/index.html
INFO Generated: 2020/02/04/windowsbug/index.html
INFO Generated: 2019/12/18/shellHotkey/index.html
INFO Generated: 2019/08/07/aliyuncomposer/index.html
INFO Generated: 2018/08/24/180824/index.html
INFO Generated: 2019/11/28/yapi1-1/10.jpg
INFO Generated: 2020/11/15/front-struct-202011/index.html
INFO Generated: 2019/12/26/githubhosts/index.html
INFO Generated: 2020/04/09/gitlabrunner202004/index.html
INFO Generated: 2019/12/15/swift2/index.html
INFO Generated: 2019/12/17/swift3/index.html
INFO Generated: 2019/12/14/swift1/index.html
INFO Generated: 2019/12/11/shell20191211/index.html
INFO Generated: 2019/08/15/promise/index.html
INFO Generated: 2019/08/05/laravelnote/index.html
INFO Generated: 2018/05/23/180523/index.html
INFO Generated: 2020/04/15/byegithub202004/Xnip2020-04-15_17-54-50.png
INFO Generated: 2019/08/07/laravel2/index.html
INFO Generated: 2019/11/28/yapi1-1/8.jpg
INFO Generated: 2019/08/03/pleaseusemarkdown/Xnip2019-08-04_13-10-42.jpg
INFO Generated: 2019/08/03/pleaseusemarkdown/Xnip2019-08-04_13-12-30.jpg
INFO Generated: 2020/04/15/jenkins202004/Xnip2020-04-15_21-21-30.png
INFO Generated: 2019/12/27/brown/Xnip2019-12-27_23-48-45.jpg
INFO Generated: 2019/12/27/brown/1577461641987.jpg
INFO Generated: 2020/04/15/jenkins202004/Xnip2020-04-15_21-27-48.png
INFO Generated: 2020/04/15/jenkins202004/Xnip2020-04-15_21-48-17.png
INFO Generated: 2020/04/15/jenkins202004/Xnip2020-04-15_21-48-22.png
INFO Generated: 2020/04/15/jenkins202004/Xnip2020-04-15_21-51-14.png
INFO Generated: 2019/11/28/yapi1-1/11.jpg
INFO Generated: 2020/02/15/makepostcard2020/Xnip2020-02-16_14-38-05.png
INFO Generated: 2020/02/15/makepostcard2020/image-20200215204839677.png
INFO Generated: 2019/08/03/pleaseusemarkdown/WeChat952c26237293beeef80e2ea3f9577153.png
INFO Generated: 2020/04/15/byegithub202004/Xnip2020-04-15_17-58-02.png
INFO Generated: 2020/04/15/jenkins202004/Xnip2020-04-15_21-47-44.png
INFO Generated: 2019/11/28/yapi1-1/5.jpg
INFO Generated: 2019/11/28/yapi1-1/6.jpg
INFO Generated: 2019/11/28/yapi1-1/2.jpg
INFO Generated: 2020/04/15/jenkins202004/index.html
INFO Generated: 2020/04/15/byegithub202004/index.html
INFO Generated: 2020/03/14/autohealthy202003/index.html
INFO Generated: 2019/11/28/yapi1-1/index.html
INFO Generated: 2020/02/15/makepostcard2020/index.html
INFO Generated: 2019/11/27/domaincandowhat/index.html
INFO Generated: 2019/08/03/pleaseusemarkdown/index.html
INFO Generated: 2019/07/07/190707/index.html
INFO Generated: 2019/11/28/yapi1-1/1.jpg
INFO Generated: 2019/11/28/yapi1-1/7.jpg
INFO Generated: 2019/11/28/yapi1-1/9.jpg
INFO Generated: 2020/04/15/byegithub202004/Xnip2020-04-15_17-43-51.png
INFO Generated: 2019/11/27/domaincandowhat/1.jpg
INFO Generated: 2019/11/27/domaincandowhat/2.jpg
INFO Generated: 2019/11/27/domaincandowhat/3.jpg
INFO Generated: 2019/08/03/pleaseusemarkdown/pleaseusemarkdown.jpg
INFO Generated: 2019/08/03/pleaseusemarkdown/sendbymyajax.jpg
INFO Generated: 2020/04/15/jenkins202004/Xnip2020-04-15_21-23-51.png
INFO Generated: 2020/04/15/jenkins202004/Xnip2020-04-15_21-28-37.png
INFO Generated: 2019/11/28/yapi1-1/3.jpg
INFO Generated: 2019/11/28/yapi1-1/4.jpg
INFO Generated: 2020/02/15/makepostcard2020/Xnip2020-02-15_20-50-16.png
INFO Generated: 2020/02/15/makepostcard2020/Xnip2020-02-16_13-24-08.png
INFO Generated: 2020/02/15/makepostcard2020/Xnip2020-02-16_13-26-19.png
INFO Generated: 2020/02/15/makepostcard2020/Xnip2020-02-16_14-32-33.png
INFO Generated: 2020/02/15/makepostcard2020/Xnip2020-02-16_14-34-24.png
INFO Generated: 2020/02/15/makepostcard2020/Xnip2020-02-16_14-50-56.png
INFO Generated: 2020/02/15/makepostcard2020/Xnip2020-02-16_14-52-26.png
INFO Generated: 2020/02/15/makepostcard2020/githubrepo.png
INFO Generated: 2020/02/15/makepostcard2020/nightqr.png
INFO Generated: 2020/02/15/makepostcard2020/banner.png
INFO Generated: 2019/08/03/pleaseusemarkdown/Xnip2019-08-04_13-14-36.jpg
INFO Generated: 2019/07/07/190707/1.png
INFO Generated: 2020/04/15/jenkins202004/Xnip2020-04-15_21-49-30.png
INFO 175 files generated in 983 ms
🍺全部完成~!

再打开git,发现git上显示了今天调试过程中的提交记录:

打开页面发现内容也更新上去了

这还愣着干啥,完事了就。

总结

  1. shell脚本真难写,if的格式都有要求。可能不是shell太难,是我平时不用,没怎么写过。以后多写就好了。

  2. 那个通过分享触发的不能用SSH密钥登录的问题到最后也没解决,等下次(3000年13月32日)再看看。

  3. 粘贴运行结果太无耻了,但是字数一下子就上来了,还是原创。

  4. 这篇博客我决定也用这个快捷指令发送,但我是在电脑上写的,我还得想办法给拿到手机上去。

  5. 用快捷指令发送博客的话还没法处理图片,下一步准备搭个图床,用手机写博客的时候直接粘贴图床链接就好了。

  6. 手机真难用,改个root密码从11点改到2点还没成功。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!