#Efficiency

买的一些课程配套资料都是 PDF 格式的,为了防止盗版都事先用的图片转成的 PDF,这样 PDF 里的内容既没法复制也没法搜索,在查找资料里的关键词的时候就很不方便,所以就想着把这些 PDF 转成可搜索的 PDF。找到了一款工具叫做 ocrmypdf,可以把 PDF 转成可搜索的 PDF,而且还支持中文,这里记录一下使用方法。详细使用文档可以参考官方文档 OCRmyPDF documentation

安装

1
sudo apt install ocrmypdf

使用

指定 OCR 的语言

安装语言包

1
sudo apt install tesseract-ocr-chi-sim

查看是否安装成功

1
2
3
4
5
$ tesseract --list-langs
List of available languages (3):
chi_sim
eng
osd

注意参数 -l 后面的语言包名称是下划线,而不是短横线。

1
ocrmypdf -l chi_sim input.pdf output.pdf
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
$  ocrmypdf -l chi_sim  --redo-ocr  input.pdf output.pdf
Scanning contents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████| 752/752 [00:14<00:00, 51.36page/s]
Start processing 24 pages concurrently
33 redoing OCR
26 [tesseract] lots of diacritics - possibly poor OCR
54 [tesseract] lots of diacritics - possibly poor OCR
88 [tesseract] lots of diacritics - possibly poor OCR
119 [tesseract] lots of diacritics - possibly poor OCR
203 [tesseract] lots of diacritics - possibly poor OCR
256 [tesseract] lots of diacritics - possibly poor OCR
265 [tesseract] lots of diacritics - possibly poor OCR
347 [tesseract] lots of diacritics - possibly poor OCR
376 [tesseract] lots of diacritics - possibly poor OCR
383 [tesseract] lots of diacritics - possibly poor OCR
386 [tesseract] lots of diacritics - possibly poor OCR
402 [tesseract] lots of diacritics - possibly poor OCR
404 [tesseract] lots of diacritics - possibly poor OCR
403 [tesseract] lots of diacritics - possibly poor OCR
412 [tesseract] lots of diacritics - possibly poor OCR
415 [tesseract] lots of diacritics - possibly poor OCR
410 [tesseract] lots of diacritics - possibly poor OCR
439 [tesseract] lots of diacritics - possibly poor OCR
519 [tesseract] lots of diacritics - possibly poor OCR
526 [tesseract] lots of diacritics - possibly poor OCR
587 [tesseract] lots of diacritics - possibly poor OCR
591 [tesseract] lots of diacritics - possibly poor OCR
595 [tesseract] lots of diacritics - possibly poor OCR
607 [tesseract] lots of diacritics - possibly poor OCR
644 [tesseract] lots of diacritics - possibly poor OCR
661 [tesseract] lots of diacritics - possibly poor OCR
682 [tesseract] lots of diacritics - possibly poor OCR
720 [tesseract] lots of diacritics - possibly poor OCR
742 [tesseract] lots of diacritics - possibly poor OCR
OCR: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 752.0/752.0 [03:41<00:00, 3.40page/s]
Postprocessing...
Some input metadata could not be copied because it is not permitted in PDF/A. You may wish to examine the output PDF's XMP metadata.
PDF/A conversion: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████| 752/752 [01:09<00:00, 10.80page/s]
Recompressing JPEGs: 0image [00:00, ?image/s]
Deflating JPEGs: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████| 756/756 [00:00<00:00, 920.21image/s]
JBIG2: 0item [00:00, ?item/s]
Optimize ratio: 1.20 savings: 17.0%
Output file is okay but is not PDF/A (seems to be No PDF/A metadata in XMP)

转换的结果还不错,页面排版不会改变,保持原样,但是搜索文字时可能需要用空格分开。

背景简介

在使用 VSCode 的过程中,我们经常会安装一些插件来提高开发效率。但是,由于某些原因,我们可能无法直接访问 VSCode 的插件市场,这时候我们就需要离线安装插件了。

这里存在两种情况,一种是为本地的 VSCode 安装插件,另一种是为远程的 VSCode 安装插件。本文将分别介绍这两种情况下的离线安装方法。

远程 VSCode 也就是 VSCode 的Remote Development功能,可以通过 SSH、Docker、WSL 等方式远程连接到远程主机上的 VSCode。

方法一:使用已安装的插件目录

  • 从已经安装插件的电脑上拷贝所有插件,路径一般为 C:\用户\用户名\.vscode\extensions
  • 拷贝到离线安装的电脑上的 .vscode/extensions 文件夹下即可,重启 VScode 即可安装成功。

对于远程 VSCode 我们需要知道,插件不区分操作系统,所以我们可以在本地的 Windows 上的 VSCode 上安装插件,然后将插件目录压缩后整个拷贝到远程主机上即可。

远程主机上的插件目录一般在 ~/.vscode-server/extensions 下。将压缩的文件解药到这个目录下,重启 VSCode 即可。

方法二:下载离线安装包 vslx 安装

  • VScode 插件中心 搜索需要使用的插件名称

  • 下载对应的拓展程序文件,下载的文件的后缀是.vslx

  • VSCode 中安装

简介

GitHub Actions 是 GitHub 在 2018 年推出的持续集成服务。它可以自动完成一些开发周期内的任务,如 Push 代码时自动编译,Pull 代码时自动执行测试脚本等等。

我了解 GitHub Actions 的契机是,我在 GitHub 上保存了一些 Markdown 文档,我希望每次更新文档后自动使用 Pandoc 转换成 PDF 文档。接下来我们一起学习如何通过 GitHub Actions 实现这样的需求。

首先我们先直观的了解一下它在 GitHub 的位置,如果打开一个仓库,它有图中绿色对号√,或者红色叉号×,说明这个项目配置了 GitHub Actions,绿色表示自动化的流程运行成功了,红色表示失败了。

我们点开Actions按钮就可以查看具体的任务详情。下面我们先学习如何配置一个简单的 GitHub Actions。

配置 GitHub Actions

GitHub Actions 可以简单理解为一些自动化脚本,工具,目的就是为了减少重复工作,所以这些工具都可以做成普适性的工具。而 GitHub 官方就开放了一个这类工具的市场,我们可以在上面搜索自己想要的工具。因为初学 GitHub Actions 所以也不知道怎么写配置文件,我们可以直接搜索一个并应用它,看看别人是怎么写的。

我们进入一个自己的仓库,点击Actions,搜索框中搜索PDF,在搜索结果中找到Create PDF · Actions这个工具。如果搜索到点击Configure。如果显示未找到,则点击set up a workflow yourself,同样搜索PDF

打开详情页面,拉到底,将Example usage。里的内容复制到编辑框中。点击右上角Start commit将会把我们新建的main.yml提交到仓库中。这就相当于创建了一个生成 PDF 的 GitHub Actions。当然每个 Actions 都有一些使用要求,比如这里还要根据介绍,创建几个文件夹,比如从哪个文件夹获取源文件,生成后的 PDF 又会放到哪个文件夹等。这里就不再介绍,我们先了解如何创建一个 Actions。

Workflow 配置

GitHub Actions 的配置文件叫做 workflow 文件,存放在代码仓库的.github/workflows 目录。

workflow 文件采用 YAML 格式,文件名可以任意取,但是后缀名统一为.yml or .yaml,比如 foo.yml or foo.yaml。一个库可以有多个 workflow 文件。GitHub 只要发现.github/workflows 目录里面有.yml or .yaml 文件,就会自动运行该文件(并行)。

接下来我们逐个参数来解释都有哪些功能。

on

触发 workflow 的 GitHub 事件的名称。比如push代码时触发,其他人fork代码仓时触发等等。

可以只有一个事件触发,

1
on: push

也可有多个事件触发,使用列表列举,

1
on: [push, fork]

所有支持的事件列表,请查看官方文档

on.[push|fork].[tags|branches]

注意:从这里开始就会出现一个字段下有子字段,每个点号.分割一个子字段。如push或者fork可以作为on的子字段,tags或者branches可以作为push或者fork的子字段。在yaml文件中,缩进很重要,每个缩进都表示是从属关系,表示是该字段的子字段。千万要注意缩进关系,如果缩进出错,那么将无法解析yaml文件。

指定触发事件时,可以限定分支或标签。

1
2
3
4
on:
push:
branches:
- master

上面代码指定,只有 master 分支发生 push 事件时,才会触发 workflow。

name

工作流程的名称。GitHub 在仓库的操作页面上显示工作流程的名称。如果省略 name,GitHub 将其设置为相对于仓库根目录的工作流程文件路径。

jobs

workflow 运行包括一项或多项 jobs。jobs 默认是并行运行。要按顺序运行作业,可以使用 [job_id].needs 关键词在其他 job 上定义依赖项。

每个作业在 runs-on 指定的运行器环境中运行。

jobs.[job_id]

jobs 中的每个任务都有一个[job_id] ,且其必须为 jobs 对象中唯一的字符串键值[job_id]必须以字母或_开头,并且只能包含字母数字字符、-_

1
2
3
4
5
jobs:
first_job: # [job_id],任务 id
name: My first job
second_job:
name: My second job

jobs.[job_id].[runs-on]

runs-on 字段指定运行所需要的虚拟机环境。它是必填字段。目前可用的虚拟机如下。

1
2
3
- ubuntu-latest,ubuntu-18.04或ubuntu-16.04
- windows-latest,windows-2019或windows-2016
- macOS-latest或macOS-10.14

下面代码指定虚拟机环境为 ubuntu-18.04。

1
runs-on: ubuntu-18.04

jobs.[job_id].name

workflow 文件的主体是 jobs 字段,表示要执行的一项或多项任务。

job_id 里面的 name 字段是任务的说明。它可以在网页端的 UI 上显示。

1
2
3
4
5
jobs:
first_job:
name: My first job # [job_name],任务名称
second_job:
name: My second job

jobs.[job_id].needs

needs 字段指定当前任务的依赖关系,即运行顺序。

1
2
3
4
5
6
jobs:
job1:
job2:
needs: job1
job3:
needs: [job1, job2]

上面代码中,job1 必须先于 job2 完成,而 job3 等待 job1 和 job2 的完成才能运行。因此,这个 workflow 的运行顺序依次为:job1、job2、job3。

jobs.[job_id].steps

steps 字段指定每个 Job 的运行步骤,可以包含一个或多个步骤。每个步骤都可以指定以下三个字段。

1
2
3
- jobs.[job_id].steps.name:步骤名称。
- jobs.[job_id].steps.run:该步骤运行的命令或者 action。
- jobs.[job_id].steps.env:该步骤所需的环境变量。

下面是一个完整的 workflow 文件的范例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
name: Greeting from Mona
on: push

jobs:
my-job:
name: My Job
runs-on: ubuntu-latest
steps:
- name: Print a greeting
env:
MY_VAR: Hi there! My name is
FIRST_NAME: Mona
MIDDLE_NAME: The
LAST_NAME: Octocat
run: |
echo $MY_VAR $FIRST_NAME $MIDDLE_NAME $LAST_NAME.

上面代码中,steps 字段只包括一个步骤。该步骤先注入四个环境变量,然后执行一条 Bash 命令。

jobs.[job_id].steps[*].uses

选择一个 action,可以理解为若干 steps.run,有利于代码复用。这也是 github action 最主要的功能。

比如最常用的,下载本仓库的代码到工作区,就是使用的一个 action 完成的:

1
2
3
steps:
- name: Check out Git repository
uses: actions/checkout@v2

注:@v2 什么意思?
表示 Action 的版本。我们如果不带版本号的话,就是默认使用最新版本。Github 官方强烈要求我们带上版本号。这样子的话,我们就不会出现:写好一个 Workflow,但是由于某个 Action 的作者一更新,我们的 Workflow 就崩了的问题

jobs.[job_id].steps.run

在 shell 中执行的命令:

1
2
3
4
5
6
steps:
- uses: actions/checkout@v2
- name: create dir
id: dir
run: |
mkdir output # create output dir

以上配置是在下载完本仓库的代码后,在仓库根目录新建一个output文件夹。注意run:后的|表示可以多行命令。如果没有|表示只能执行一条命令。

jobs.[job_id].steps.working-directory

用来指定在run命令在哪执行。

1
2
3
- name: Create dir
run: mkdir output
working-directory: ./build

jobs.[job_id].steps.shell

用来指定 shell 类型,如 Python,bash,powershell 等。

1
2
3
4
steps:
- name: Display the path
run: echo $PATH
shell: bash

所有支持的类型请查看官方文档

如何跳过 GitHub Actions

在 commit message 中只要包含了下面几个关键词就会跳过 Github Actions。

1
2
3
4
5
[skip ci]
[ci skip]
[no ci]
[skip actions]
[actions skip]

实例:自动使用 Pandoc 将 Markdown 文件转换为 PDF

Dunky-Z/uefi-spec-zh项目中使用的 GitHub Actions 为例,解释如何实现将 Markdown 文件转换为 PDF。

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
# CI 名为 MPPL
name: MPPL

# 在 Push 代码时触发 CI
on: push

jobs:
# 任务名称为 convert_via_pandoc
convert_via_pandoc:
# 在 ubuntu-latest 系统上运行
runs-on: ubuntu-latest
steps:
# 步骤一:下载最新代码
- uses: actions/checkout@v2
# 步骤二:在项目根目录建立 output 文件夹放生成的 PDF 文件
- name: create file list
id: files_list
run: |
mkdir output # create output dir
# 步骤三:更新项目的子模块
- name: Git Sumbodule Update
run: |
git submodule update --init --remote --recursive
# 步骤四:为运行的系统中安装需要的字体,因为原系统没有需要的中文字体
# 字体来源为项目目录的MPPL/fonts
- name: add fonts
run: |
sudo apt-get install ttf-mscorefonts-installer
sudo apt-get install fontconfig
fc-list :lang=zh
ls -lh /usr/share/fonts/
cp -rf ./MPPL/fonts/* /usr/share/fonts/
mkfontscale
mkfontdir
fc-cache
fc-list
# 步骤五:安装 pandoc 和 texlive
- name: install pandoc
run: |
sudo apt-get update
sudo apt-get install texlive-full
sudo apt-get install pandoc
sudo apt-get clean
# 步骤六:使用 pandoc 命令生成 pdf
- name: build pdf
run: |
cd src
pandoc -f markdown-auto_identifiers --listings --pdf-engine=xelatex --template=../MPPL/templates/mppl.tex --output=../output/UEFI规范-中文.pdf *.md
# 步骤七:将生成的结果上传到 GitHub
- uses: actions/upload-artifact@master
with:
name: output
path: output

注意事项

every step must define a uses or run key
every step must define a uses or run key · Issue #2 · einaregilsson/beanstalk-deploy

参考

GH actions: a step cannot have both the uses and run keys · Issue #318 · fhem/mod-Buienradar

every step must define a uses or run key · Issue #2 · einaregilsson/beanstalk-deploy

需求背景

Markdown 中的表格,只要符合语法就能够正常渲染显示,但是符合语法但是 Markdown 源码却不一定易读。就如以下的这个表格,可以正常显示,但是源码在源文件中竖线不对齐,就阅读困难。

源码:

1
2
3
4
5
|诗名|作者|朝代|
|-|-|-|
|白头吟|卓文君|两汉|
|锦瑟|李商隐|唐代|
|登科后|孟郊|唐代|

显示效果:

诗名 作者 朝代
白头吟 卓文君 两汉
锦瑟 李商隐 唐代
登科后 孟郊 唐代

我们可以手动将其竖线对齐,如下这样就易读许多:

1
2
3
4
5
| 诗名   | 作者   | 朝代 |
| ------ | ------ | ---- |
| 白头吟 | 卓文君 | 两汉 |
| 锦瑟 | 李商隐 | 唐代 |
| 登科后 | 孟郊 | 唐代 |

显示效果保持一致。但是如果一个字符一个字符去手动对齐效率太低,也不符合 Markdown 设计初衷。这就用到了额外的插件,能够辅助我们完成这个工作。

Markdown All in One

VSCode 插件中心搜索Markdown All in One安装。

安装完成后,使用时右击窗口选择Format Document with

选择Markdown All in One即可自动对齐所有表格竖线:

常见问题

格式化文档后仍未对齐

这是由于表格中同时有中英文,而中英文字体不等宽导致的。如果对阅读要求不高,可以不用管,实际上已经格式化完成了。如果需要对齐,那么可以查看编码字体与阅读字体推荐这篇文章的中文等宽字体下载并安装,即可正常对齐。

Markdownlint 简介

Markdown 标记语言旨在易于阅读、编写和理解。它的灵活性既是优点也是缺点。语法众多,因此格式可能不一致。某些构造在所有解析器中都不能很好地工作,应该避免。CommonMark 规范标准化解析器。

Markdownlint 是一个用于 Node.js 的静态分析工具,有一个标准规范,用于强制执行 Markdown 文件的标准和一致性。

Markdownlint 插件使用

markdownlint提供了多种使用场景下的解决方案,如命令行,编辑器甚至 GitHub Action。因为我平时写 Markdown 文档都是使用 VSCode,所以介绍一下 VSCode 下的使用。其他编辑器包括 VIM,Sublime 也都支持,可以前往官网查阅方法。

VSCode 需要下载插件,Ctrl+Shift+X打开插件中心,搜索Markdownlint安装即可。

安装插件后打开 Markdown 文档,如果有不符合规范的语法将会警告标识。如,标题前后没有空行,将会标识:

提示违反了第 22 条规范,第 22 条规范的就是标题前后需要有空行隔开。

目前有 53 条规范,可以在markdownlint/Rules.md查看所有规范的内容。

当然这些规范也都可以自定义是否检查,比如第 24 条规定,文档内不可以有重复的标题,但是我就有重复标题的需求,那该如何关闭这个检查呢,Markdownlint 提供了配置的方式。

Ctrl+Shift+P打开运行窗口,输入 Markdownlint,找到Creat or open the markdownlint configuration file

创建一个配置文件,并输入以下内容,表示关闭第 24 条规范的检查:

1
2
3
{
"MD024": false,
}

这样文档中将不会有第 24 条规范的检查警告,其他检查同理。

Markdownlint 自定义规则

MD001 - Heading levels should only increment by one level at a time

标题等级一次只能增加一级,不能跨级。

原理:标题代表文档的结构,跳过时可能会造成混淆 - 特别是对于可访问性场景。

MD002 - First heading should be a top-level heading

文档的第一个标题必须是最高级的标题(标题等级 1 级到 6 级逐渐降低)

MD003 - Heading style

整篇文档需要采用一致的标题格式。

MD004 - Unordered list style

无序列表格式需要一致。

MD005 - Inconsistent indentation for list items at the same level

  • 同一级的列表缩进必须一致
  • 在有序列表中,前面的数字序号可以左对齐,也可以右对齐

MD006 - Consider starting bulleted lists at the beginning of the line

一级列表不能缩进。

如下为报错:

1
2
3
4
Some text

* List item
* List item

MD007 - Unordered list indentation

无序列表嵌套缩进时默认采用两个空格。

MD009 - Trailing spaces

行尾最多可以添加两个空格,超过会给出警告,两个空格正好可以用于换行。

MD010 - Hard tabs

不能使用 tab 键缩进,要使用空格。

原理:硬制表符通常由不同的编辑器以不一致的方式呈现,并且比空格更难处理。

当遇到看似链接的文本,但语法似乎已反转([] 和 () 反转)时,将触发此规则。

MD012 - Multiple consecutive blank lines

文档中不能有连续的空行,在代码块中此规则不会生效。

MD013 - Line length

默认行的最大长度是 80,此规则对代码块、表格、标题也生效。

MD014 - Dollar signs used before commands without showing output

在代码块中,终端命令前不需要有美元符号 ($)
如果代码块中既有终端命令,也有命令的输出,则终端命令前可以有美元符号 ($)。

MD018 - No space after hash on atx style heading

在”atx”格式的标题中,#号和文字间需用一个空格隔开。

MD019 - Multiple spaces after hash on atx style heading

在”atx”格式的标题中,#号和文字间只能用一个空格隔开,不能有多余的空格。

MD020 - No space inside hashes on closed atx style heading

在”closed_atx”格式的标题中,文字和前后的#号之间需用一个空格隔开。

MD021 - Multiple spaces inside hashes on closed atx style heading

在”closed_atx”格式的标题中,文字和前后的#号之间只能用一个空格隔开,不能有多余的空格。

MD022 - Headings should be surrounded by blank lines

标题行的上下行必须都是空行。

MD023 - Headings must start at the beginning of the line

标题行不能缩进。

MD024 - Multiple headings with the same content

文档不能有内容重复的标题。

MD025 - Multiple top-level headings in the same document

同一文档只能有一个最高级的标题,默认是只能有一个 1 级标题。

MD026 - Trailing punctuation in heading

标题行末尾不能有以下标点符号。

MD027 - Multiple spaces after blockquote symbol

创建引用区块时,右尖括号 ( > ) 和文字之间有且只能有一个空格。

MD028 - Blank line inside blockquote

两个引用区块间不能仅用一个空行隔开或者同一引用区块中不能有空行,如果一行中没有内容,则这一行要用>开头。

MD029 - Ordered list item prefix

有序列表的前缀序号格式必须只用 1 或者从 1 开始的加 1 递增数字。

MD030 - Spaces after list markers

列表(有序、无序)的前缀符号和文字之间用 1 个空格隔开
在列表嵌套或者同一列表项中有多个段落时,无序列表缩进两个空格,有序列表缩进 3 个空格。

MD031 - Fenced code blocks should be surrounded by blank lines

单独的代码块前后需要用空行隔开(除非是在文档开头或末尾),否则有些解释器不会解释为代码块

MD032 - Lists should be surrounded by blank lines

列表(有序、无序)前后需要用空行隔开,否则有些解释器不会解释为列表。

列表的缩进必须一致。

MD033 - Inline HTML

文档中不允许使用 HTML 语句。

MD034 - Bare URL used

单纯的链接地址需要用尖括号 (<>) 包裹,否则有些解释器不会解释为链接。

MD035 - Horizontal rule style

创建水平线时整篇文档要统一 (consistent),要和文档中第一次创建水平线使用的符号一致。

MD036 - Emphasis used instead of a heading

不能用加粗代替标题。

MD037 - Spaces inside emphasis markers

用于创建强调的符号和强调的的文字之间不能有空格。

MD038 - Spaces inside code span elements

当用单反引号创建代码段的时候,单反引号和它们之间的代码不能有空格
如果要把单反引号嵌入到代码段的首尾,创建代码段的单反引号和嵌入的单反引号间要有一个空格隔开。

链接名和包围它的中括号之间不能有空格,但链接名中间可以有空格。

MD040 - Fenced code blocks should have a language specified

单独的代码块(此处是指上下用三个反引号包围的代码块)应该指定代码块的编程语言,这一点有助于解释器对代码进行代码高亮。

MD041 - First line in a file should be a top-level heading

文档的第一个非空行应该是文档最高级的标题,默认是 1 级标题。

链接的地址不能为空。

MD043 - Required heading structure

要求标题遵循一定的结构,默认是没有规定的结构。

MD044 - Proper names should have the correct capitalization

指定一些名称,会检查它是否有正确的大写。

MD045 - Images should have alternate text (alt text)

图片链接必须包含描述文本(alt text)。

MD046 - Code block style

整篇文档采用一致的代码格式。

MD047 - Files should end with a single newline character

文档需用一个空行结尾。

MD048 - Code fence style

表示代码块的标记需要一直,可以是波浪号,也可以是点号。但是需要保持一致。

MD049 - Emphasis style should be consistent

强调符号需要一直,如斜体。

MD050 - Strong style should be consistent

加粗符号需要保持一致。

锚点需要表示正确。

需求背景

在写 MD 文档时为了追求美观,表格通常都是对齐的,这就需要字体必须等宽,但是写代码时等宽字体的因为很瘦小,不容易阅读,所以想要一个插件能够在多个字体直接快速切换。万能 VSCode 啥都有,插件中心就有一款专门切换字体的插件Font Switcher。直接搜索安装。

配置与使用

打开配置脚本settings.json,如果以前修改过字体,找到"editor.fontFamily"配置项,如果没有就直接添加。

这是我的字体,添加你们机器上安装的字体,每个逗号间隔都是不同的字体,可以使用Font Switcher切换,需要注意的是,字体名没有空格不需要加单引号,加了也无妨,如果有空格,一定要加引号

1
"editor.fontFamily": "'Sarasa Mono SC', 微软雅黑,'Noto Sans Mono CJK SC', 'JetBrains Mono', Consolas, monospace",

Ctrl+Shift+P打开运行窗口,输入Switch Font,选择切换的字体。如图:

![](https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/12/15-17-44-dd742307432154f630585e05a1f57956-GIF 2022-9-12 15-17-27-836285.gif)

SSH 总是被强行中断,尤其是用 VSCode 代码写的好好的,突然刷新窗口,不仅效率低,更惹人恼火。

可以通过配置服务端或客户端的 SSH 来保持 SSH 链接:

方法一:配置服务端

可以在服务端配置,让 server 每隔 30 秒向 client 发送一个 keep-alive 包来保持连接:

1
vim /etc/ssh/sshd_config
1
2
ClientAliveInterval 30
ClientAliveCountMax 60

第二行配置表示如果发送 keep-alive 包数量达到 60 次,客户端依然没有反应,则服务端 sshd 断开连接。如果什么都不操作,该配置可以让连接保持 30s*60,30 min

重启本地 ssh

1
sudo service ssh restart

如果找不到 ssh,”Failed to restart ssh.service: Unit ssh.service not found.” ,需要安装

1
sudo apt-get install openssh-server

方法二:配置客户端

如果服务端没有权限配置,或者无法配置,可以配置客户端 ssh,使客户端发起的所有会话都保持连接:

1
vim /etc/ssh/ssh_config
1
2
ServerAliveInterval 30
ServerAliveCountMax 60

本地 ssh 每隔 30s 向 server 端 sshd 发送 keep-alive 包,如果发送 60 次,server 无回应断开连接。

在 VSCode 里可以直接添加配置,效果一样:

1
2
3
4
5
6
Host 11.22.33.44
HostName 11.22.33.44
User user
Port 112343
ServerAliveInterval 30
ServerAliveCountMax 60

折腾背景

一直想找一个能够快速同步手机与电脑数据的工具,因为手机云服务的空间少的可怜,所以习惯隔一段时间将手机里的照片、视频还有一些文件导出到电脑上。但是每次备份文件都得连接数据线,并且没法增量备份,得手动挑选,也还挺麻烦的。

逛 GitHub 时,无意间发现了 Syncthing,几乎符合了我所有的预期。

  • 开源,免费,自己电脑就可以当服务器,以后入了 NAS,可以自己搭建本地服务器。
  • 同步速度快,取决 WIFI 的速度,目前使用 30M/s,基本满速。
  • 多端支持,除了 IOS(反正我也没有 iOS 设备,嘿嘿),几乎全平台支持,包括 NAS 及路由器。
  • 增量同步,再也不用挑文件备份了。

话不多说,开整。

下载安装

直接进入Syncthing官网,下载安装。在 Ubuntu 下安装参考这里。Android 版本下载Syncthing

接下来以 Windows 与 Android 手机同步为例,下载安装后,打开syncthing.exe,即可打开管理界面,或者浏览器输入http://127.0.0.1:8384也可进入管理界面。

Windows 界面:

Android 界面:

设备配对

Windows 管理页面->操作->显示 ID,会显示本机的二维码:

Android 手机打开应用,切换到设备界面,点击右上角加号,点击二维码标识,即可扫描二维码,完成设备添加。

如果正确添加,Windows 管理界面会显示 Android 设备:

Android 同步至 Windows

打开 Android 应用,切换到文件夹界面,点击右上角加号,配置同步的文件夹:

根据下图提示,配置应用,记得保存:

目录列表显示刚刚的配置:

点击打开,开启与远程设备 Windows 同步:

当返回时,Windows 端将会弹出通知,提示有 Android 设备的文件要分享到电脑,点击添加

至此,Android 同步至 Windows 完成。此时在 Android 设备的文件夹中添加任意文件,都会同步到 Windows。

如果是局域网内,发现设备的速度很慢,可以尝试设置静态的 IP。手机端 -> 设备 -> 链接图标。默认为 dynamic,将其改为 Windows 的 IP 和 syncthing 的端口。如tcp://192.168.1.9:22000

也可以在服务端配置手机的IP,手机IP可以通过设置中心->关于手机->状态->IP地址查看。比如192.168.1.16,那么可以配置为tcp://192.168.1.16:22000

Windows 同步至 Android

Windows 管理界面,添加文件夹:

点击保存后,与之前类似,Android 会提示有 Windows 设备的文件要分享到 Android,点击添加

如果 Android 设备没有弹出提示添加共享文件夹,那么打开应用侧边栏->网页管理页面,将会有弹窗,如下图

点击添加,配置文件夹目录等与之前类似。

至此,Windows 同步至 Android 完成。此时在 Windows 设备的文件夹中添加任意文件,都会同步到 Android。

使用技巧

Syncthing 支持三种工作模式

  • 发送和接收,Send & Receive Folder,这是文件夹的默认模式,对文件夹的修改会发送,其他设备的修改也会同步回来。
  • 仅发送 Send Only,这种模式表示仅仅将当前设备上的文件夹的改动发送到其他设备,用来隐式地表示其他同步设备上的文件不会被修改,或者其他设备上的修改可以被忽略。这种模式非常适合,将当前设备设定为工作设备,然后设定一台设备作为此设备的备份。
    • 在 Send Only 模式下,集群中其他设备的修改都会被忽略,修改依然会接收,文件夹可能会出现 「out of sync」,但是没有修改会被应用到本地。
    • 当 Send Only 文件夹出现 out of sync,那么一个红色的 Override Changes 会出现在文件夹详情中,点击该按钮会强制将当前主机的状态同步到其他剩余节点。任何对文件的修改,都会被当前主机上的版本所覆盖,任何不存在于当前主机节点的文件都会被删除,其他类似。
  • 仅接收 Receive Only,这种模式下所有的修改都会被接收并应用,然后重新分发给其他使用 send-receive 模式的设备。但是本地的修改不会被分发给其他设备。这种模式适合于建立备份镜像(replication mirrors),或者备份目的主机的场景,这些情况下不期望有本地修改或者本地的修改是不允许的
    • 当本地文件被删除时,Syncthing 会显示一个 Revert Local Changes 按钮。使用这个按钮会将本地的修改回撤,所有添加的文件会被删除,修改或删除的文件会重新从其他节点同步,比较容易理解,但是假如 A 设备设置仅发送,B 设备设置发送和接收,A 是不会同步 B 的更改的!

忽略特定文件、目录

忽略列表,和 gitignore 类似。每一台设备上的 .stignore 都是分别设置的,不会进行同步。

如果 A 的.stignore忽略了 test ,而 B 没有这样做,实际上会发生这样的事情:

  • A 不会扫描和通知 B(广播)关于 test 的变动;
  • B 对关于 test 的变动持开放的姿态,但不会收到任何关于 A 上面 test 的变动信息(可能接收到其它同步设备的);
  • B 会扫描 test 以及推送其关于 test 变动的信息,但会被 A 忽略,A 也会忽略其它同步设备关于 test 的信息;
  • B 会接收来自其它同步设备推送的关于 test 的信息;

参考资料

Syncthing 又一款同步工具 | Verne in GitHub

Folder Types — Syncthing documentation

背景

公司使用 Gerrit 作为 Review 平台,但是每次提交代码都需要手动添加 Reviewer,还要抄送组内成员,这种重复性劳动,程序员是绝不能容忍的。gerrit 提供了发送邮件的功能。

解决方法

官方示例:

1
git push ssh://john.doe@git.example.com:29418/kernel/common HEAD:refs/for/experimental%r=a@a.com,cc=b@o.com

最后的%是个分隔符,r='a@a.com表示 Reviewer 是a@a.comcc=b@o.com表示抄送组内成员是b@o.com

注意!邮箱之间不能有空格!

以一个仓库为例:

1
git push origin HEAD:refs/for/branch_dev_name%cc=zhangsan@qq.com,cc=lisi@qq.com,cc=wangerma@qq.com,cc=chenwu@qq.com

但是要这么写,岂不是把操作搞更复杂了。

终极办法,打开项目路径下的.git目录。编辑config文件:

原文件里有如下字段:

1
2
3
4
5
6
7
8
9
[core]
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
ignorecase = true
[remote "origin"]
url = git@github.com:Dunky-Z/Dunky-Z.github.io.git
fetch = +refs/heads/*:refs/remotes/origin/*

我们可以将远程仓库名换成容易区分的名字,自己随意:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[core]
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
ignorecase = true
[remote "origin"]
url = git@github.com:Dunky-Z/Dunky-Z.github.io.git
fetch = +refs/heads/*:refs/remotes/origin/*
# 以下为新增内容
[remote "review"]
url = git@github.com:Dunky-Z/Dunky-Z.github.io.git
fetch = +refs/heads/*:refs/remotes/origin/*
push = HEAD:refs/for/%cc=zhangsan@qq.com,
cc=lisi@qq.com,
cc=wangerma@qq.com,
cc=chenwu@qq.com

下次想要推送需要 review 的代码,就直接执行git push review,其中push就相当于:

1
push HEAD:refs/for/%cc=zhangsan@qq.com,cc=lisi@qq.com,cc=wangerma@qq.com,cc=chenwu@qq.com

参考资料

Gerrit Code Review - Uploading Changes

KeePass 安装

下载与安装

官网: https://keepass.info/download.html

下载完成后进行安装,默认安装位置是:C:\Program Files (x86)\KeePass Password Safe 2文件夹下,可以根据自己需要选择安装路径。

更改中文语言

中文语言包: KeePass-Chinese_Simplified

将语言包下载后复制到安装路径下的Languages文件夹下,默认为:C:\Program Files (x86)\KeePass Password Safe 2\Languages。重启软件

点击 View->Change Language. 选择中文简体(Chinese-Simplified)。重启软件,即可完成语言更改。

中文界面:

基本使用

1.创建一个数据库

点击 文件-》新建。弹出对话框为数据库创建管理密码。这个密码是唯一需要记忆的密码。当然如果追求更高的安全性,可以点击显示高级选项,提供更多的密码选项。

2.添加记录

点击添加记录,在弹出的窗口填入相关信息。即可完成密码添加。

如果是第一次使用的网站,第一次注册密码。可以通过密码生成器,生成一个高强度的密码来添加记录。

3.创建一个密码生成模板

正常国内的网站可以使用的密码长度 6-16 位,可以使用大小写,数字,下划线。我们把这些选项勾选,密码长度设置 16 位。

点击保存并给模板设置个名字方便下次使用

如果保存后想更改一下,比如再加个可以使用空格,可以重新勾选刚刚的选项,保存时点击小三角,选择刚刚保存的方案就可以覆盖。

导入 Chrome 已保存的密码

很多小伙伴在使用 KeePass 之前肯定在 Chrome 等浏览器里也保存了很多密码。想将其导入 KeePass 方便管理。Chrome 是可以导出密码的,KeePass 也可以导入密码。

点击浏览器右上角,打开设置界面。找到密码

找到已保存的密码-》导出密码。选择方便找到的路径,保存密码记录。

打开 KeePass,点击文件-》导入,选择 Chrome 浏览器的格式。点击文件夹图标找到刚刚导出的密码文件。

高级配置

KeePass 搭配坚果云实现云同步

登录坚果云创建个人同步文件夹,若没有先注册。

最好单独建一个专门的文件夹

将已经生成的数据库上传到这个文件夹下

点击右上角进入账户信息,点击安全选项:

点击添加应用

输入应用名称,应用名称只是方便区分作用,所以和要同步的应用名称一致就好:

点击生成密码

此时云盘端配置完成,切回到 KeePass 进行客户端配置。点击文件-》同步-》与网址(URL)同步

网址: https://dav.jianguoyun.com/dav/KeePass/keepassData.kdbx

注意:红色部分是个人同步文件夹的名称,绿色部分是上传的数据库全称,一定别忘了后缀

用户名:你的坚果云登录名(邮箱或者手机号)

密码:生成应用的密码,(不是登录坚果云的密码

点击确定,此时已经可以完成同步,但是每次同步仍然需要手动确定。参考了什么值得买上小乐 CSN的方法,通过触发器实现自动同步。

触发器代码:

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
<?xml version="1.0" encoding="utf-8"?>
<TriggerCollection xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <Triggers>
                <Trigger>
                        <Guid>L2euC7Mr/EKh7nPjueuZvQ==</Guid>
                        <Name>SaveSync</Name>
                        <Events>
                                <Event>
                                        <TypeGuid>s6j9/ngTSmqcXdW6hDqbjg==</TypeGuid>
                                        <Parameters>
                                                <Parameter>1</Parameter>
                                                <Parameter>kdbx</Parameter>
                                        </Parameters>
                                </Event>
                        </Events>
                        <Conditions />
                        <Actions>
                                <Action>
                                        <TypeGuid>tkamn96US7mbrjykfswQ6g==</TypeGuid>
                                        <Parameters>
                                                <Parameter>SaveSync</Parameter>
                                                <Parameter>0</Parameter>
                                        </Parameters>
                                </Action>
                                <Action>
                                        <TypeGuid>Iq135Bd4Tu2ZtFcdArOtTQ==</TypeGuid>
                                        <Parameters>
                                                <Parameter>https://dav.jianguoyun.com/dav/keePass/passwordSync.kdbx</Parameter>
                                                <Parameter>123456</Parameter>
                                                <Parameter>123456</Parameter>
                                        </Parameters>
                                </Action>
                                <Action>
                                        <TypeGuid>tkamn96US7mbrjykfswQ6g==</TypeGuid>
                                        <Parameters>
                                                <Parameter>SaveSync</Parameter>
                                                <Parameter>1</Parameter>
                                        </Parameters>
                                </Action>
                        </Actions>
                </Trigger>
        </Triggers>
</TriggerCollection>

复制触发器代码,点击工具-》触发器,点击工具-》从剪切板粘贴触发器

导入成功后,在触发器页面会多一个触发器:

双击打开SaveSync,打开最后一个动作窗口:

双击中间的条目:

将信息换成同步云盘的信息:

文件/网址: https://dav.jianguoyun.com/dav/KeePass/keepassData.kdbx

注意:红色部分是个人同步文件夹的名称,绿色部分是上传的数据库全称,一定别忘了后缀

IO 连接 - 用户名:你的坚果云登录名(邮箱或者手机号)

IO 连接 - 密码:生成应用的密码,(不是登录坚果云的密码

点击确定,回到主页面,点击工具-》选项

找到 高级,向下翻,在文件输入/输出连接 栏目里找到 写入数据库时使用文件交换 此项不勾选

点击确定,返回主页面。此时点击保存按钮或者 Ctrl+S。即可与云盘进行同步。

Chrome 上使用插件实现密码自动填充与同步

在 KeePass 客户端安装KeePassRPC 插件

将其放入安装目录(.\KeePass\Plugins)文件夹下,退出软件,重启即可自动安装。

在浏览器客户端安装浏览器插件Kee,若无法科学上网,可能需要自行百度搜索 Kee 插件

安装完成后会跳出窗口提示授权,将 KeePass 客户端跳出的窗口中的红色授权码填入即可连接浏览器:

使用 Kee

再次使用浏览器填写密码是可以看到文本框会有 logo,Kee 会自动填写已保存的密码。如果第一次登陆,在登录后可以点击浏览器插件图标,找到 Save latest login,保存刚刚输入的密码。

密码管理器的重要作用之一就是生成高强度密码,可以用 KeePass 客户端来生成,也可以是 Kee 这个插件的一个生成密码功能生成。英文版的是Generate new password

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×