0%

转载 https://zhuanlan.zhihu.com/p/150889781

如何优雅地管理 GitHub 上 star 的项目

GitHub Star管理工具很多,或是插件,或是网站.我想,纯文本还是最简单的方法,如果把它以一定格式导出来,发布到知乎专栏上可能更方便查看和分享,下面谈做法.

安装PyGithub

pip install PyGithub

导出stars.csv

这里使用github上的export-stars项目来导出. github.com/JeffCarpenter/export-stars

GH_USER=yourGithubusername python3 export_stars.py > stars.csv

由csv文本转markdown格式并用split分割

stars.csv内容例如

1
2
3
4
https://github.com/TheAlgorithms/C,All Algorithms implemented in C 
https://github.com/TheAlgorithms/C-Plus-Plus,All Algorithms implemented in C++
https://github.com/mitmath/1806,18.06 course at MIT
用sed过滤器将其转换为markdown的链接形式,这里用了捕获组这点小知识.
1
sed "s#\(https://github.com/\)\([^,]*\),#- [\2](\1\2)#g" test.txt

转换之后

1
2
3
- [TheAlgorithms/C](https://github.com/TheAlgorithms/C)All Algorithms implemented in C 
- [TheAlgorithms/C-Plus-Plus](https://github.com/TheAlgorithms/C-Plus-Plus)All Algorithms implemented in C++
- [mitmath/1806](https://github.com/mitmath/1806)18.06 course at MIT

sed可以用-i选项直接改源文件.这里只列了三行,假设stars.csv里有1800行,那么-l参数设300可以把文件拆成 6份.我这样做了,一个个以markdown导出来,发在另一个专栏中,感兴趣的小伙伴可以看看.

1
2
sed -i "s#\(https://github.com/\)\([^,]*\),#- [\2](\1\2)#g" stars.csv 
split -l 300 stars.csv

参考资料

github.com/JeffCarpenter/export-stars
PyGithub/PyGithub

https://www.cnblogs.com/jiangzhaowei/p/5451173.html

find之强大毋庸置疑,此处只是带领大家一窥find门径,更详细的说明见man find和 info find。
整篇文章循序渐进,从最常用的文件名测试项开始步步深入,到第六节基本讲完find处理文件的规则,再之后的章节是一些常用表达式的说明。
(此篇中所有选项及例子基于GNU find version 4.2.28)

(一)Get Start
最简单的find用法莫过于如此:

$ find .
查找当前目录下的所有文件。
find命令的一般格式为:

find [-H] [-L] [-P] [path…] [expression]

其中,’-H’ ‘-L’ ‘-P’三个选项主要是用来处理符号连接,’-H’表示只跟随命令行中指定的符号连接,’-L’表示跟随所有的符号连接,’-P’是默认的选项,表示不跟随符号连接。
例如,在我的当前目录下有一个符号连接e1000,现在我想查找文件名中最后一个字母是数字的源文件,那么

$ find -H . -name “*[0-9].c” -print
./2234.c
像上面这样写只能查找出当前目录下符合要求的文件,却找不出e1000下的文件。因此可以这么写:

$ find -H e1000 . -name “*[0-9].c” -print
或者使用 ‘-L’选项

$ find -L . -name “*[0-9].c” -print

格式中的[path…]部分表示以此目录为根目录进行搜索。

格式中的[expression]是一个表达式。最基本的表达式分为三类:设置项(option)、测试项(test)、动作项(action),这三类又可以通过逻辑运算符(operator)组合在一起形成更大更复杂的表达式。设置项(如-depth,-maxdepth等)针对这次查找任务,而不是仅仅针对某一个文件,设置项总是返回true;测试项(test)则不同,它针对具体的一个文件进行匹配测试,如-name,-num,-user等,返回true或者false;动作项(action)则是对某一个文件进行某种动作(最常见的如-print),返回true或者false。
正是[expression]部分的丰富,才使得find如此强大。此部分较复杂,后面慢慢说明。

(二)文件名
根据文件名来查找一个文件是大家经常遇到的事情,第一节中的’-name’正是解决此问题的。
-name属于表达式中的测试项(test),它按照文件名模式来匹配文件,若匹配则返回true,否则返回false。最好用引号将文件名模式引起来,防止shell自己解析要匹配的字符串。(可以用单引号也可以用双引号,单引号和双引号在shell环境中的区别见后续部分)
例如,想要的当前目录及子目录中查找文件名以一个大写字母开头或者以小写a或b开头的文件,可以用:

$ find . -name “[A-Za-b]*” -print
./a_book_of_c.chm
./TMP1234
如果想在当前目录查找文件名不以大写字母开头,之后跟一个小写字母,再之后是两个数字,最后是.txt的文件,可以这么用:

$ find . -name “[^A-Z][a-z][0-9][0-9].txt” -print
./@y38.txt
注意:此处的模式匹配并不符合正则表达式。

-name对大小写字母敏感,如果想匹配时不考虑大小写可以使用-iname测试项。’i’可以加在许多选项前面,比如-ipath,-iregex,-iwholename等等,都是表示大小写不敏感。

(三)正则表达式
使用上面的-name测试项能解决许多问题,但是有些还是不太好办,比如:查找当前目录下名称全部为数字的c源代码文件,这时就该’-regex’出手了。正则表达式绝对值得你去好好研究一下,在unix系统下太有用了,这里不做过多说明,请读者自行学习。
-regex同样属于测试项。使用-regex时有一点要注意:-regex不是匹配文件名,而是匹配完整的文件名(包括路径)。例如,当前目录下有一个文件”abar9”,如果你用”ab.*9”来匹配,将查找不到任何结果,正确的方法是使用”.*ab.9”或者”./ab.*9”来匹配。
针对上面的那个查找c代码的问题,可以这么写:

$ find . -regex “./[0-9]/.c” -print
./2234.c

还有一个设置项(option)’-regextype’,可以让你根据自己的喜好选择使用的正则表达式类型,大家可以试试。

(四)wholename与path
既然上一节提到了完整文件名(包括路径名),那么这里不妨说一下-wholename和-path。
-wholename和-path都属于测试项(test),而且功能也一样。-path从字面上看给人一种错觉,好像只匹配路径名(或者目录名),其实它也可以匹配文件名,因此-wholename这个名字更贴切一些。
看看这个例子,当前目录下有一个phone目录,phone目录里有一个文件名称是puk.txt,使用-path:

$ find . -path ‘phone/pu
./phone/puk.txt

另外要提一点:使用-path的一般格式是:find [path …] -path pattern …
它的意思是:在[path …]部分指明的路径上,使用pattern匹配所有文件的完整文件名;而不是说在类似的pattern目录下查找文件。

(五)逻辑运算符
有了上面三个选项,你现在应该对文件名的相关匹配得心应手了,对于不是很复杂的查找应该也胜任了。但是看看这个例子,解释一下它在做什么?

$ find . -size +0c -wholename “e[0-9]*” -o ! /( -name “.” -o -name “phone” /) -prune -name “.c” -user xixi -o -name “*phone”
下面是当前目录下的所有文件:

$ ls -l
total 224
-rw-r–r– 1 xixi admin 0 2007-11-01 17:34 0dfe.c
-rw-r–r– 1 abc admin 0 2007-10-30 15:56 0s8a.txt
-rw-r–r– 1 abc admin 0 2007-11-04 01:00 0TMP123
-rw-r–r– 1 abc admin 73 2007-11-05 15:33 2234.c
-rw-r–r– 1 abc admin 72 2007-11-05 15:34 3e10.c
-rw——- 1 abc admin 224017 2006-03-16 12:16 a_book_of_c.chm
lrwxrwxrwx 1 abc admin 15 2007-11-04 11:48 e1000 -> ../e1000-7.6.9/
-rw-r–r– 1 abc admin 70 2007-11-05 14:57 e100.dat
lrwxrwxrwx 1 abc admin 13 2007-11-05 14:59 e100puk.txt -> phone/puk.txt
-rw-r–r– 1 abc admin 0 2007-11-06 22:21 e680phone
drwxr-xr-x 2 abc admin 37 2007-11-06 22:24 phone
drwxr-xr-x 2 abc admin 20 2007-11-07 01:07 phone1
drwxr-xr-x 2 abc admin 6 2007-11-05 15:37 phone2
-rw-r–r– 1 abc admin 67 2007-11-04 12:23 @y38.txt

phone$ ls -l
total 4
-rw-r–r– 1 abc admin 0 2007-11-06 22:24 e680gphone
-rw——- 1 abc admin 38 2007-11-05 14:58 puk.txt

phone1$ ls -l
total 0
-rw-r–r– 1 xixi admin 0 2007-11-07 01:07 hello.c

phone2$ ls -l
total 0

要想解决上面的问题就得学习一下find中的逻辑运算符。逻辑运算符主要有以下几个,按照优先级从高到低的顺序如下:
( expr )

括号优先级最高,首先对括号内的求值
! expr

对expr表达式的值取反
-not expr

同上,但是POSIX不支持
expr1 expr2

不加任何运算符,相当于两个之间加and,即与运算,两个表达式值都为true整个才返回true。先对expr1表达式求值,若为false,则不对expr2求值。
expr1 -a expr2

同上
expr1 -and expr2

同上,但是POSIX不支持
expr1 -o expr2

表示对expr1和expr2两个表达式的值求或,左右两个值只要有一个为ture,整个表达式就是true。先对expr1表达式求值,若为ture,则不对expr2求值。
expr1 -or expr2

同上,但是POSIX不支持
expr1 , expr2

逗号表达式。expr1和expr2都会求值,但是只返回expr2的值,expr1的值会被丢弃

正是因为有一个求值的顺序,所以你才有可能见到这样的写法:

$ find . -name “.txt” -o -print
表示,如果表达式-name “
.txt”为真,就不再执行另一个表达式-print,即查找所有不是以.txt结尾的文件。

再有,要查找当前目录下,文件名中包括字母’e’,在’e’之后又有数字的不是目录文件的所有文件,可以这么写:

$ find . -name “e[0-9]*” ! -type d -print
./e1000
./e100.dat
./e100puk.txt
./3e10.c
大家可以自己多举几个例子试一下。

(六)-prune
-prune是一个动作项,它表示当文件是一个目录文件时,不进入此目录进行搜索。
要理解-prune动作,首先得理解find命令的搜索规则(也可以说find命令的算法)。
find命令递归遍历所指定的目录树,针对每个文件依次执行find命令中的表达式,表达式首先根据逻辑运算符进行结合,然后依次从左至右对表达式求值。以下面代码为例,进行说明

find PATHP1 OPT1 TEST1 ACT1 ( TEST2 or TEST3 ) ACT2
(1) 根据OPT1设置项进行find命令的整体设置,若没有-depth设置项,依次进行下面的步骤
(2) 令文件变量File = PATHP1
(3) 对File文件进行TEST1测试,若执行结果为false,转(8)
(4) 对File文件进行ACT1动作,若执行结果为false,转(8)
(5) 对File文件进行TEST2测试,若执行结果为true,转(7)
(6) 对File文件进行TEST3测试,若执行结果为false,转(8)
(7) 对File文件进行ACT2动作
(8) 若File文件是一个目录,并且没有被执行过-prune动作,则进入此目录
(9) 当前目录下是否还有文件,若有依次取一个文件,令File指向此文件,转(3);
(10) 判断当前目录是否是PATHP1,若是则程序退出;若不是,则返回上一层目录,转(9)

理解了上面的流程,那么不难理解下面的代码为什么只输出一个’.’

$ find . -prune
.
再有,当前目录下大于4090字节的文件有两个,而大于4096字节的文件只有一个,如下:

$ find . -size +4090c -print
.
./a_book_of_c.chm

$ find . -size +4096c -print
./a_book_of_c.chm

那么,将上面两个-print都替换为-prune,这两条命令分别输出什么?

$ find . -size +4090c -prune
.
$ find . -size +4096c -prune
./a_book_of_c.chm
这就是答案,如果你答对了,恭喜你,你已经掌握了find命令!

-prune经常和-path或-wholename一起使用,以避开某个目录,常见的形式是:

$ find PATH (-path <don’t want this path #1> -o -path <don’t want this path #2>) -prune -o -path

注意:如果同时使用-depth设置项,那么-prune将被find命令忽略。man手册页中这么说:”If -depth is given, false; no effect.”
说到这里,又得说说-depth设置项。网上好多资料说-depth设置项的功能是“在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找”,这明显是错误的,man手册页中如是说:”-depth Process each directory’s contents before the directory itself.”。这有点像树的后序遍历,先遍历当前节点的所有子节点,然后再访问当前节点…
考考你:
下面的命令输出什么?为什么?

$ find . -depth -prune -name “*.c” -print

(七)时间戳
理解了上面几节,你已经掌握了find命令的“道” ^_^ ,下面这几节只是介绍一些常用、好用的“招式”。这一节介绍时间戳。

文件有三个时间属性:创建时间、最近修改时间、最近访问时间。
最近修改时间又包括两种,一是文件的状态(也即权限如rwx等)最近被修改时间,一是文件的数据(也即内容)最近被修改时间。touch命令改变的即是文件数据最近被修改时间。
最近访问时间,指的是最近一次文件数据(内容)被访问的时间。因此,使用ls命令输出文件的相关信息并不会修改文件的最近访问时间。

find命令提供了针对文件的最近访问时间、文件状态最近被修改时间、文件数据最近被修改时间进行匹配的测试项,分别是-amin, -cmin, -mmin和-atime, -ctime, -mtime两组,第一组基于分钟,第二组基于天。
以-amin为例,假设当前时间tnow=”2007-11-12 14:42:10”、t1=”2007-11-12 14:39:10”、t2=”2007-11-12 14:40:10”,那么要查找最近访问时间属于[t1,t2]时间段的文件,可以这么写:

$ find . -amin 3

若测试项参数是数字,则基本上都可以在数字参数前加”+”或者”-“号,表示“大于”或“小于”的意思,因此,要查找最近访问时间属于[t1,tnow]时间段的文件,可以这么写:

$ find . -amin -3

“-amin n”和”-atime n”的处理方法都是:根据当前时间和文件的相应时间属性求n值,然后比较n值和参数n,看是否符合要求。但是这个求n值的过程却有很大不同,他们的不同也代表了两组(基于分钟和基于天)的不同:
“-amin n”

1、求Δt,用当前时间减去文件对应属性的时间值即得到Δt,Δt = tnow - tfile;
2、求浮点数f,用Δt除以1分钟,f = Δt / 1min;
3、将f的小数部分入到整数部分,得到n。即,不管f是6.0102还是6.8901,n都等于7
“-atime n”

1、求Δt,用当前时间减去文件对应属性的时间值即得到Δt,Δt = tnow - tfile;
2、求浮点数f,用Δt处以24小时,f = Δt / 24hours;
3、将f的小数部分都舍掉,得到n。即,不管f是6.0102还是6.8901,n都等于6
大家可以多做实验,试一下。

(八)权限位
很多人都在用windows,从windows系统拷过来的文件经常被加上了可执行权限,比如我现在想把主目录下所有的后缀名为.txt .pdf .rm并且具有可执行权限位的文件查找出来,该怎么写呢?
这里就不得不说一说权限位测试项:-perm。-perm支持符号权限位表示法也支持绝对(八进制)权限位表示法,但是最好使用八进制的权限表示法(这只是个建议 ^_^ )。
-perm基本上有下面这几中形式:

-perm mode File’s permission bits are exactly mode.
-perm -mode All of the permission bits mode are set for the file.
-perm /mode Any of the permission bits mode are set for the file.
-perm +mode (此形式已经不推荐使用,功能与/mode相同)
好好理解上面蓝色部分,理解了,-perm测试项也就掌握了。
考考你:
看看下面这句话是什么意思?

find . -perm -444 -perm /222 ! -perm /111

现在再来解决本节最开始提出的问题:查找主目录下所有的后缀名为.txt .pdf .rm并且具有可执行权限位的文件。

$ find ~ /( -name “.txt” -o -name “.pdf” -o -name “*.rm” /) /
-not /( -type d -o -type l /) /
-perm /111 -print

(九)文件类型
有一个问题:我只想查找符号连接文件,可是查找结果中却包括了普通文件、目录文件等等,不相关的东西太多了,怎么把不是符号连接文件的查找结果去掉?
-type测试项刚好可以满足你的要求,-type c即可,其中c表示文件类型,find中支持如下类型:

          b      block (buffered) special
          c      character (unbuffered) special
          d      directory
          p      named pipe (FIFO)
          f       regular file
          l       symbolic link;
          s      socket
          D     door (Solaris)

针对上面的问题,可以这么写:

$ find . -name “e100*” -type l -print
./e1000
./e100puk.txt
但是,不要这么写:

$ find -L . -name “e100*” -type l -print
加上’-L’选项之后,你将查不到需要的东西,除非符号连接已经失效了。

(十)文件大小
前面一再使用-size测试项,这里简单介绍一下。
-size测试项根据文件的大小查找文件,文件大小既可以用块(block)来计量,也可以用字节来计量。默认情况下以块计量文件大小,若想使用字节来计量只需要在数字参数后加c即可。find支持的其他计量方式有:
-size n[cwbkMG],分别表示

          ‘b’    for 512-byte blocks (this is the default if no suffix  is used)
          ‘c’    for bytes
          ‘w’    for two-byte words
          ‘k’    for Kilobytes (units of 1024 bytes)
          ‘M’    for Megabytes (units of 1048576 bytes)
          ‘G’    for Gigabytes (units of 1073741824 bytes)

(十一)用户、用户组
根据用户、用户组来查找文件,这个没有太多要说的,记住命令格式即可:

-uid n
-user username or uid
-nouser
-gid n
-group gname or gid
-nogroup

(十二)输出格式
如果你不想查找到你想要的文件事单调的输出文件名,你可以使用-printf动作项输出你想要的格式,下面举几个-printf动作的参数:

%p 输出文件名,包括路径名
%f 输出文件名,不包括路径名
%m 以8进制方式输出文件的权限
%g 输出文件所属的组
%h 输出文件所在的目录名
%u 输出文件的属主名

例如:

$ find . -user xixi -printf “%m %p //n”
644 ./phone1/hello.c
644 ./0dfe.c

其余的,看man手册页吧。

(十三)执行外部命令
这又是一个很容易出彩的地方。find真是强大,对查找到的文件竟然可以调用外部命令进行处理。-exec动作项就是来完成这个功能的,格式是:

find . EXPR1 -exec command {} /;
注意:后一个花括号’}’和’/‘之间有一个空格。
例如,查找当前目录下的所有普通文件,并用ls命令输出:

find . -type f -exec ls -l {} /;
有些操作系统中出于安全考虑只允许-exec选项执行诸如l s或ls -l这样的命令。
也可以使用-exec动作项的安全模式:-ok动作项。它的功能和语法都跟-exec一样,只不过它以更安全的模式运行,当要删除文件时,它会给出提示,让你选择到底删除还是不删。
例如:

$ find logs -name “abc“ -ok rm {} /;

使用-exec动作项处理匹配到的文件时,find命令会将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误。错误信息通常是“参数列太长”或“参数列溢出”。这就是xargs命令的用处所在,特别是与find命令一起使用。
xargs的使用格式是:

find PATH EXPR1 EXPR2 | xargs command
利用管道,把find命令匹配到的文件名传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部。这样它可以先处理最先获取的一部分文件,然后是下一批,并如此继续下去。
在有些系统中,使用-exec动作项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高;而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参数来确定。
例如,要在普通文件中查找文件内容中包含”io”的文件,可以这么写:

$ find . -type f | xargs grep “io”
Binary file ./a_book_of_c.chm matches
./2234.c:#include <stdio.h>
./3e10.c:#include <stdio.h>

find命令配合exec和xargs可以对所匹配到的文件执行几乎所有的命令。

(十四)总结
理解并运用find,关键是掌握find命令的处理规则(见第五节):递归遍历所指定的目录树,针对每个文件依次执行find命令中的表达式,表达式首先根据逻辑运算符进行结合,然后依次从左至右对表达式求值。把这个理解了,需要什么功能查一下man就可以了。

find命令还有好多功能这里没有涉及到,具体的大家看man手册页吧。在任何时候,man都是一个极好的帮助工具。 ^_^

(十五)附
第五节提出的问题,答案如下:

$ find . -size +0c -wholename “e[0-9]*” -o /
! /( -name “.” -o -name “phone” /) -prune -name “.c” -user xixi /
-o -name “*phone”
./e1000
./e100.dat
./phone
./phone/e680gphone
./e100puk.txt
./3e10.c
./phone1
./phone1/hello.c
./phone2
./0dfe.c
./e680phone

这篇文章断断续续写了好久,今天终于基本完工。参考了man手册页以及一些网上的资料。
要把自己心中所想有条理的写出来感觉真是不易,希望对大家有所帮助。
欢迎批评指正。

使用 Docker 搭建个人博客:从零到上线
原文 https://mp.weixin.qq.com/s/FSYM34_vNe9wSY6mn_bG0Q

图片
图片
在当今数字时代,拥有一个个人博客不仅能展示你的技术和思想,还能为你提供一个记录和分享的平台。

Docker 作为一种流行的容器化技术,可以让你快速、轻松地部署和管理你的博客。

在本文中,我们将详细介绍如何使用 Docker 从零开始搭建个人博客。

图片

目录

  1. 前提条件
  2. 选择博客平台
  3. 环境准备
  4. 克隆博客仓库
  5. 编写 Docker Compose 文件
  6. 配置环境变量
  7. 启动容器
  8. 访问博客
  9. 自定义博客
  10. 总结

前提条件

在开始之前,请确保你的系统已经安装了以下工具:

  1. Docker[1]

  2. Docker Compose[2]

这些工具的安装可以参考各自的官方文档。如果您是初次接触 Docker,可以先了解一下 Docker 的基本概念和命令。

选择博客平台

我们选择了 Hexo[3] 作为我们的博客平台。Hexo 是一个快速、简洁且高效的博客框架,支持 Markdown 语法,并且有丰富的主题和插件可供选择。

环境准备

首先,我们需要为 Hexo 创建一个工作目录,并初始化一个 Hexo 项目。打开终端并运行以下命令:

1
2
3
4
5
mkdir my-blog
cd my-blog
npm install hexo-cli -g
hexo init
npm install

这些命令将创建一个新的 Hexo 项目,并安装所有必要的依赖项。接下来,我们将准备 Docker 环境。

克隆博客仓库

为了方便管理和部署,我们将博客项目托管在 GitHub 上。首先,创建一个新的 GitHub 仓库,然后将本地 Hexo 项目推送到该仓库。

1
2
3
4
5
git init
git remote add origin https://github.com/yourusername/yourblog.git
git add .
git commit -m "Initial commit"
git push -u origin master

编写 Docker Compose 文件

我们将使用 Docker Compose 来管理多个 Docker 容器。创建一个名为 docker-compose.yml 的文件,并添加以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
version: '3.8'

services:
hexo:
image: node:14
container_name: hexo_blog
working_dir: /usr/src/app
volumes:
- .:/usr/src/app
command: sh -c "npm install && hexo server -p 4000"
ports:
- "4000:4000"

这个 Docker Compose 文件定义了一个名为 hexo 的服务,使用官方的 Node.js 镜像,并将当前目录挂载到容器内。启动容器时,将安装依赖并启动 Hexo 服务器。

配置环境变量

为了方便管理配置,我们可以将一些环境变量放入 .env 文件中。创建一个 .env 文件,并添加以下内容:

BLOG_PORT=4000
然后,在 docker-compose.yml 文件中引用这些环境变量:

1
2
3
4
5
6
7
8
9
10
11
12
version: '3.8'

services:
hexo:
image: node:14
container_name: hexo_blog
working_dir: /usr/src/app
volumes:
- .:/usr/src/app
command: sh -c "npm install && hexo server -p ${BLOG_PORT}"
ports:
- "${BLOG_PORT}:${BLOG_PORT}"

启动容器

现在我们可以使用 Docker Compose 启动容器了。运行以下命令:

1
docker-compose up -d

该命令会在后台启动 Hexo 容器。你可以使用以下命令查看容器的状态:

1
docker-compose ps

如果一切顺利,你应该会看到 Hexo 容器正在运行。

访问博客

打开浏览器,并访问 http://localhost:4000,你应该会看到 Hexo 的默认欢迎页面。 当然,我们继续深入探讨如何自定义和管理你的 Hexo 博客,包括更改主题、添加插件和部署到生产环境。

自定义博客

更改主题

Hexo 有许多精美的主题,你可以在 Hexo 主题库[4] 中找到。以下是更改主题的步骤。

  1. 选择主题:在 Hexo 主题库中选择一个你喜欢的主题,并记下其安装命令或 GitHub 仓库地址。

  2. 安装主题:在你的博客根目录下运行安装命令。例如,安装 NexT 主题:

1
git clone https://github.com/theme-next/hexo-theme-next themes/next
  1. 配置主题:打开 Hexo 配置文件 _config.yml,更改主题配置:
1
theme: next
  1. 自定义主题:进入 themes/next 目录,根据主题文档自定义配置,例如更改配色、布局等。

添加插件

Hexo 提供了丰富的插件系统,可以扩展博客的功能。以下是添加插件的步骤:

  1. 选择插件:在 Hexo 插件库[5] 中选择需要的插件。

  2. 安装插件:在博客根目录下运行安装命令。例如,安装 Hexo SEO 插件:

1
npm install hexo-generator-seo-friendly-sitemap --save
  1. 配置插件:根据插件文档,打开 _config.yml 文件,添加相应的配置。例如,配置 SEO 插件:
1
2
sitemap:
path: sitemap.xml

部署到生产环境

将你的博客部署到云服务器或静态网站托管服务(如 GitHub Pages、Netlify)上,可以让全世界的人访问。以下是一些常见的部署方法。

部署到 GitHub Pages
  1. 安装部署插件:在博客根目录下运行以下命令:
1
npm install hexo-deployer-git --save
  1. 配置部署插件:在 _config.yml 文件中添加部署配置:
1
2
3
4
deploy:
type: git
repo: https://github.com/yourusername/yourblog.git
branch: gh-pages
  1. 生成静态文件并部署:运行以下命令:
1
2
3
hexo clean
hexo generate
hexo deploy
部署到 Netlify
  1. 创建 Netlify 帐号:访问 Netlify[6] 创建一个免费帐号。

  2. 连接 GitHub 仓库:在 Netlify 仪表盘中创建一个新站点,并选择你的 GitHub 仓库。

  3. 配置构建设置:设置构建命令为 hexo generate,发布目录为 public。

  4. 部署站点:保存并部署,Netlify 会自动从你的仓库中拉取代码并部署。

持续集成和自动部署

为了简化部署过程,你可以使用持续集成工具(如 GitHub Actions)来实现自动化部署。

使用 GitHub Actions 自动部署
  1. 创建 GitHub Actions 工作流文件:在你的仓库中创建 .github/workflows/deploy.yml 文件,并添加以下内容:
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
name: Deploy Hexo Blog

on:
push:
branches:
- master

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Setup Node.js
uses: actions/setup-node@v1
with:
node-version: '14'

- name: Install dependencies
run: npm install

- name: Generate static files
run: npm run build

- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
  1. 配置 GitHub Secrets:在你的 GitHub 仓库设置中,添加 GITHUB_TOKEN 到 Secrets 中。

  2. 推送代码:每次将代码推送到 master 分支时,GitHub Actions 会自动运行工作流并部署你的博客。

访问博客

在部署完成后,你可以通过配置的域名或托管服务提供的默认域名访问你的博客。

自定义博客

自定义域名

如果你希望使用自定义域名而不是默认的 GitHub Pages 或 Netlify 域名,你可以按照以下步骤进行设置。

在 GitHub Pages 上使用自定义域名
  1. 购买域名:你可以通过域名注册商(如 Namecheap、GoDaddy)购买一个域名。

  2. 配置 DNS:在你的域名注册商的管理控制台中,添加一个 CNAME 记录,指向 yourusername.github.io。例如:

1
2
3
CNAME record:
Name: www
Value: yourusername.github.io
  1. 添加 CNAME 文件:在你的 Hexo 项目根目录下创建一个名为 CNAME 的文件,内容为你的自定义域名,例如:
1
www.yourdomain.com
  1. 部署:再次运行 hexo deploy 命令,将 CNAME 文件部署到 GitHub Pages。
在 Netlify 上使用自定义域名
  1. 购买域名:同样,你需要通过域名注册商购买一个域名。

  2. 添加域名到 Netlify:在 Netlify 仪表盘中,进入你的站点设置,找到 “Domain management” 并添加你的自定义域名。

  3. 配置 DNS:Netlify 会提供 DNS 记录配置指导,你需要在域名注册商的管理控制台中添加相应的 DNS 记录,例如 A 记录或 CNAME 记录。

添加评论系统

一个互动的博客通常会包含评论系统。Hexo 支持多种评论系统,例如 Disqus 和 Gitalk。以下以 Disqus 为例:

  1. 注册 Disqus:访问 Disqus[7] 并创建一个新的站点。

  2. 获取 Disqus Shortname:在 Disqus 的设置中找到 Shortname,它是你站点的唯一标识符。

  3. 配置 Hexo:在 Hexo 的 _config.yml 文件中添加 Disqus 配置:

1
disqus_shortname: your-disqus-shortname
  1. 安装 Disqus 插件:如果你的主题不支持 Disqus 评论系统,你可能需要安装 Hexo Disqus 插件:
1
npm install hexo-disqus --save

添加搜索功能

为了让读者更容易找到他们感兴趣的文章,你可以为博客添加搜索功能。例如,使用 hexo-generator-searchdb 插件:

  1. 安装插件:
1
npm install hexo-generator-searchdb --save
  1. 配置插件:在 Hexo 的 _config.yml 文件中添加以下配置:
1
2
3
4
search:
path: search.xml
field: post
format: html
  1. 修改主题:根据你使用的主题文档,添加搜索框和相应的 JS 代码来启用搜索功能。

优化性能

为了提升博客的加载速度和性能,可以进行以下优化:

启用 CDN

使用内容分发网络(CDN)可以加速你博客的静态资源加载。例如,使用 Cloudflare:

  1. 注册 Cloudflare:访问 Cloudflare[8] 并注册一个新账户。

  2. 添加站点:按照提示添加你的自定义域名,并更新域名注册商的 DNS 服务器设置为 Cloudflare 提供的 DNS 服务器。

  3. 启用 CDN:确保 Cloudflare 的 CDN 功能已启用,并配置缓存规则。

压缩资源

压缩 CSS、JS 和图片等静态资源可以显著减少页面加载时间。你可以使用 Hexo 插件来实现资源压缩:

  1. 安装压缩插件:
1
npm install hexo-neat --save
  1. 配置插件:在 Hexo 的 _config.yml 文件中添加以下配置:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    neat_enable: true
    neat_html:
    enable: true
    exclude:
    neat_css:
    enable: true
    exclude:
    neat_js:
    enable: true
    exclude:

备份和恢复

定期备份你的博客项目是个好习惯,可以防止数据丢失。你可以使用 Git 来管理备份。

使用 GitHub 备份
  1. 确保项目在 GitHub 上:之前我们已经将 Hexo 项目推送到 GitHub 仓库,这里简单回顾一下:
1
2
3
4
5
git init
git remote add origin https://github.com/yourusername/yourblog.git
git add .
git commit -m "Initial commit"
git push -u origin master
  1. 定期提交和推送:每次对博客进行修改后,记得提交并推送到 GitHub:
1
2
3
git add .
git commit -m "Update blog content"
git push
恢复博客

如果需要恢复你的博客,只需从 GitHub 克隆仓库并安装依赖:

1
2
3
git clone https://github.com/yourusername/yourblog.git
cd yourblog
npm install

常见问题解决

Docker 容器无法启动

如果遇到 Docker 容器无法启动的情况,可以查看容器日志来诊断问题:

1
docker-compose logs hexo

常见问题可能包括依赖安装失败、端口冲突等。根据日志信息进行相应的调整和修复。

Hexo 部署失败

如果在部署到 GitHub Pages 或其他平台时失败,可以尝试以下步骤:

  1. 检查配置文件:确保 _config.yml 中的配置正确,特别是 deploy 部分。

  2. 清理缓存和生成文件:

1
2
hexo clean
hexo generate
  1. 重新部署:
1
hexo deploy

主题样式不生效

如果更改主题或自定义样式后没有生效,可以尝试以下步骤:

  1. 清理缓存和生成文件:
1
2
hexo clean
hexo generate
  1. 检查主题配置:确保主题的 _config.yml 文件中的配置正确,并已保存。

  2. 重启本地服务器:

1
hexo server

进一步优化和扩展

SEO 优化

为了提高搜索引擎排名,可以进行以下 SEO 优化:

  1. 设置 Meta 标签:在 _config.yml 中配置 meta 标签,如 title, description, keywords 等。

  2. 使用 SEO 插件:例如,安装 hexo-generator-seo-friendly-sitemap 和 hexo-generator-robots 插件:

1
npm install hexo-generator-seo-friendly-sitemap hexo-generator-robots --save

并在 _config.yml 中进行相应配置:

1
2
3
4
5
6
sitemap:
path: sitemap.xml

robots:
useragent: *
disallow:

分析和监控

为了了解博客的访问情况,可以集成分析工具,如 Google Analytics 或 Baidu Analytics。

集成 Google Analytics
  1. 注册 Google Analytics:访问 Google Analytics[9],并获取跟踪 ID。

  2. 配置 Hexo:在 _config.yml 中添加 Google Analytics 配置:

1
google_analytics: UA-XXXXX-Y
集成 Baidu Analytics
  1. 注册 Baidu Analytics:访问 Baidu Analytics[10],并获取代码片段。

  2. 配置 Hexo:将代码片段添加到主题的 _config.yml 文件中,或直接修改主题的 layout/_partial/ 文件。

社交分享

增加社交分享按钮可以提升博客的互动性和传播度。

  1. 选择插件:例如,使用 hexo-plugin-social-share 插件。

  2. 安装插件:

1
npm install hexo-plugin-social-share --save
  1. 配置插件:在 _config.yml 中添加社交分享配置:
1
2
3
4
5
6
social_share:
enable: true
sites:
- twitter
- facebook
- linkedin

总结

通过本文的详细指南,我们从零开始搭建了一个基于 Hexo 的个人博客,并通过 Docker 容器化技术进行了管理和部署。同时,我们还介绍了如何自定义博客主题、添加插件、优化性能以及解决常见问题。希望这些步骤能帮助你顺利搭建并管理一个专业的个人博客。

使用 Docker 和 Hexo,你可以快速、轻松地创建和维护一个个人博客,不仅展示你的技术和思想,还可以为你提供一个记录和分享的平台。赶快动手试试吧!

如果你有任何疑问或需要进一步的帮助,请随时在评论区留言,我们将尽力为你解答。Happy Blogging!

END

欢迎关注我的公众号

原创技术文章第一时间推送,点赞和在看就是最大的支持❤️

图片

点分享

图片

点收藏

图片

点点赞

图片

点在看

微信扫一扫
关注该公众号

人划线

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post 创建一篇博客

1
$ hexo new "My New Post"

More info: Writing

Run server 运行服务器

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment