<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Efficiency on 夜云泊</title>
    <link>https://lifeislife.cn/tags/efficiency/</link>
    <description>feedId:57980998056508425+userId:73222296380546048 Recent content in Efficiency on 夜云泊</description>
    <generator>Hugo -- 0.157.0</generator>
    <language>zh</language>
    <lastBuildDate>Tue, 19 Sep 2023 19:51:18 +0000</lastBuildDate>
    <atom:link href="https://lifeislife.cn/tags/efficiency/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>ocrmypdf 让 PDF 可搜索</title>
      <link>https://lifeislife.cn/posts/ocrmypdf-%E8%AE%A9pdf%E5%8F%AF%E6%90%9C%E7%B4%A2/</link>
      <pubDate>Tue, 19 Sep 2023 19:51:18 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/ocrmypdf-%E8%AE%A9pdf%E5%8F%AF%E6%90%9C%E7%B4%A2/</guid>
      <description>&lt;p&gt;买的一些课程配套资料都是 PDF 格式的，为了防止盗版都事先用的图片转成的 PDF，这样 PDF 里的内容既没法复制也没法搜索，在查找资料里的关键词的时候就很不方便，所以就想着把这些 PDF 转成可搜索的 PDF。找到了一款工具叫做 ocrmypdf，可以把 PDF 转成可搜索的 PDF，而且还支持中文，这里记录一下使用方法。详细使用文档可以参考官方文档&lt;a href=&#34;https://ocrmypdf.readthedocs.io/en/latest/installation.html&#34;&gt; OCRmyPDF documentation&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&#34;安装&#34;&gt;安装&lt;/h1&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo apt install ocrmypdf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;使用&#34;&gt;使用&lt;/h1&gt;
&lt;h2 id=&#34;指定-ocr-的语言&#34;&gt;指定 OCR 的语言&lt;/h2&gt;
&lt;p&gt;安装语言包&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo apt install tesseract-ocr-chi-sim
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;查看是否安装成功&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ tesseract --list-langs
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;List of available languages &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;3&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;chi_sim
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;eng
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;osd
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;注意参数 &lt;code&gt;-l&lt;/code&gt; 后面的语言包名称是下划线，而不是短横线。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ocrmypdf -l chi_sim input.pdf output.pdf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$  ocrmypdf -l chi_sim  --redo-ocr  input.pdf output.pdf
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Scanning contents: 100%&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;██████████████████████████████████████████████████████████████████████████████████████████████████████&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; 752/752 &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;00:14&amp;lt;00:00, 51.36page/s&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Start processing &lt;span class=&#34;m&#34;&gt;24&lt;/span&gt; pages concurrently
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;m&#34;&gt;33&lt;/span&gt; redoing OCR                                                                                                                                                 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;m&#34;&gt;26&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;m&#34;&gt;54&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;m&#34;&gt;88&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;119&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;203&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;256&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;265&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;347&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;376&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;383&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;386&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;402&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;404&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;403&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;412&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;415&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;410&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;439&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;519&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;526&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;587&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;591&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;595&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;607&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;644&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;661&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;682&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;720&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;m&#34;&gt;742&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;tesseract&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; lots of diacritics - possibly poor OCR                                                                                                          
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;OCR: 100%&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;████████████████████████████████████████████████████████████████████████████████████████████████████████████████&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; 752.0/752.0 &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;03:41&amp;lt;00:00,  3.40page/s&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Postprocessing...
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Some input metadata could not be copied because it is not permitted in PDF/A. You may wish to examine the output PDF&lt;span class=&#34;err&#34;&gt;&amp;#39;&lt;/span&gt;s XMP metadata.                              
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;PDF/A conversion: 100%&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;███████████████████████████████████████████████████████████████████████████████████████████████████████&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; 752/752 &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;01:09&amp;lt;00:00, 10.80page/s&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Recompressing JPEGs: 0image &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;00:00, ?image/s&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Deflating JPEGs: 100%&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;██████████████████████████████████████████████████████████████████████████████████████████████████████&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; 756/756 &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;00:00&amp;lt;00:00, 920.21image/s&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;JBIG2: 0item &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;00:00, ?item/s&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Optimize ratio: 1.20 savings: 17.0%
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Output file is okay but is not PDF/A &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;seems to be No PDF/A metadata in XMP&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;转换的结果还不错，页面排版不会改变，保持原样，但是搜索文字时可能需要用空格分开。&lt;/p&gt;
</description>
      <content:encoded><![CDATA[<p>买的一些课程配套资料都是 PDF 格式的，为了防止盗版都事先用的图片转成的 PDF，这样 PDF 里的内容既没法复制也没法搜索，在查找资料里的关键词的时候就很不方便，所以就想着把这些 PDF 转成可搜索的 PDF。找到了一款工具叫做 ocrmypdf，可以把 PDF 转成可搜索的 PDF，而且还支持中文，这里记录一下使用方法。详细使用文档可以参考官方文档<a href="https://ocrmypdf.readthedocs.io/en/latest/installation.html"> OCRmyPDF documentation</a>。</p>
<h1 id="安装">安装</h1>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt install ocrmypdf
</span></span></code></pre></div><h1 id="使用">使用</h1>
<h2 id="指定-ocr-的语言">指定 OCR 的语言</h2>
<p>安装语言包</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt install tesseract-ocr-chi-sim
</span></span></code></pre></div><p>查看是否安装成功</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ tesseract --list-langs
</span></span><span class="line"><span class="cl">List of available languages <span class="o">(</span>3<span class="o">)</span>:
</span></span><span class="line"><span class="cl">chi_sim
</span></span><span class="line"><span class="cl">eng
</span></span><span class="line"><span class="cl">osd
</span></span></code></pre></div><p>注意参数 <code>-l</code> 后面的语言包名称是下划线，而不是短横线。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ocrmypdf -l chi_sim input.pdf output.pdf
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$  ocrmypdf -l chi_sim  --redo-ocr  input.pdf output.pdf
</span></span><span class="line"><span class="cl">Scanning contents: 100%<span class="p">|</span>██████████████████████████████████████████████████████████████████████████████████████████████████████<span class="p">|</span> 752/752 <span class="o">[</span>00:14&lt;00:00, 51.36page/s<span class="o">]</span>
</span></span><span class="line"><span class="cl">Start processing <span class="m">24</span> pages concurrently
</span></span><span class="line"><span class="cl">   <span class="m">33</span> redoing OCR                                                                                                                                                 
</span></span><span class="line"><span class="cl">   <span class="m">26</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">   <span class="m">54</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">   <span class="m">88</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">119</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">203</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">256</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">265</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">347</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">376</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">383</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">386</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">402</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">404</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">403</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">412</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">415</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">410</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">439</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">519</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">526</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">587</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">591</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">595</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">607</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">644</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">661</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">682</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">720</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">  <span class="m">742</span> <span class="o">[</span>tesseract<span class="o">]</span> lots of diacritics - possibly poor OCR                                                                                                          
</span></span><span class="line"><span class="cl">OCR: 100%<span class="p">|</span>████████████████████████████████████████████████████████████████████████████████████████████████████████████████<span class="p">|</span> 752.0/752.0 <span class="o">[</span>03:41&lt;00:00,  3.40page/s<span class="o">]</span>
</span></span><span class="line"><span class="cl">Postprocessing...
</span></span><span class="line"><span class="cl">Some input metadata could not be copied because it is not permitted in PDF/A. You may wish to examine the output PDF<span class="err">&#39;</span>s XMP metadata.                              
</span></span><span class="line"><span class="cl">PDF/A conversion: 100%<span class="p">|</span>███████████████████████████████████████████████████████████████████████████████████████████████████████<span class="p">|</span> 752/752 <span class="o">[</span>01:09&lt;00:00, 10.80page/s<span class="o">]</span>
</span></span><span class="line"><span class="cl">Recompressing JPEGs: 0image <span class="o">[</span>00:00, ?image/s<span class="o">]</span>
</span></span><span class="line"><span class="cl">Deflating JPEGs: 100%<span class="p">|</span>██████████████████████████████████████████████████████████████████████████████████████████████████████<span class="p">|</span> 756/756 <span class="o">[</span>00:00&lt;00:00, 920.21image/s<span class="o">]</span>
</span></span><span class="line"><span class="cl">JBIG2: 0item <span class="o">[</span>00:00, ?item/s<span class="o">]</span>
</span></span><span class="line"><span class="cl">Optimize ratio: 1.20 savings: 17.0%
</span></span><span class="line"><span class="cl">Output file is okay but is not PDF/A <span class="o">(</span>seems to be No PDF/A metadata in XMP<span class="o">)</span>
</span></span></code></pre></div><p>转换的结果还不错，页面排版不会改变，保持原样，但是搜索文字时可能需要用空格分开。</p>
]]></content:encoded>
    </item>
    <item>
      <title>如何离线安装 VSCode 插件</title>
      <link>https://lifeislife.cn/posts/%E5%A6%82%E4%BD%95%E7%A6%BB%E7%BA%BF%E5%AE%89%E8%A3%85vscode%E6%8F%92%E4%BB%B6/</link>
      <pubDate>Tue, 29 Aug 2023 20:59:19 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/%E5%A6%82%E4%BD%95%E7%A6%BB%E7%BA%BF%E5%AE%89%E8%A3%85vscode%E6%8F%92%E4%BB%B6/</guid>
      <description>&lt;h1 id=&#34;背景简介&#34;&gt;背景简介&lt;/h1&gt;
&lt;p&gt;在使用 VSCode 的过程中，我们经常会安装一些插件来提高开发效率。但是，由于某些原因，我们可能无法直接访问 VSCode 的插件市场，这时候我们就需要离线安装插件了。&lt;/p&gt;
&lt;p&gt;这里存在两种情况，一种是为本地的 VSCode 安装插件，另一种是为远程的 VSCode 安装插件。本文将分别介绍这两种情况下的离线安装方法。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;远程 VSCode 也就是 VSCode 的&lt;a href=&#34;https://code.visualstudio.com/docs/remote/remote-overview&#34;&gt;Remote Development&lt;/a&gt;功能，可以通过 SSH、Docker、WSL 等方式远程连接到远程主机上的 VSCode。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&#34;方法一使用已安装的插件目录&#34;&gt;方法一：使用已安装的插件目录&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;从已经安装插件的电脑上拷贝所有插件，路径一般为 &lt;code&gt;C:\用户\用户名\.vscode\extensions&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;拷贝到离线安装的电脑上的 &lt;code&gt;.vscode/extensions&lt;/code&gt; 文件夹下即可，重启 VScode 即可安装成功。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对于远程 VSCode 我们需要知道，插件不区分操作系统，所以我们可以在本地的 Windows 上的 VSCode 上安装插件，然后将插件目录压缩后整个拷贝到远程主机上即可。&lt;/p&gt;
&lt;p&gt;远程主机上的插件目录一般在 &lt;code&gt;~/.vscode-server/extensions&lt;/code&gt; 下。将压缩的文件解药到这个目录下，重启 VSCode 即可。&lt;/p&gt;
&lt;h1 id=&#34;方法二下载离线安装包-vslx-安装&#34;&gt;方法二：下载离线安装包 vslx 安装&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;到 &lt;a href=&#34;https://marketplace.visualstudio.com/vscode&#34;&gt;VScode 插件中心&lt;/a&gt; 搜索需要使用的插件名称&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;下载对应的拓展程序文件，下载的文件的后缀是&lt;code&gt;.vslx&lt;/code&gt;


&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/08/29/f4349bbfc8cf734951fc70e2f5b0eabd.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/08/29/f4349bbfc8cf734951fc70e2f5b0eabd.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;VSCode 中安装


&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/08/29/25b2839add215a8a61449f0ac9b1ca81.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/08/29/25b2839add215a8a61449f0ac9b1ca81.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
      <content:encoded><![CDATA[<h1 id="背景简介">背景简介</h1>
<p>在使用 VSCode 的过程中，我们经常会安装一些插件来提高开发效率。但是，由于某些原因，我们可能无法直接访问 VSCode 的插件市场，这时候我们就需要离线安装插件了。</p>
<p>这里存在两种情况，一种是为本地的 VSCode 安装插件，另一种是为远程的 VSCode 安装插件。本文将分别介绍这两种情况下的离线安装方法。</p>
<blockquote>
<p>远程 VSCode 也就是 VSCode 的<a href="https://code.visualstudio.com/docs/remote/remote-overview">Remote Development</a>功能，可以通过 SSH、Docker、WSL 等方式远程连接到远程主机上的 VSCode。</p>
</blockquote>
<h1 id="方法一使用已安装的插件目录">方法一：使用已安装的插件目录</h1>
<ul>
<li>从已经安装插件的电脑上拷贝所有插件，路径一般为 <code>C:\用户\用户名\.vscode\extensions</code></li>
<li>拷贝到离线安装的电脑上的 <code>.vscode/extensions</code> 文件夹下即可，重启 VScode 即可安装成功。</li>
</ul>
<p>对于远程 VSCode 我们需要知道，插件不区分操作系统，所以我们可以在本地的 Windows 上的 VSCode 上安装插件，然后将插件目录压缩后整个拷贝到远程主机上即可。</p>
<p>远程主机上的插件目录一般在 <code>~/.vscode-server/extensions</code> 下。将压缩的文件解药到这个目录下，重启 VSCode 即可。</p>
<h1 id="方法二下载离线安装包-vslx-安装">方法二：下载离线安装包 vslx 安装</h1>
<ul>
<li>
<p>到 <a href="https://marketplace.visualstudio.com/vscode">VScode 插件中心</a> 搜索需要使用的插件名称</p>
</li>
<li>
<p>下载对应的拓展程序文件，下载的文件的后缀是<code>.vslx</code>


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/08/29/f4349bbfc8cf734951fc70e2f5b0eabd.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/08/29/f4349bbfc8cf734951fc70e2f5b0eabd.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
</li>
<li>
<p>VSCode 中安装


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/08/29/25b2839add215a8a61449f0ac9b1ca81.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/08/29/25b2839add215a8a61449f0ac9b1ca81.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
</li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Windows 端口映射</title>
      <link>https://lifeislife.cn/posts/windows%E7%AB%AF%E5%8F%A3%E6%98%A0%E5%B0%84/</link>
      <pubDate>Mon, 28 Aug 2023 23:24:53 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/windows%E7%AB%AF%E5%8F%A3%E6%98%A0%E5%B0%84/</guid>
      <description>&lt;h1 id=&#34;命令行&#34;&gt;命令行&lt;/h1&gt;
&lt;p&gt;在 Windows 中，可以使用 netsh 命令来添加、查看和删除端口转发规则。&lt;/p&gt;
&lt;p&gt;要&lt;strong&gt;添加一个端口转发规则&lt;/strong&gt;，可以使用以下命令：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;netsh interface portproxy add v4tov4 &lt;span class=&#34;nv&#34;&gt;listenaddress&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&amp;lt;local_address&amp;gt; &lt;span class=&#34;nv&#34;&gt;listenport&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&amp;lt;local_port&amp;gt; &lt;span class=&#34;nv&#34;&gt;connectaddress&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&amp;lt;remote_address&amp;gt; &lt;span class=&#34;nv&#34;&gt;connectport&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&amp;lt;remote_port&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;local_address&amp;gt;&lt;/code&gt;是本地监听的地址（可以是 IP 地址或 0.0.0.0 表示所有地址）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;local_port&amp;gt;&lt;/code&gt;是本地监听的端口。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;remote_address&amp;gt;&lt;/code&gt;是转发连接到的远程地址。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;remote_port&amp;gt;&lt;/code&gt;是转发连接到的远程端口。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例如，要将本地的 8080 端口转发到远程服务器上的 80 端口，可以使用以下命令：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;netsh interface portproxy add v4tov4 &lt;span class=&#34;nv&#34;&gt;listenaddress&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;127.0.0.1 &lt;span class=&#34;nv&#34;&gt;listenport&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8080&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;connectaddress&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;192.168.0.100 &lt;span class=&#34;nv&#34;&gt;connectport&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;要&lt;strong&gt;查看当前的端口转发规则&lt;/strong&gt;，可以使用以下命令：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;netsh interface portproxy show v4tov4
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;要&lt;strong&gt;删除特定的端口转发规则&lt;/strong&gt;，可以使用以下命令：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;netsh interface portproxy delete v4tov4 &lt;span class=&#34;nv&#34;&gt;listenaddress&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&amp;lt;local_address&amp;gt; &lt;span class=&#34;nv&#34;&gt;listenport&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&amp;lt;local_port&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;其中的&lt;code&gt;&amp;lt;local_address&amp;gt;&lt;/code&gt;和&lt;code&gt;&amp;lt;local_port&amp;gt;&lt;/code&gt;应该与你想删除的规则匹配。&lt;/p&gt;
&lt;p&gt;请注意，执行这些操作通常需要管理员权限。&lt;/p&gt;
&lt;h1 id=&#34;gui&#34;&gt;GUI&lt;/h1&gt;
&lt;p&gt;使用开源工具&lt;a href=&#34;https://github.com/zmjack/PortProxyGUI/releases&#34;&gt;PortProxyGUI&lt;/a&gt;可以在 UI 界面快速增删改查端口映射。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/08/28/e5bf0ce1f4a25150f69586825c2e7309.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/08/28/e5bf0ce1f4a25150f69586825c2e7309.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
</description>
      <content:encoded><![CDATA[<h1 id="命令行">命令行</h1>
<p>在 Windows 中，可以使用 netsh 命令来添加、查看和删除端口转发规则。</p>
<p>要<strong>添加一个端口转发规则</strong>，可以使用以下命令：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">netsh interface portproxy add v4tov4 <span class="nv">listenaddress</span><span class="o">=</span>&lt;local_address&gt; <span class="nv">listenport</span><span class="o">=</span>&lt;local_port&gt; <span class="nv">connectaddress</span><span class="o">=</span>&lt;remote_address&gt; <span class="nv">connectport</span><span class="o">=</span>&lt;remote_port&gt;
</span></span></code></pre></div><p>其中：</p>
<ul>
<li><code>&lt;local_address&gt;</code>是本地监听的地址（可以是 IP 地址或 0.0.0.0 表示所有地址）。</li>
<li><code>&lt;local_port&gt;</code>是本地监听的端口。</li>
<li><code>&lt;remote_address&gt;</code>是转发连接到的远程地址。</li>
<li><code>&lt;remote_port&gt;</code>是转发连接到的远程端口。</li>
</ul>
<p>例如，要将本地的 8080 端口转发到远程服务器上的 80 端口，可以使用以下命令：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">netsh interface portproxy add v4tov4 <span class="nv">listenaddress</span><span class="o">=</span>127.0.0.1 <span class="nv">listenport</span><span class="o">=</span><span class="m">8080</span> <span class="nv">connectaddress</span><span class="o">=</span>192.168.0.100 <span class="nv">connectport</span><span class="o">=</span><span class="m">80</span>
</span></span></code></pre></div><p>要<strong>查看当前的端口转发规则</strong>，可以使用以下命令：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">netsh interface portproxy show v4tov4
</span></span></code></pre></div><p>要<strong>删除特定的端口转发规则</strong>，可以使用以下命令：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">netsh interface portproxy delete v4tov4 <span class="nv">listenaddress</span><span class="o">=</span>&lt;local_address&gt; <span class="nv">listenport</span><span class="o">=</span>&lt;local_port&gt;
</span></span></code></pre></div><p>其中的<code>&lt;local_address&gt;</code>和<code>&lt;local_port&gt;</code>应该与你想删除的规则匹配。</p>
<p>请注意，执行这些操作通常需要管理员权限。</p>
<h1 id="gui">GUI</h1>
<p>使用开源工具<a href="https://github.com/zmjack/PortProxyGUI/releases">PortProxyGUI</a>可以在 UI 界面快速增删改查端口映射。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/08/28/e5bf0ce1f4a25150f69586825c2e7309.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/08/28/e5bf0ce1f4a25150f69586825c2e7309.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
]]></content:encoded>
    </item>
    <item>
      <title>内网穿透远程访问家里的 WSL2</title>
      <link>https://lifeislife.cn/posts/%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F%E8%BF%9C%E7%A8%8B%E8%AE%BF%E9%97%AE%E5%AE%B6%E9%87%8C%E7%9A%84wsl2/</link>
      <pubDate>Mon, 28 Aug 2023 22:45:01 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F%E8%BF%9C%E7%A8%8B%E8%AE%BF%E9%97%AE%E5%AE%B6%E9%87%8C%E7%9A%84wsl2/</guid>
      <description>&lt;h1 id=&#34;背景简介&#34;&gt;背景简介&lt;/h1&gt;
&lt;p&gt;WSL2 是 Windows 的子系统，可以在 Windows 上运行 Linux，但是 WSL2 是运行在虚拟机中的，所以无法直接访问 WSL2 中的服务，比如 SSH 服务。本文介绍如何使用内网穿透工具&lt;strong&gt;花生壳&lt;/strong&gt;来实现远程访问 WSL2 中的服务。&lt;/p&gt;
&lt;p&gt;实现这一需求需要完成两个功能。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;WSL2 中的服务是运行在虚拟机中的，如何将公网的访问转发到 WSL2 中。&lt;/li&gt;
&lt;li&gt;Windows 没有公网 IP，如何通过公网来访问。&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id=&#34;wsl2-端口转发&#34;&gt;WSL2 端口转发&lt;/h1&gt;
&lt;p&gt;获取 WSL2 的 IP 地址：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;hostname -I &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; awk &lt;span class=&#34;s1&#34;&gt;&amp;#39;{print $1}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;172.26.13.98
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Windows 自带的&lt;code&gt;netsh interface portproxy&lt;/code&gt;可以实现端口转发。管理员身份打开 cmd，执行以下命令：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;netsh interface portproxy add v4tov4 &lt;span class=&#34;nv&#34;&gt;listenaddress&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;0.0.0.0 &lt;span class=&#34;nv&#34;&gt;listenport&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2222&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;connectaddress&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;172.26.13.98 &lt;span class=&#34;nv&#34;&gt;connectport&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;22&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;listenport：公网访问的端口（改一个不冲突的就行）&lt;/li&gt;
&lt;li&gt;connectaddress：WSL2 的 IP 地址&lt;/li&gt;
&lt;li&gt;connectport：WSL2 中 SSH 服务的端口 (默认为 22，不需要更改)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;开启 Windows 防火墙入站规则，管理员身份打开 cmd，执行以下命令：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;netsh advfirewall firewall add rule &lt;span class=&#34;nv&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;WSL2 &lt;span class=&#34;nv&#34;&gt;dir&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;in &lt;span class=&#34;nv&#34;&gt;action&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;allow &lt;span class=&#34;nv&#34;&gt;protocol&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;TCP &lt;span class=&#34;nv&#34;&gt;localport&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2222&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个命令是用于在 Windows 高级防火墙中添加一条规则。下面是对每个参数的解释：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;name=WSL2&lt;/code&gt;：将规则命名为 &amp;ldquo;WSL2&amp;rdquo;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dir=in&lt;/code&gt;：指定规则适用于传入的网络流量。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;action=allow&lt;/code&gt;：允许通过该规则的流量通过防火墙。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;protocol=TCP&lt;/code&gt;：指定规则适用于 TCP 协议的流量。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;localport=2222&lt;/code&gt;：指定本地端口号为 2222。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;验证端口转发是否成功：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ssh -p &lt;span class=&#34;m&#34;&gt;2222&lt;/span&gt; user@localhost
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;user 修改成 WSL2 的用户名&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果配置成功，则会成功登录 WSL2。&lt;/p&gt;
&lt;h1 id=&#34;安装配置花生壳&#34;&gt;安装配置花生壳&lt;/h1&gt;
&lt;p&gt;进入官网&lt;a href=&#34;https://hsk.oray.com/download&#34;&gt;下载花生壳客户端&lt;/a&gt;，安装后打开，注册账号，登录。&lt;strong&gt;需要实名认证&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;免费账户可以绑定&lt;strong&gt;2 个映射&lt;/strong&gt;，对我来说暂时够用了，免费流量 1G/月。实测阅读代码不编译的话大概&lt;strong&gt;每天 50M&lt;/strong&gt;左右。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;打开客户端，添加映射，配置如下：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/08/28/3423c43e8d319abd89c11afd7be03a11.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/08/28/3423c43e8d319abd89c11afd7be03a11.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;保存即可。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/08/28/fddec1e9e0cc03c7208b4244dd35ad01.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/08/28/fddec1e9e0cc03c7208b4244dd35ad01.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;验证是否配置成功，找一台不在同一个局域网的电脑，使用 SSH 连接 WSL2：&lt;/p&gt;
&lt;p&gt;如果复制出来的访问地址为&lt;code&gt;abcdjsj.goho.co:33445&lt;/code&gt;，那么 SSH 命令修改为如下：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ssh -p &lt;span class=&#34;m&#34;&gt;33445&lt;/span&gt;  user@abcdjsj.goho.co
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;user 修改成 WSL2 的用户名&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果配置成功，则会成功登录 WSL2。&lt;/p&gt;
&lt;h1 id=&#34;题外话&#34;&gt;题外话&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;WSL2 的 &lt;strong&gt;IP 会经常变化&lt;/strong&gt;，如果连不上了，可以重新获取一下 IP，然后修改一下各个配置。或者想办法将 WSL2 的 IP 固定下来。&lt;/li&gt;
&lt;li&gt;带宽有限，登录时比较慢，耐心等待。后续准备使用 frp 自建一个穿透服务。&lt;/li&gt;
&lt;li&gt;PC 耗电伤不起啊，一百多瓦赶上三四台 NAS 了。这玩意只能应急，长时间挂机电费都够买个云服务器了。&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id=&#34;常见问题&#34;&gt;常见问题&lt;/h1&gt;
&lt;h2 id=&#34;system-is-booting-up-unprivileged-users-are-not-permitted-to-log-in-yet&#34;&gt;&amp;ldquo;System is booting up. Unprivileged users are not permitted to log in yet&amp;rdquo;&lt;/h2&gt;
&lt;p&gt;登录服务端，也就是 WSL2，执行以下命令&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo rm /run/nologin
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <content:encoded><![CDATA[<h1 id="背景简介">背景简介</h1>
<p>WSL2 是 Windows 的子系统，可以在 Windows 上运行 Linux，但是 WSL2 是运行在虚拟机中的，所以无法直接访问 WSL2 中的服务，比如 SSH 服务。本文介绍如何使用内网穿透工具<strong>花生壳</strong>来实现远程访问 WSL2 中的服务。</p>
<p>实现这一需求需要完成两个功能。</p>
<ol>
<li>WSL2 中的服务是运行在虚拟机中的，如何将公网的访问转发到 WSL2 中。</li>
<li>Windows 没有公网 IP，如何通过公网来访问。</li>
</ol>
<h1 id="wsl2-端口转发">WSL2 端口转发</h1>
<p>获取 WSL2 的 IP 地址：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hostname -I <span class="p">|</span> awk <span class="s1">&#39;{print $1}&#39;</span>
</span></span><span class="line"><span class="cl">172.26.13.98
</span></span></code></pre></div><p>Windows 自带的<code>netsh interface portproxy</code>可以实现端口转发。管理员身份打开 cmd，执行以下命令：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">netsh interface portproxy add v4tov4 <span class="nv">listenaddress</span><span class="o">=</span>0.0.0.0 <span class="nv">listenport</span><span class="o">=</span><span class="m">2222</span> <span class="nv">connectaddress</span><span class="o">=</span>172.26.13.98 <span class="nv">connectport</span><span class="o">=</span><span class="m">22</span>
</span></span></code></pre></div><ul>
<li>listenport：公网访问的端口（改一个不冲突的就行）</li>
<li>connectaddress：WSL2 的 IP 地址</li>
<li>connectport：WSL2 中 SSH 服务的端口 (默认为 22，不需要更改)</li>
</ul>
<p>开启 Windows 防火墙入站规则，管理员身份打开 cmd，执行以下命令：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">netsh advfirewall firewall add rule <span class="nv">name</span><span class="o">=</span>WSL2 <span class="nv">dir</span><span class="o">=</span>in <span class="nv">action</span><span class="o">=</span>allow <span class="nv">protocol</span><span class="o">=</span>TCP <span class="nv">localport</span><span class="o">=</span><span class="m">2222</span>
</span></span></code></pre></div><p>这个命令是用于在 Windows 高级防火墙中添加一条规则。下面是对每个参数的解释：</p>
<ul>
<li><code>name=WSL2</code>：将规则命名为 &ldquo;WSL2&rdquo;。</li>
<li><code>dir=in</code>：指定规则适用于传入的网络流量。</li>
<li><code>action=allow</code>：允许通过该规则的流量通过防火墙。</li>
<li><code>protocol=TCP</code>：指定规则适用于 TCP 协议的流量。</li>
<li><code>localport=2222</code>：指定本地端口号为 2222。</li>
</ul>
<p>验证端口转发是否成功：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ssh -p <span class="m">2222</span> user@localhost
</span></span></code></pre></div><ul>
<li>user 修改成 WSL2 的用户名</li>
</ul>
<p>如果配置成功，则会成功登录 WSL2。</p>
<h1 id="安装配置花生壳">安装配置花生壳</h1>
<p>进入官网<a href="https://hsk.oray.com/download">下载花生壳客户端</a>，安装后打开，注册账号，登录。<strong>需要实名认证</strong></p>
<blockquote>
<p>免费账户可以绑定<strong>2 个映射</strong>，对我来说暂时够用了，免费流量 1G/月。实测阅读代码不编译的话大概<strong>每天 50M</strong>左右。</p>
</blockquote>
<p>打开客户端，添加映射，配置如下：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/08/28/3423c43e8d319abd89c11afd7be03a11.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/08/28/3423c43e8d319abd89c11afd7be03a11.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>保存即可。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/08/28/fddec1e9e0cc03c7208b4244dd35ad01.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2023/08/28/fddec1e9e0cc03c7208b4244dd35ad01.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>验证是否配置成功，找一台不在同一个局域网的电脑，使用 SSH 连接 WSL2：</p>
<p>如果复制出来的访问地址为<code>abcdjsj.goho.co:33445</code>，那么 SSH 命令修改为如下：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ssh -p <span class="m">33445</span>  user@abcdjsj.goho.co
</span></span></code></pre></div><ul>
<li>user 修改成 WSL2 的用户名</li>
</ul>
<p>如果配置成功，则会成功登录 WSL2。</p>
<h1 id="题外话">题外话</h1>
<ol>
<li>WSL2 的 <strong>IP 会经常变化</strong>，如果连不上了，可以重新获取一下 IP，然后修改一下各个配置。或者想办法将 WSL2 的 IP 固定下来。</li>
<li>带宽有限，登录时比较慢，耐心等待。后续准备使用 frp 自建一个穿透服务。</li>
<li>PC 耗电伤不起啊，一百多瓦赶上三四台 NAS 了。这玩意只能应急，长时间挂机电费都够买个云服务器了。</li>
</ol>
<h1 id="常见问题">常见问题</h1>
<h2 id="system-is-booting-up-unprivileged-users-are-not-permitted-to-log-in-yet">&ldquo;System is booting up. Unprivileged users are not permitted to log in yet&rdquo;</h2>
<p>登录服务端，也就是 WSL2，执行以下命令</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo rm /run/nologin
</span></span></code></pre></div>]]></content:encoded>
    </item>
    <item>
      <title>如何使用 GitHub Actions</title>
      <link>https://lifeislife.cn/posts/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8github-actions/</link>
      <pubDate>Fri, 14 Oct 2022 22:08:54 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8github-actions/</guid>
      <description>&lt;h1 id=&#34;简介&#34;&gt;简介&lt;/h1&gt;
&lt;p&gt;GitHub Actions 是 GitHub 在 2018 年推出的&lt;a href=&#34;http://www.ruanyifeng.com/blog/2015/09/continuous-integration.html&#34;&gt;持续集成服务&lt;/a&gt;。它可以自动完成一些开发周期内的任务，如 Push 代码时自动编译，Pull 代码时自动执行测试脚本等等。&lt;/p&gt;
&lt;p&gt;我了解 GitHub Actions 的契机是，我在 GitHub 上保存了一些 Markdown 文档，我希望每次更新文档后自动使用 Pandoc 转换成 PDF 文档。接下来我们一起学习如何通过 GitHub Actions 实现这样的需求。&lt;/p&gt;
&lt;p&gt;首先我们先直观的了解一下它在 GitHub 的位置，如果打开一个仓库，它有图中绿色对号√，或者红色叉号×，说明这个项目配置了 GitHub Actions，绿色表示自动化的流程运行成功了，红色表示失败了。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/10/15/a3a273415c7250d26bb50e293378bf5e.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/10/15/a3a273415c7250d26bb50e293378bf5e.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;我们点开&lt;code&gt;Actions&lt;/code&gt;按钮就可以查看具体的任务详情。下面我们先学习如何配置一个简单的 GitHub Actions。&lt;/p&gt;
&lt;h1 id=&#34;配置-github-actions&#34;&gt;配置 GitHub Actions&lt;/h1&gt;
&lt;p&gt;GitHub Actions 可以简单理解为一些自动化脚本，工具，目的就是为了减少重复工作，所以这些工具都可以做成普适性的工具。而 GitHub 官方就开放了一个这类工具的&lt;a href=&#34;https://github.com/marketplace&#34;&gt;市场&lt;/a&gt;，我们可以在上面搜索自己想要的工具。因为初学 GitHub Actions 所以也不知道怎么写配置文件，我们可以直接搜索一个并应用它，看看别人是怎么写的。&lt;/p&gt;
&lt;p&gt;我们进入一个自己的仓库，点击&lt;code&gt;Actions&lt;/code&gt;，搜索框中搜索&lt;code&gt;PDF&lt;/code&gt;，在搜索结果中找到&lt;a href=&#34;https://github.com/marketplace/actions/create-pdf&#34;&gt;Create PDF · Actions&lt;/a&gt;这个工具。如果搜索到点击&lt;code&gt;Configure&lt;/code&gt;。如果显示未找到，则点击&lt;code&gt;set up a workflow yourself&lt;/code&gt;，同样搜索&lt;code&gt;PDF&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/10/15/f6baead7ab50e1db5ce3611a0525f833.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/10/15/f6baead7ab50e1db5ce3611a0525f833.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;打开&lt;a href=&#34;https://github.com/marketplace/actions/create-pdf&#34;&gt;详情页面&lt;/a&gt;，拉到底，将&lt;code&gt;Example usage&lt;/code&gt;。里的内容复制到编辑框中。点击右上角&lt;code&gt;Start commit&lt;/code&gt;将会把我们新建的&lt;code&gt;main.yml&lt;/code&gt;提交到仓库中。这就相当于创建了一个生成 PDF 的 GitHub Actions。当然每个 Actions 都有一些使用要求，比如这里还要根据介绍，创建几个文件夹，比如从哪个文件夹获取源文件，生成后的 PDF 又会放到哪个文件夹等。这里就不再介绍，我们先了解如何创建一个 Actions。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/10/16/0a24d8bcecc9d210b4e6b75b2fccae0b.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/10/16/0a24d8bcecc9d210b4e6b75b2fccae0b.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/10/16/69370e917f9c35963a2343176ecf0eea.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/10/16/69370e917f9c35963a2343176ecf0eea.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h1 id=&#34;workflow-配置&#34;&gt;Workflow 配置&lt;/h1&gt;
&lt;p&gt;GitHub Actions 的配置文件叫做 workflow 文件，存放在代码仓库的.github/workflows 目录。&lt;/p&gt;
&lt;p&gt;workflow 文件采用 YAML 格式，文件名可以任意取，但是后缀名统一为.yml or .yaml，比如 foo.yml or foo.yaml。一个库可以有多个 workflow 文件。GitHub 只要发现.github/workflows 目录里面有.yml or .yaml 文件，就会自动运行该文件（并行）。&lt;/p&gt;
&lt;p&gt;接下来我们逐个参数来解释都有哪些功能。&lt;/p&gt;
&lt;h2 id=&#34;on&#34;&gt;on&lt;/h2&gt;
&lt;p&gt;触发 workflow 的 GitHub 事件的名称。比如&lt;code&gt;push&lt;/code&gt;代码时触发，其他人&lt;code&gt;fork&lt;/code&gt;代码仓时触发等等。&lt;/p&gt;
&lt;p&gt;可以只有一个事件触发，&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;push&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;也可有多个事件触发，使用列表列举，&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;l&#34;&gt;push, fork]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;所有支持的事件列表，请查看&lt;a href=&#34;https://docs.github.com/cn/actions/using-workflows/events-that-trigger-workflows&#34;&gt;官方文档&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&#34;onpushforktagsbranches&#34;&gt;on.[push|fork].[tags|branches]&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：从这里开始就会出现一个字段下有子字段，每个点号&lt;code&gt;.&lt;/code&gt;分割一个子字段。如&lt;code&gt;push&lt;/code&gt;或者&lt;code&gt;fork&lt;/code&gt;可以作为&lt;code&gt;on&lt;/code&gt;的子字段，&lt;code&gt;tags&lt;/code&gt;或者&lt;code&gt;branches&lt;/code&gt;可以作为&lt;code&gt;push&lt;/code&gt;或者&lt;code&gt;fork&lt;/code&gt;的子字段。在&lt;code&gt;yaml&lt;/code&gt;文件中，缩进很重要，每个缩进都表示是从属关系，表示是该字段的子字段。千万要注意缩进关系，如果缩进出错，那么将无法解析&lt;code&gt;yaml&lt;/code&gt;文件。&lt;/p&gt;
&lt;p&gt;指定触发事件时，可以限定分支或标签。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;push&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;branches&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;master&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上面代码指定，只有 master 分支发生 push 事件时，才会触发 workflow。&lt;/p&gt;
&lt;h2 id=&#34;name&#34;&gt;name&lt;/h2&gt;
&lt;p&gt;工作流程的名称。GitHub 在仓库的操作页面上显示工作流程的名称。如果省略 name，GitHub 将其设置为相对于仓库根目录的工作流程文件路径。&lt;/p&gt;
&lt;h2 id=&#34;jobs&#34;&gt;jobs&lt;/h2&gt;
&lt;p&gt;workflow 运行包括一项或多项 jobs。jobs 默认是并行运行。要按顺序运行作业，可以使用 &lt;code&gt;[job_id].needs&lt;/code&gt; 关键词在其他 job 上定义依赖项。&lt;/p&gt;
&lt;p&gt;每个作业在 &lt;code&gt;runs-on&lt;/code&gt; 指定的运行器环境中运行。&lt;/p&gt;
&lt;h3 id=&#34;jobsjob_id&#34;&gt;jobs.[job_id]&lt;/h3&gt;
&lt;p&gt;jobs 中的每个任务都有一个&lt;code&gt;[job_id]&lt;/code&gt; ，且其必须为 jobs 对象中&lt;strong&gt;唯一的字符串键值&lt;/strong&gt;。&lt;code&gt;[job_id]&lt;/code&gt;必须以字母或&lt;code&gt;_&lt;/code&gt;开头，并且只能包含字母数字字符、&lt;code&gt;-&lt;/code&gt;或&lt;code&gt;_&lt;/code&gt;。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;jobs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;first_job&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# [job_id]，任务 id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;My first job&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;second_job&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;My second job&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;jobsjob_idruns-on&#34;&gt;jobs.[job_id].[runs-on]&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;runs-on&lt;/code&gt; 字段指定运行所需要的虚拟机环境。它是必填字段。目前可用的虚拟机如下。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- &lt;span class=&#34;l&#34;&gt;ubuntu-latest，ubuntu-18.04或ubuntu-16.04&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- &lt;span class=&#34;l&#34;&gt;windows-latest，windows-2019或windows-2016&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- &lt;span class=&#34;l&#34;&gt;macOS-latest或macOS-10.14&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;下面代码指定虚拟机环境为 ubuntu-18.04。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;runs-on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ubuntu-18.04&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;jobsjob_idname&#34;&gt;jobs.[job_id].name&lt;/h3&gt;
&lt;p&gt;workflow 文件的主体是 jobs 字段，表示要执行的一项或多项任务。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;job_id&lt;/code&gt; 里面的 &lt;code&gt;name&lt;/code&gt; 字段是任务的说明。它可以在网页端的 UI 上显示。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;jobs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;first_job&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;My first job &lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# [job_name]，任务名称&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;second_job&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;My second job&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;jobsjob_idneeds&#34;&gt;jobs.[job_id].needs&lt;/h3&gt;
&lt;p&gt;needs 字段指定当前任务的依赖关系，即运行顺序。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;jobs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;job1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;job2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;needs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;job1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;job3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;needs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;l&#34;&gt;job1, job2]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上面代码中，job1 必须先于 job2 完成，而 job3 等待 job1 和 job2 的完成才能运行。因此，这个 workflow 的运行顺序依次为：job1、job2、job3。&lt;/p&gt;
&lt;h3 id=&#34;jobsjob_idsteps&#34;&gt;jobs.[job_id].steps&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;steps&lt;/code&gt; 字段指定每个 Job 的运行步骤，可以包含一个或多个步骤。每个步骤都可以指定以下三个字段。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- &lt;span class=&#34;l&#34;&gt;jobs.[job_id].steps.name：步骤名称。&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- &lt;span class=&#34;l&#34;&gt;jobs.[job_id].steps.run：该步骤运行的命令或者 action。&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- &lt;span class=&#34;l&#34;&gt;jobs.[job_id].steps.env：该步骤所需的环境变量。&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;下面是一个完整的 workflow 文件的范例。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Greeting from Mona&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;push&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;jobs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;my-job&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;My Job&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;runs-on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ubuntu-latest&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;steps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Print a greeting&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;env&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;MY_VAR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Hi there! My name is&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;FIRST_NAME&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Mona&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;MIDDLE_NAME&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;The&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;LAST_NAME&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Octocat&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;          echo $MY_VAR $FIRST_NAME $MIDDLE_NAME $LAST_NAME.&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上面代码中，steps 字段只包括一个步骤。该步骤先注入四个环境变量，然后执行一条 Bash 命令。&lt;/p&gt;
&lt;h3 id=&#34;jobsjob_idstepsuses&#34;&gt;jobs.[job_id].steps[*].uses&lt;/h3&gt;
&lt;p&gt;选择一个 action，可以理解为若干 steps.run，有利于代码复用。这也是 github action 最主要的功能。&lt;/p&gt;
&lt;p&gt;比如最常用的，下载本仓库的代码到工作区，就是使用的一个 action 完成的：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;steps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Check out Git repository&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;actions/checkout@v2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;注：&lt;code&gt;@v2&lt;/code&gt; 什么意思？
表示 Action 的版本。我们如果不带版本号的话，就是默认使用最新版本。Github 官方强烈要求我们带上版本号。这样子的话，我们就不会出现：写好一个 Workflow，但是由于某个 Action 的作者一更新，我们的 Workflow 就崩了的问题&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;jobsjob_idstepsrun&#34;&gt;jobs.[job_id].steps.run&lt;/h3&gt;
&lt;p&gt;在 shell 中执行的命令：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;steps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;actions/checkout@v2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;create dir&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;dir&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;            mkdir output  # create output dir&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;以上配置是在下载完本仓库的代码后，在仓库根目录新建一个&lt;code&gt;output&lt;/code&gt;文件夹。注意&lt;code&gt;run:&lt;/code&gt;后的&lt;code&gt;|&lt;/code&gt;表示可以多行命令。如果没有&lt;code&gt;|&lt;/code&gt;表示只能执行一条命令。&lt;/p&gt;
&lt;h3 id=&#34;jobsjob_idstepsworking-directory&#34;&gt;jobs.[job_id].steps.working-directory&lt;/h3&gt;
&lt;p&gt;用来指定在&lt;code&gt;run&lt;/code&gt;命令在哪执行。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Create dir&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;mkdir output&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;working-directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;./build&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;jobsjob_idstepsshell&#34;&gt;jobs.[job_id].steps.shell&lt;/h3&gt;
&lt;p&gt;用来指定 shell 类型，如 Python，bash，powershell 等。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;steps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Display the path&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;echo $PATH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;shell&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;bash&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;所有支持的类型请查看&lt;a href=&#34;https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsshell&#34;&gt;官方文档&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&#34;如何跳过-github-actions&#34;&gt;如何跳过 GitHub Actions&lt;/h3&gt;
&lt;p&gt;在 commit message 中只要包含了下面几个关键词就会跳过 Github Actions。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;l&#34;&gt;skip ci]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ci skip]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;no&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ci]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;l&#34;&gt;skip actions]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;l&#34;&gt;actions skip]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;实例自动使用-pandoc-将-markdown-文件转换为-pdf&#34;&gt;实例：自动使用 Pandoc 将 Markdown 文件转换为 PDF&lt;/h1&gt;
&lt;p&gt;以&lt;a href=&#34;https://github.com/Dunky-Z/uefi-spec-zh&#34;&gt;Dunky-Z/uefi-spec-zh&lt;/a&gt;项目中使用的 GitHub Actions 为例，解释如何实现将 Markdown 文件转换为 PDF。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# CI 名为 MPPL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;MPPL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# 在 Push 代码时触发 CI&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;push&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;jobs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 任务名称为 convert_via_pandoc&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;convert_via_pandoc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 在 ubuntu-latest 系统上运行&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;runs-on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ubuntu-latest&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;steps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 步骤一：下载最新代码&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;actions/checkout@v2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 步骤二：在项目根目录建立 output 文件夹放生成的 PDF 文件&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;create file list&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;files_list&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;          mkdir output  # create output dir&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 步骤三：更新项目的子模块&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Git Sumbodule Update&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;          git submodule update --init --remote --recursive&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 步骤四：为运行的系统中安装需要的字体，因为原系统没有需要的中文字体&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 字体来源为项目目录的MPPL/fonts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;add fonts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;          sudo apt-get install ttf-mscorefonts-installer
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;          sudo apt-get install fontconfig
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;          fc-list :lang=zh
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;          ls -lh /usr/share/fonts/
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;          cp -rf ./MPPL/fonts/* /usr/share/fonts/
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;          mkfontscale
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;          mkfontdir
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;          fc-cache
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;          fc-list&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 步骤五：安装 pandoc 和 texlive&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;install pandoc&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;          sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;          sudo apt-get install texlive-full
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;          sudo apt-get install pandoc
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;          sudo apt-get clean&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 步骤六：使用 pandoc 命令生成 pdf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;build pdf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;          cd src
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;          pandoc -f  markdown-auto_identifiers  --listings --pdf-engine=xelatex --template=../MPPL/templates/mppl.tex  --output=../output/UEFI规范-中文.pdf *.md&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 步骤七：将生成的结果上传到 GitHub&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;actions/upload-artifact@master&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;output&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;output&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;注意事项&#34;&gt;注意事项&lt;/h1&gt;
&lt;p&gt;every step must define a &lt;code&gt;uses&lt;/code&gt; or &lt;code&gt;run&lt;/code&gt; key
&lt;a href=&#34;https://github.com/einaregilsson/beanstalk-deploy/issues/2&#34;&gt;every step must define a uses or run key · Issue #2 · einaregilsson/beanstalk-deploy&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&#34;参考&#34;&gt;参考&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/fhem/mod-Buienradar/issues/318&#34;&gt;GH actions: a step cannot have both the &lt;/a&gt;&lt;a href=&#34;https://github.com/fhem/mod-Buienradar/issues/318&#34;&gt;&lt;code&gt;uses&lt;/code&gt;&lt;/a&gt;&lt;a href=&#34;https://github.com/fhem/mod-Buienradar/issues/318&#34;&gt; and &lt;/a&gt;&lt;a href=&#34;https://github.com/fhem/mod-Buienradar/issues/318&#34;&gt;&lt;code&gt;run&lt;/code&gt;&lt;/a&gt;&lt;a href=&#34;https://github.com/fhem/mod-Buienradar/issues/318&#34;&gt; keys · Issue #318 · fhem/mod-Buienradar&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/einaregilsson/beanstalk-deploy/issues/2&#34;&gt;every step must define a uses or run key · Issue #2 · einaregilsson/beanstalk-deploy&lt;/a&gt;&lt;/p&gt;
</description>
      <content:encoded><![CDATA[<h1 id="简介">简介</h1>
<p>GitHub Actions 是 GitHub 在 2018 年推出的<a href="http://www.ruanyifeng.com/blog/2015/09/continuous-integration.html">持续集成服务</a>。它可以自动完成一些开发周期内的任务，如 Push 代码时自动编译，Pull 代码时自动执行测试脚本等等。</p>
<p>我了解 GitHub Actions 的契机是，我在 GitHub 上保存了一些 Markdown 文档，我希望每次更新文档后自动使用 Pandoc 转换成 PDF 文档。接下来我们一起学习如何通过 GitHub Actions 实现这样的需求。</p>
<p>首先我们先直观的了解一下它在 GitHub 的位置，如果打开一个仓库，它有图中绿色对号√，或者红色叉号×，说明这个项目配置了 GitHub Actions，绿色表示自动化的流程运行成功了，红色表示失败了。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/10/15/a3a273415c7250d26bb50e293378bf5e.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/10/15/a3a273415c7250d26bb50e293378bf5e.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>我们点开<code>Actions</code>按钮就可以查看具体的任务详情。下面我们先学习如何配置一个简单的 GitHub Actions。</p>
<h1 id="配置-github-actions">配置 GitHub Actions</h1>
<p>GitHub Actions 可以简单理解为一些自动化脚本，工具，目的就是为了减少重复工作，所以这些工具都可以做成普适性的工具。而 GitHub 官方就开放了一个这类工具的<a href="https://github.com/marketplace">市场</a>，我们可以在上面搜索自己想要的工具。因为初学 GitHub Actions 所以也不知道怎么写配置文件，我们可以直接搜索一个并应用它，看看别人是怎么写的。</p>
<p>我们进入一个自己的仓库，点击<code>Actions</code>，搜索框中搜索<code>PDF</code>，在搜索结果中找到<a href="https://github.com/marketplace/actions/create-pdf">Create PDF · Actions</a>这个工具。如果搜索到点击<code>Configure</code>。如果显示未找到，则点击<code>set up a workflow yourself</code>，同样搜索<code>PDF</code>。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/10/15/f6baead7ab50e1db5ce3611a0525f833.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/10/15/f6baead7ab50e1db5ce3611a0525f833.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>打开<a href="https://github.com/marketplace/actions/create-pdf">详情页面</a>，拉到底，将<code>Example usage</code>。里的内容复制到编辑框中。点击右上角<code>Start commit</code>将会把我们新建的<code>main.yml</code>提交到仓库中。这就相当于创建了一个生成 PDF 的 GitHub Actions。当然每个 Actions 都有一些使用要求，比如这里还要根据介绍，创建几个文件夹，比如从哪个文件夹获取源文件，生成后的 PDF 又会放到哪个文件夹等。这里就不再介绍，我们先了解如何创建一个 Actions。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/10/16/0a24d8bcecc9d210b4e6b75b2fccae0b.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/10/16/0a24d8bcecc9d210b4e6b75b2fccae0b.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/10/16/69370e917f9c35963a2343176ecf0eea.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/10/16/69370e917f9c35963a2343176ecf0eea.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h1 id="workflow-配置">Workflow 配置</h1>
<p>GitHub Actions 的配置文件叫做 workflow 文件，存放在代码仓库的.github/workflows 目录。</p>
<p>workflow 文件采用 YAML 格式，文件名可以任意取，但是后缀名统一为.yml or .yaml，比如 foo.yml or foo.yaml。一个库可以有多个 workflow 文件。GitHub 只要发现.github/workflows 目录里面有.yml or .yaml 文件，就会自动运行该文件（并行）。</p>
<p>接下来我们逐个参数来解释都有哪些功能。</p>
<h2 id="on">on</h2>
<p>触发 workflow 的 GitHub 事件的名称。比如<code>push</code>代码时触发，其他人<code>fork</code>代码仓时触发等等。</p>
<p>可以只有一个事件触发，</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">on</span><span class="p">:</span><span class="w"> </span><span class="l">push</span><span class="w">
</span></span></span></code></pre></div><p>也可有多个事件触发，使用列表列举，</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">on</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">push, fork]</span><span class="w">
</span></span></span></code></pre></div><p>所有支持的事件列表，请查看<a href="https://docs.github.com/cn/actions/using-workflows/events-that-trigger-workflows">官方文档</a>。</p>
<h3 id="onpushforktagsbranches">on.[push|fork].[tags|branches]</h3>
<p><strong>注意</strong>：从这里开始就会出现一个字段下有子字段，每个点号<code>.</code>分割一个子字段。如<code>push</code>或者<code>fork</code>可以作为<code>on</code>的子字段，<code>tags</code>或者<code>branches</code>可以作为<code>push</code>或者<code>fork</code>的子字段。在<code>yaml</code>文件中，缩进很重要，每个缩进都表示是从属关系，表示是该字段的子字段。千万要注意缩进关系，如果缩进出错，那么将无法解析<code>yaml</code>文件。</p>
<p>指定触发事件时，可以限定分支或标签。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">on</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">push</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">branches</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">master</span><span class="w">
</span></span></span></code></pre></div><p>上面代码指定，只有 master 分支发生 push 事件时，才会触发 workflow。</p>
<h2 id="name">name</h2>
<p>工作流程的名称。GitHub 在仓库的操作页面上显示工作流程的名称。如果省略 name，GitHub 将其设置为相对于仓库根目录的工作流程文件路径。</p>
<h2 id="jobs">jobs</h2>
<p>workflow 运行包括一项或多项 jobs。jobs 默认是并行运行。要按顺序运行作业，可以使用 <code>[job_id].needs</code> 关键词在其他 job 上定义依赖项。</p>
<p>每个作业在 <code>runs-on</code> 指定的运行器环境中运行。</p>
<h3 id="jobsjob_id">jobs.[job_id]</h3>
<p>jobs 中的每个任务都有一个<code>[job_id]</code> ，且其必须为 jobs 对象中<strong>唯一的字符串键值</strong>。<code>[job_id]</code>必须以字母或<code>_</code>开头，并且只能包含字母数字字符、<code>-</code>或<code>_</code>。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">jobs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">first_job</span><span class="p">:</span><span class="w">  </span><span class="c"># [job_id]，任务 id</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">My first job</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">second_job</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">My second job</span><span class="w">
</span></span></span></code></pre></div><h3 id="jobsjob_idruns-on">jobs.[job_id].[runs-on]</h3>
<p><code>runs-on</code> 字段指定运行所需要的虚拟机环境。它是必填字段。目前可用的虚拟机如下。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl">- <span class="l">ubuntu-latest，ubuntu-18.04或ubuntu-16.04</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="l">windows-latest，windows-2019或windows-2016</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="l">macOS-latest或macOS-10.14</span><span class="w">
</span></span></span></code></pre></div><p>下面代码指定虚拟机环境为 ubuntu-18.04。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">ubuntu-18.04</span><span class="w">
</span></span></span></code></pre></div><h3 id="jobsjob_idname">jobs.[job_id].name</h3>
<p>workflow 文件的主体是 jobs 字段，表示要执行的一项或多项任务。</p>
<p><code>job_id</code> 里面的 <code>name</code> 字段是任务的说明。它可以在网页端的 UI 上显示。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">jobs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">first_job</span><span class="p">:</span><span class="w">  
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">My first job </span><span class="w"> </span><span class="c"># [job_name]，任务名称</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">second_job</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">My second job</span><span class="w">
</span></span></span></code></pre></div><h3 id="jobsjob_idneeds">jobs.[job_id].needs</h3>
<p>needs 字段指定当前任务的依赖关系，即运行顺序。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">jobs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">job1</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">job2</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">needs</span><span class="p">:</span><span class="w"> </span><span class="l">job1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">job3</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">needs</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">job1, job2]</span><span class="w">
</span></span></span></code></pre></div><p>上面代码中，job1 必须先于 job2 完成，而 job3 等待 job1 和 job2 的完成才能运行。因此，这个 workflow 的运行顺序依次为：job1、job2、job3。</p>
<h3 id="jobsjob_idsteps">jobs.[job_id].steps</h3>
<p><code>steps</code> 字段指定每个 Job 的运行步骤，可以包含一个或多个步骤。每个步骤都可以指定以下三个字段。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl">- <span class="l">jobs.[job_id].steps.name：步骤名称。</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="l">jobs.[job_id].steps.run：该步骤运行的命令或者 action。</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="l">jobs.[job_id].steps.env：该步骤所需的环境变量。</span><span class="w">
</span></span></span></code></pre></div><p>下面是一个完整的 workflow 文件的范例。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Greeting from Mona</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">on</span><span class="p">:</span><span class="w"> </span><span class="l">push</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">jobs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">my-job</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">My Job</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">ubuntu-latest</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Print a greeting</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">env</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">MY_VAR</span><span class="p">:</span><span class="w"> </span><span class="l">Hi there! My name is</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">FIRST_NAME</span><span class="p">:</span><span class="w"> </span><span class="l">Mona</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">MIDDLE_NAME</span><span class="p">:</span><span class="w"> </span><span class="l">The</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">LAST_NAME</span><span class="p">:</span><span class="w"> </span><span class="l">Octocat</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">          echo $MY_VAR $FIRST_NAME $MIDDLE_NAME $LAST_NAME.</span><span class="w">
</span></span></span></code></pre></div><p>上面代码中，steps 字段只包括一个步骤。该步骤先注入四个环境变量，然后执行一条 Bash 命令。</p>
<h3 id="jobsjob_idstepsuses">jobs.[job_id].steps[*].uses</h3>
<p>选择一个 action，可以理解为若干 steps.run，有利于代码复用。这也是 github action 最主要的功能。</p>
<p>比如最常用的，下载本仓库的代码到工作区，就是使用的一个 action 完成的：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Check out Git repository</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/checkout@v2</span><span class="w">
</span></span></span></code></pre></div><blockquote>
<p>注：<code>@v2</code> 什么意思？
表示 Action 的版本。我们如果不带版本号的话，就是默认使用最新版本。Github 官方强烈要求我们带上版本号。这样子的话，我们就不会出现：写好一个 Workflow，但是由于某个 Action 的作者一更新，我们的 Workflow 就崩了的问题</p>
</blockquote>
<h3 id="jobsjob_idstepsrun">jobs.[job_id].steps.run</h3>
<p>在 shell 中执行的命令：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/checkout@v2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">create dir</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l">dir</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">            mkdir output  # create output dir</span><span class="w">
</span></span></span></code></pre></div><p>以上配置是在下载完本仓库的代码后，在仓库根目录新建一个<code>output</code>文件夹。注意<code>run:</code>后的<code>|</code>表示可以多行命令。如果没有<code>|</code>表示只能执行一条命令。</p>
<h3 id="jobsjob_idstepsworking-directory">jobs.[job_id].steps.working-directory</h3>
<p>用来指定在<code>run</code>命令在哪执行。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl">- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Create dir</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="l">mkdir output</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">working-directory</span><span class="p">:</span><span class="w"> </span><span class="l">./build</span><span class="w">
</span></span></span></code></pre></div><h3 id="jobsjob_idstepsshell">jobs.[job_id].steps.shell</h3>
<p>用来指定 shell 类型，如 Python，bash，powershell 等。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Display the path</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="l">echo $PATH</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">shell</span><span class="p">:</span><span class="w"> </span><span class="l">bash</span><span class="w">
</span></span></span></code></pre></div><p>所有支持的类型请查看<a href="https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsshell">官方文档</a>。</p>
<h3 id="如何跳过-github-actions">如何跳过 GitHub Actions</h3>
<p>在 commit message 中只要包含了下面几个关键词就会跳过 Github Actions。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="p">[</span><span class="l">skip ci]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">[</span><span class="l">ci skip]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">[</span><span class="kc">no</span><span class="w"> </span><span class="l">ci]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">[</span><span class="l">skip actions]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">[</span><span class="l">actions skip]</span><span class="w">
</span></span></span></code></pre></div><h1 id="实例自动使用-pandoc-将-markdown-文件转换为-pdf">实例：自动使用 Pandoc 将 Markdown 文件转换为 PDF</h1>
<p>以<a href="https://github.com/Dunky-Z/uefi-spec-zh">Dunky-Z/uefi-spec-zh</a>项目中使用的 GitHub Actions 为例，解释如何实现将 Markdown 文件转换为 PDF。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># CI 名为 MPPL</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">MPPL</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># 在 Push 代码时触发 CI</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">on</span><span class="p">:</span><span class="w"> </span><span class="l">push</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">jobs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c"># 任务名称为 convert_via_pandoc</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">convert_via_pandoc</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># 在 ubuntu-latest 系统上运行</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">ubuntu-latest</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># 步骤一：下载最新代码</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/checkout@v2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># 步骤二：在项目根目录建立 output 文件夹放生成的 PDF 文件</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">create file list</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l">files_list</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">          mkdir output  # create output dir</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># 步骤三：更新项目的子模块</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Git Sumbodule Update</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">          git submodule update --init --remote --recursive</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># 步骤四：为运行的系统中安装需要的字体，因为原系统没有需要的中文字体</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># 字体来源为项目目录的MPPL/fonts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">add fonts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">          sudo apt-get install ttf-mscorefonts-installer
</span></span></span><span class="line"><span class="cl"><span class="sd">          sudo apt-get install fontconfig
</span></span></span><span class="line"><span class="cl"><span class="sd">          fc-list :lang=zh
</span></span></span><span class="line"><span class="cl"><span class="sd">          ls -lh /usr/share/fonts/
</span></span></span><span class="line"><span class="cl"><span class="sd">          cp -rf ./MPPL/fonts/* /usr/share/fonts/
</span></span></span><span class="line"><span class="cl"><span class="sd">          mkfontscale
</span></span></span><span class="line"><span class="cl"><span class="sd">          mkfontdir
</span></span></span><span class="line"><span class="cl"><span class="sd">          fc-cache
</span></span></span><span class="line"><span class="cl"><span class="sd">          fc-list</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># 步骤五：安装 pandoc 和 texlive</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">install pandoc</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">          sudo apt-get update
</span></span></span><span class="line"><span class="cl"><span class="sd">          sudo apt-get install texlive-full
</span></span></span><span class="line"><span class="cl"><span class="sd">          sudo apt-get install pandoc
</span></span></span><span class="line"><span class="cl"><span class="sd">          sudo apt-get clean</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># 步骤六：使用 pandoc 命令生成 pdf</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">build pdf</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">          cd src
</span></span></span><span class="line"><span class="cl"><span class="sd">          pandoc -f  markdown-auto_identifiers  --listings --pdf-engine=xelatex --template=../MPPL/templates/mppl.tex  --output=../output/UEFI规范-中文.pdf *.md</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># 步骤七：将生成的结果上传到 GitHub</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/upload-artifact@master</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">output</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">output</span><span class="w">
</span></span></span></code></pre></div><h1 id="注意事项">注意事项</h1>
<p>every step must define a <code>uses</code> or <code>run</code> key
<a href="https://github.com/einaregilsson/beanstalk-deploy/issues/2">every step must define a uses or run key · Issue #2 · einaregilsson/beanstalk-deploy</a></p>
<h1 id="参考">参考</h1>
<p><a href="https://github.com/fhem/mod-Buienradar/issues/318">GH actions: a step cannot have both the </a><a href="https://github.com/fhem/mod-Buienradar/issues/318"><code>uses</code></a><a href="https://github.com/fhem/mod-Buienradar/issues/318"> and </a><a href="https://github.com/fhem/mod-Buienradar/issues/318"><code>run</code></a><a href="https://github.com/fhem/mod-Buienradar/issues/318"> keys · Issue #318 · fhem/mod-Buienradar</a></p>
<p><a href="https://github.com/einaregilsson/beanstalk-deploy/issues/2">every step must define a uses or run key · Issue #2 · einaregilsson/beanstalk-deploy</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>Markdown 表格竖线自动对齐</title>
      <link>https://lifeislife.cn/posts/markdown%E8%A1%A8%E6%A0%BC%E7%AB%96%E7%BA%BF%E8%87%AA%E5%8A%A8%E5%AF%B9%E9%BD%90/</link>
      <pubDate>Sat, 24 Sep 2022 15:01:41 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/markdown%E8%A1%A8%E6%A0%BC%E7%AB%96%E7%BA%BF%E8%87%AA%E5%8A%A8%E5%AF%B9%E9%BD%90/</guid>
      <description>&lt;h2 id=&#34;需求背景&#34;&gt;需求背景&lt;/h2&gt;
&lt;p&gt;Markdown 中的表格，只要符合语法就能够正常渲染显示，但是符合语法但是 Markdown 源码却不一定易读。就如以下的这个表格，可以正常显示，但是源码在源文件中竖线不对齐，就阅读困难。&lt;/p&gt;
&lt;p&gt;源码：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;|诗名|作者|朝代|
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;|-|-|-|
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;|白头吟|卓文君|两汉|
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;|锦瑟|李商隐|唐代|
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;|登科后|孟郊|唐代|
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;显示效果：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;诗名&lt;/th&gt;
          &lt;th&gt;作者&lt;/th&gt;
          &lt;th&gt;朝代&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;白头吟&lt;/td&gt;
          &lt;td&gt;卓文君&lt;/td&gt;
          &lt;td&gt;两汉&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;锦瑟&lt;/td&gt;
          &lt;td&gt;李商隐&lt;/td&gt;
          &lt;td&gt;唐代&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;登科后&lt;/td&gt;
          &lt;td&gt;孟郊&lt;/td&gt;
          &lt;td&gt;唐代&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;我们可以手动将其竖线对齐，如下这样就易读许多：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;| 诗名   | 作者   | 朝代 |
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;| ------ | ------ | ---- |
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;| 白头吟 | 卓文君 | 两汉 |
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;| 锦瑟   | 李商隐 | 唐代 |
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;| 登科后 | 孟郊   | 唐代 |
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;显示效果保持一致。但是如果一个字符一个字符去手动对齐效率太低，也不符合 Markdown 设计初衷。这就用到了额外的插件，能够辅助我们完成这个工作。&lt;/p&gt;
&lt;h2 id=&#34;markdown-all-in-one&#34;&gt;Markdown All in One&lt;/h2&gt;
&lt;p&gt;VSCode 插件中心搜索&lt;code&gt;Markdown All in One&lt;/code&gt;安装。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/24/fe35a13933da93bba8f234be209bb212.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/24/fe35a13933da93bba8f234be209bb212.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;安装完成后，使用时右击窗口选择&lt;code&gt;Format Document with&lt;/code&gt;：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/24/285b770adf0f3b3faff57ee14caca45b.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/24/285b770adf0f3b3faff57ee14caca45b.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;选择&lt;code&gt;Markdown All in One&lt;/code&gt;即可自动对齐所有表格竖线：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/24/313d3b85a4e98be59acc85fc7337d30f.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/24/313d3b85a4e98be59acc85fc7337d30f.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h2 id=&#34;常见问题&#34;&gt;常见问题&lt;/h2&gt;
&lt;h3 id=&#34;格式化文档后仍未对齐&#34;&gt;格式化文档后仍未对齐&lt;/h3&gt;
&lt;p&gt;这是由于表格中同时有中英文，而中英文字体不等宽导致的。如果对阅读要求不高，可以不用管，实际上已经格式化完成了。如果需要对齐，那么可以查看&lt;a href=&#34;http://lifeislife.cn/2022/08/27/%E7%BC%96%E7%A0%81%E5%AD%97%E4%BD%93%E4%B8%8E%E9%98%85%E8%AF%BB%E5%AD%97%E4%BD%93%E6%8E%A8%E8%8D%90/&#34;&gt;编码字体与阅读字体推荐&lt;/a&gt;这篇文章的&lt;strong&gt;中文等宽字体&lt;/strong&gt;下载并安装，即可正常对齐。&lt;/p&gt;
</description>
      <content:encoded><![CDATA[<h2 id="需求背景">需求背景</h2>
<p>Markdown 中的表格，只要符合语法就能够正常渲染显示，但是符合语法但是 Markdown 源码却不一定易读。就如以下的这个表格，可以正常显示，但是源码在源文件中竖线不对齐，就阅读困难。</p>
<p>源码：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">|诗名|作者|朝代|
</span></span><span class="line"><span class="cl">|-|-|-|
</span></span><span class="line"><span class="cl">|白头吟|卓文君|两汉|
</span></span><span class="line"><span class="cl">|锦瑟|李商隐|唐代|
</span></span><span class="line"><span class="cl">|登科后|孟郊|唐代|
</span></span></code></pre></div><p>显示效果：</p>
<table>
  <thead>
      <tr>
          <th>诗名</th>
          <th>作者</th>
          <th>朝代</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>白头吟</td>
          <td>卓文君</td>
          <td>两汉</td>
      </tr>
      <tr>
          <td>锦瑟</td>
          <td>李商隐</td>
          <td>唐代</td>
      </tr>
      <tr>
          <td>登科后</td>
          <td>孟郊</td>
          <td>唐代</td>
      </tr>
  </tbody>
</table>
<p>我们可以手动将其竖线对齐，如下这样就易读许多：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">| 诗名   | 作者   | 朝代 |
</span></span><span class="line"><span class="cl">| ------ | ------ | ---- |
</span></span><span class="line"><span class="cl">| 白头吟 | 卓文君 | 两汉 |
</span></span><span class="line"><span class="cl">| 锦瑟   | 李商隐 | 唐代 |
</span></span><span class="line"><span class="cl">| 登科后 | 孟郊   | 唐代 |
</span></span></code></pre></div><p>显示效果保持一致。但是如果一个字符一个字符去手动对齐效率太低，也不符合 Markdown 设计初衷。这就用到了额外的插件，能够辅助我们完成这个工作。</p>
<h2 id="markdown-all-in-one">Markdown All in One</h2>
<p>VSCode 插件中心搜索<code>Markdown All in One</code>安装。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/24/fe35a13933da93bba8f234be209bb212.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/24/fe35a13933da93bba8f234be209bb212.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>安装完成后，使用时右击窗口选择<code>Format Document with</code>：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/24/285b770adf0f3b3faff57ee14caca45b.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/24/285b770adf0f3b3faff57ee14caca45b.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>选择<code>Markdown All in One</code>即可自动对齐所有表格竖线：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/24/313d3b85a4e98be59acc85fc7337d30f.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/24/313d3b85a4e98be59acc85fc7337d30f.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h2 id="常见问题">常见问题</h2>
<h3 id="格式化文档后仍未对齐">格式化文档后仍未对齐</h3>
<p>这是由于表格中同时有中英文，而中英文字体不等宽导致的。如果对阅读要求不高，可以不用管，实际上已经格式化完成了。如果需要对齐，那么可以查看<a href="http://lifeislife.cn/2022/08/27/%E7%BC%96%E7%A0%81%E5%AD%97%E4%BD%93%E4%B8%8E%E9%98%85%E8%AF%BB%E5%AD%97%E4%BD%93%E6%8E%A8%E8%8D%90/">编码字体与阅读字体推荐</a>这篇文章的<strong>中文等宽字体</strong>下载并安装，即可正常对齐。</p>
]]></content:encoded>
    </item>
    <item>
      <title>使用 Markdownlint 对 Markdown 文本格式检查</title>
      <link>https://lifeislife.cn/posts/%E4%BD%BF%E7%94%A8markdownlint%E5%AF%B9markdown%E6%96%87%E6%9C%AC%E6%A0%BC%E5%BC%8F%E6%A3%80%E6%9F%A5/</link>
      <pubDate>Sat, 17 Sep 2022 11:07:10 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/%E4%BD%BF%E7%94%A8markdownlint%E5%AF%B9markdown%E6%96%87%E6%9C%AC%E6%A0%BC%E5%BC%8F%E6%A3%80%E6%9F%A5/</guid>
      <description>&lt;h1 id=&#34;markdownlint-简介&#34;&gt;Markdownlint 简介&lt;/h1&gt;
&lt;p&gt;Markdown 标记语言旨在易于阅读、编写和理解。它的灵活性既是优点也是缺点。语法众多，因此格式可能不一致。某些构造在所有解析器中都不能很好地工作，应该避免。CommonMark 规范标准化解析器。&lt;/p&gt;
&lt;p&gt;Markdownlint 是一个用于 Node.js 的静态分析工具，有一个标准规范，用于强制执行 Markdown 文件的标准和一致性。&lt;/p&gt;
&lt;h1 id=&#34;markdownlint-插件使用&#34;&gt;Markdownlint 插件使用&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/DavidAnson/markdownlint&#34;&gt;markdownlint&lt;/a&gt;提供了多种使用场景下的解决方案，如命令行，编辑器甚至 GitHub Action。因为我平时写 Markdown 文档都是使用 VSCode，所以介绍一下 VSCode 下的使用。其他编辑器包括 VIM，Sublime 也都支持，可以前往官网查阅方法。&lt;/p&gt;
&lt;p&gt;VSCode 需要下载插件，&lt;code&gt;Ctrl+Shift+X&lt;/code&gt;打开插件中心，搜索&lt;strong&gt;Markdownlint&lt;/strong&gt;安装即可。&lt;/p&gt;
&lt;p&gt;安装插件后打开 Markdown 文档，如果有不符合规范的语法将会警告标识。如，标题前后没有空行，将会标识：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/17/fbd7a1e70279b69efdfb5cd6d8120b7a.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/17/fbd7a1e70279b69efdfb5cd6d8120b7a.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;提示违反了第 22 条规范，第 22 条规范的就是标题前后需要有空行隔开。&lt;/p&gt;
&lt;p&gt;目前有 53 条规范，可以在&lt;a href=&#34;https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md001&#34;&gt;markdownlint/Rules.md&lt;/a&gt;查看所有规范的内容。&lt;/p&gt;
&lt;p&gt;当然这些规范也都可以自定义是否检查，比如第 24 条规定，文档内不可以有重复的标题，但是我就有重复标题的需求，那该如何关闭这个检查呢，Markdownlint 提供了配置的方式。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Ctrl+Shift+P&lt;/code&gt;打开运行窗口，输入 Markdownlint，找到&lt;code&gt;Creat or open the markdownlint configuration file&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/17/acc1dc59b5cb82261007e9fe72fccdc9.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/17/acc1dc59b5cb82261007e9fe72fccdc9.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;创建一个配置文件，并输入以下内容，表示关闭第 24 条规范的检查：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;MD024&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这样文档中将不会有第 24 条规范的检查警告，其他检查同理。&lt;/p&gt;
&lt;h1 id=&#34;markdownlint-自定义规则&#34;&gt;Markdownlint 自定义规则&lt;/h1&gt;
&lt;h2 id=&#34;md001---heading-levels-should-only-increment-by-one-level-at-a-time&#34;&gt;MD001 - Heading levels should only increment by one level at a time&lt;/h2&gt;
&lt;p&gt;标题等级一次只能增加一级，不能跨级。&lt;/p&gt;
&lt;p&gt;原理：标题代表文档的结构，跳过时可能会造成混淆 - 特别是对于可访问性场景。&lt;/p&gt;
&lt;h2 id=&#34;md002---first-heading-should-be-a-top-level-heading&#34;&gt;&lt;del&gt;MD002 - First heading should be a top-level heading&lt;/del&gt;&lt;/h2&gt;
&lt;p&gt;文档的第一个标题必须是最高级的标题（标题等级 1 级到 6 级逐渐降低）&lt;/p&gt;
&lt;h2 id=&#34;md003---heading-style&#34;&gt;MD003 - Heading style&lt;/h2&gt;
&lt;p&gt;整篇文档需要采用一致的标题格式。&lt;/p&gt;
&lt;h2 id=&#34;md004---unordered-list-style&#34;&gt;MD004 - Unordered list style&lt;/h2&gt;
&lt;p&gt;无序列表格式需要一致。&lt;/p&gt;
&lt;h2 id=&#34;md005---inconsistent-indentation-for-list-items-at-the-same-level&#34;&gt;MD005 - Inconsistent indentation for list items at the same level&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;同一级的列表缩进必须一致&lt;/li&gt;
&lt;li&gt;在有序列表中，前面的数字序号可以左对齐，也可以右对齐&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;md006---consider-starting-bulleted-lists-at-the-beginning-of-the-line&#34;&gt;&lt;del&gt;MD006 - Consider starting bulleted lists at the beginning of the line&lt;/del&gt;&lt;/h2&gt;
&lt;p&gt;一级列表不能缩进。&lt;/p&gt;
&lt;p&gt;如下为报错：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Some text
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;*&lt;/span&gt; List item
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;*&lt;/span&gt; List item
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;md007---unordered-list-indentation&#34;&gt;MD007 - Unordered list indentation&lt;/h2&gt;
&lt;p&gt;无序列表嵌套缩进时默认采用两个空格。&lt;/p&gt;
&lt;h2 id=&#34;md009---trailing-spaces&#34;&gt;MD009 - Trailing spaces&lt;/h2&gt;
&lt;p&gt;行尾最多可以添加两个空格，超过会给出警告，两个空格正好可以用于换行。&lt;/p&gt;
&lt;h2 id=&#34;md010---hard-tabs&#34;&gt;MD010 - Hard tabs&lt;/h2&gt;
&lt;p&gt;不能使用 tab 键缩进，要使用空格。&lt;/p&gt;
&lt;p&gt;原理：硬制表符通常由不同的编辑器以不一致的方式呈现，并且比空格更难处理。&lt;/p&gt;
&lt;h2 id=&#34;md011---reversed-link-syntax&#34;&gt;MD011 - Reversed link syntax&lt;/h2&gt;
&lt;p&gt;当遇到看似链接的文本，但语法似乎已反转（[] 和 () 反转）时，将触发此规则。&lt;/p&gt;
&lt;h2 id=&#34;md012---multiple-consecutive-blank-lines&#34;&gt;MD012 - Multiple consecutive blank lines&lt;/h2&gt;
&lt;p&gt;文档中不能有连续的空行，在代码块中此规则不会生效。&lt;/p&gt;
&lt;h2 id=&#34;md013---line-length&#34;&gt;MD013 - Line length&lt;/h2&gt;
&lt;p&gt;默认行的最大长度是 80，此规则对代码块、表格、标题也生效。&lt;/p&gt;
&lt;h2 id=&#34;md014---dollar-signs-used-before-commands-without-showing-output&#34;&gt;MD014 - Dollar signs used before commands without showing output&lt;/h2&gt;
&lt;p&gt;在代码块中，终端命令前不需要有美元符号 ($)
如果代码块中既有终端命令，也有命令的输出，则终端命令前可以有美元符号 ($)。&lt;/p&gt;
&lt;h2 id=&#34;md018---no-space-after-hash-on-atx-style-heading&#34;&gt;MD018 - No space after hash on atx style heading&lt;/h2&gt;
&lt;p&gt;在&amp;quot;atx&amp;quot;格式的标题中，&lt;code&gt;#&lt;/code&gt;号和文字间需用一个空格隔开。&lt;/p&gt;
&lt;h2 id=&#34;md019---multiple-spaces-after-hash-on-atx-style-heading&#34;&gt;MD019 - Multiple spaces after hash on atx style heading&lt;/h2&gt;
&lt;p&gt;在&amp;quot;atx&amp;quot;格式的标题中，#号和文字间只能用一个空格隔开，不能有多余的空格。&lt;/p&gt;
&lt;h2 id=&#34;md020---no-space-inside-hashes-on-closed-atx-style-heading&#34;&gt;MD020 - No space inside hashes on closed atx style heading&lt;/h2&gt;
&lt;p&gt;在&amp;quot;closed_atx&amp;quot;格式的标题中，文字和前后的#号之间需用一个空格隔开。&lt;/p&gt;
&lt;h2 id=&#34;md021---multiple-spaces-inside-hashes-on-closed-atx-style-heading&#34;&gt;MD021 - Multiple spaces inside hashes on closed atx style heading&lt;/h2&gt;
&lt;p&gt;在&amp;quot;closed_atx&amp;quot;格式的标题中，文字和前后的#号之间只能用一个空格隔开，不能有多余的空格。&lt;/p&gt;
&lt;h2 id=&#34;md022---headings-should-be-surrounded-by-blank-lines&#34;&gt;MD022 - Headings should be surrounded by blank lines&lt;/h2&gt;
&lt;p&gt;标题行的上下行必须都是空行。&lt;/p&gt;
&lt;h2 id=&#34;md023---headings-must-start-at-the-beginning-of-the-line&#34;&gt;MD023 - Headings must start at the beginning of the line&lt;/h2&gt;
&lt;p&gt;标题行不能缩进。&lt;/p&gt;
&lt;h2 id=&#34;md024---multiple-headings-with-the-same-content&#34;&gt;MD024 - Multiple headings with the same content&lt;/h2&gt;
&lt;p&gt;文档不能有内容重复的标题。&lt;/p&gt;
&lt;h2 id=&#34;md025---multiple-top-level-headings-in-the-same-document&#34;&gt;MD025 - Multiple top-level headings in the same document&lt;/h2&gt;
&lt;p&gt;同一文档只能有一个最高级的标题，默认是只能有一个 1 级标题。&lt;/p&gt;
&lt;h2 id=&#34;md026---trailing-punctuation-in-heading&#34;&gt;MD026 - Trailing punctuation in heading&lt;/h2&gt;
&lt;p&gt;标题行末尾不能有以下标点符号。&lt;/p&gt;
&lt;h2 id=&#34;md027---multiple-spaces-after-blockquote-symbol&#34;&gt;MD027 - Multiple spaces after blockquote symbol&lt;/h2&gt;
&lt;p&gt;创建引用区块时，右尖括号 ( &amp;gt; ) 和文字之间有且只能有一个空格。&lt;/p&gt;
&lt;h2 id=&#34;md028---blank-line-inside-blockquote&#34;&gt;MD028 - Blank line inside blockquote&lt;/h2&gt;
&lt;p&gt;两个引用区块间不能仅用一个空行隔开或者同一引用区块中不能有空行，如果一行中没有内容，则这一行要用&amp;gt;开头。&lt;/p&gt;
&lt;h2 id=&#34;md029---ordered-list-item-prefix&#34;&gt;MD029 - Ordered list item prefix&lt;/h2&gt;
&lt;p&gt;有序列表的前缀序号格式必须只用 1 或者从 1 开始的加 1 递增数字。&lt;/p&gt;
&lt;h2 id=&#34;md030---spaces-after-list-markers&#34;&gt;MD030 - Spaces after list markers&lt;/h2&gt;
&lt;p&gt;列表（有序、无序）的前缀符号和文字之间用 1 个空格隔开
在列表嵌套或者同一列表项中有多个段落时，无序列表缩进两个空格，有序列表缩进 3 个空格。&lt;/p&gt;
&lt;h2 id=&#34;md031---fenced-code-blocks-should-be-surrounded-by-blank-lines&#34;&gt;MD031 - Fenced code blocks should be surrounded by blank lines&lt;/h2&gt;
&lt;p&gt;单独的代码块前后需要用空行隔开（除非是在文档开头或末尾），否则有些解释器不会解释为代码块&lt;/p&gt;
&lt;h2 id=&#34;md032---lists-should-be-surrounded-by-blank-lines&#34;&gt;MD032 - Lists should be surrounded by blank lines&lt;/h2&gt;
&lt;p&gt;列表（有序、无序）前后需要用空行隔开，否则有些解释器不会解释为列表。&lt;/p&gt;
&lt;p&gt;列表的缩进必须一致。&lt;/p&gt;
&lt;h2 id=&#34;md033---inline-html&#34;&gt;MD033 - Inline HTML&lt;/h2&gt;
&lt;p&gt;文档中不允许使用 HTML 语句。&lt;/p&gt;
&lt;h2 id=&#34;md034---bare-url-used&#34;&gt;MD034 - Bare URL used&lt;/h2&gt;
&lt;p&gt;单纯的链接地址需要用尖括号 (&amp;lt;&amp;gt;) 包裹，否则有些解释器不会解释为链接。&lt;/p&gt;
&lt;h2 id=&#34;md035---horizontal-rule-style&#34;&gt;MD035 - Horizontal rule style&lt;/h2&gt;
&lt;p&gt;创建水平线时整篇文档要统一 (consistent)，要和文档中第一次创建水平线使用的符号一致。&lt;/p&gt;
&lt;h2 id=&#34;md036---emphasis-used-instead-of-a-heading&#34;&gt;MD036 - Emphasis used instead of a heading&lt;/h2&gt;
&lt;p&gt;不能用加粗代替标题。&lt;/p&gt;
&lt;h2 id=&#34;md037---spaces-inside-emphasis-markers&#34;&gt;MD037 - Spaces inside emphasis markers&lt;/h2&gt;
&lt;p&gt;用于创建强调的符号和强调的的文字之间不能有空格。&lt;/p&gt;
&lt;h2 id=&#34;md038---spaces-inside-code-span-elements&#34;&gt;MD038 - Spaces inside code span elements&lt;/h2&gt;
&lt;p&gt;当用单反引号创建代码段的时候，单反引号和它们之间的代码不能有空格
如果要把单反引号嵌入到代码段的首尾，创建代码段的单反引号和嵌入的单反引号间要有一个空格隔开。&lt;/p&gt;
&lt;h2 id=&#34;md039---spaces-inside-link-text&#34;&gt;MD039 - Spaces inside link text&lt;/h2&gt;
&lt;p&gt;链接名和包围它的中括号之间不能有空格，但链接名中间可以有空格。&lt;/p&gt;
&lt;h2 id=&#34;md040---fenced-code-blocks-should-have-a-language-specified&#34;&gt;MD040 - Fenced code blocks should have a language specified&lt;/h2&gt;
&lt;p&gt;单独的代码块（此处是指上下用三个反引号包围的代码块）应该指定代码块的编程语言，这一点有助于解释器对代码进行代码高亮。&lt;/p&gt;
&lt;h2 id=&#34;md041---first-line-in-a-file-should-be-a-top-level-heading&#34;&gt;MD041 - First line in a file should be a top-level heading&lt;/h2&gt;
&lt;p&gt;文档的第一个非空行应该是文档最高级的标题，默认是 1 级标题。&lt;/p&gt;
&lt;h2 id=&#34;md042---no-empty-links&#34;&gt;MD042 - No empty links&lt;/h2&gt;
&lt;p&gt;链接的地址不能为空。&lt;/p&gt;
&lt;h2 id=&#34;md043---required-heading-structure&#34;&gt;MD043 - Required heading structure&lt;/h2&gt;
&lt;p&gt;要求标题遵循一定的结构，默认是没有规定的结构。&lt;/p&gt;
&lt;h2 id=&#34;md044---proper-names-should-have-the-correct-capitalization&#34;&gt;MD044 - Proper names should have the correct capitalization&lt;/h2&gt;
&lt;p&gt;指定一些名称，会检查它是否有正确的大写。&lt;/p&gt;
&lt;h2 id=&#34;md045---images-should-have-alternate-text-alt-text&#34;&gt;MD045 - Images should have alternate text (alt text)&lt;/h2&gt;
&lt;p&gt;图片链接必须包含描述文本（alt text）。&lt;/p&gt;
&lt;h2 id=&#34;md046---code-block-style&#34;&gt;MD046 - Code block style&lt;/h2&gt;
&lt;p&gt;整篇文档采用一致的代码格式。&lt;/p&gt;
&lt;h2 id=&#34;md047---files-should-end-with-a-single-newline-character&#34;&gt;MD047 - Files should end with a single newline character&lt;/h2&gt;
&lt;p&gt;文档需用一个空行结尾。&lt;/p&gt;
&lt;h2 id=&#34;md048---code-fence-style&#34;&gt;MD048 - Code fence style&lt;/h2&gt;
&lt;p&gt;表示代码块的标记需要一直，可以是波浪号，也可以是点号。但是需要保持一致。&lt;/p&gt;
&lt;h2 id=&#34;md049---emphasis-style-should-be-consistent&#34;&gt;MD049 - Emphasis style should be consistent&lt;/h2&gt;
&lt;p&gt;强调符号需要一直，如斜体。&lt;/p&gt;
&lt;h2 id=&#34;md050---strong-style-should-be-consistent&#34;&gt;MD050 - Strong style should be consistent&lt;/h2&gt;
&lt;p&gt;加粗符号需要保持一致。&lt;/p&gt;
&lt;h2 id=&#34;md051---link-fragments-should-be-valid&#34;&gt;MD051 - Link fragments should be valid&lt;/h2&gt;
&lt;p&gt;锚点需要表示正确。&lt;/p&gt;
</description>
      <content:encoded><![CDATA[<h1 id="markdownlint-简介">Markdownlint 简介</h1>
<p>Markdown 标记语言旨在易于阅读、编写和理解。它的灵活性既是优点也是缺点。语法众多，因此格式可能不一致。某些构造在所有解析器中都不能很好地工作，应该避免。CommonMark 规范标准化解析器。</p>
<p>Markdownlint 是一个用于 Node.js 的静态分析工具，有一个标准规范，用于强制执行 Markdown 文件的标准和一致性。</p>
<h1 id="markdownlint-插件使用">Markdownlint 插件使用</h1>
<p><a href="https://github.com/DavidAnson/markdownlint">markdownlint</a>提供了多种使用场景下的解决方案，如命令行，编辑器甚至 GitHub Action。因为我平时写 Markdown 文档都是使用 VSCode，所以介绍一下 VSCode 下的使用。其他编辑器包括 VIM，Sublime 也都支持，可以前往官网查阅方法。</p>
<p>VSCode 需要下载插件，<code>Ctrl+Shift+X</code>打开插件中心，搜索<strong>Markdownlint</strong>安装即可。</p>
<p>安装插件后打开 Markdown 文档，如果有不符合规范的语法将会警告标识。如，标题前后没有空行，将会标识：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/17/fbd7a1e70279b69efdfb5cd6d8120b7a.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/17/fbd7a1e70279b69efdfb5cd6d8120b7a.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>提示违反了第 22 条规范，第 22 条规范的就是标题前后需要有空行隔开。</p>
<p>目前有 53 条规范，可以在<a href="https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md001">markdownlint/Rules.md</a>查看所有规范的内容。</p>
<p>当然这些规范也都可以自定义是否检查，比如第 24 条规定，文档内不可以有重复的标题，但是我就有重复标题的需求，那该如何关闭这个检查呢，Markdownlint 提供了配置的方式。</p>
<p><code>Ctrl+Shift+P</code>打开运行窗口，输入 Markdownlint，找到<code>Creat or open the markdownlint configuration file</code>。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/17/acc1dc59b5cb82261007e9fe72fccdc9.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/17/acc1dc59b5cb82261007e9fe72fccdc9.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>创建一个配置文件，并输入以下内容，表示关闭第 24 条规范的检查：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;MD024&#34;</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>这样文档中将不会有第 24 条规范的检查警告，其他检查同理。</p>
<h1 id="markdownlint-自定义规则">Markdownlint 自定义规则</h1>
<h2 id="md001---heading-levels-should-only-increment-by-one-level-at-a-time">MD001 - Heading levels should only increment by one level at a time</h2>
<p>标题等级一次只能增加一级，不能跨级。</p>
<p>原理：标题代表文档的结构，跳过时可能会造成混淆 - 特别是对于可访问性场景。</p>
<h2 id="md002---first-heading-should-be-a-top-level-heading"><del>MD002 - First heading should be a top-level heading</del></h2>
<p>文档的第一个标题必须是最高级的标题（标题等级 1 级到 6 级逐渐降低）</p>
<h2 id="md003---heading-style">MD003 - Heading style</h2>
<p>整篇文档需要采用一致的标题格式。</p>
<h2 id="md004---unordered-list-style">MD004 - Unordered list style</h2>
<p>无序列表格式需要一致。</p>
<h2 id="md005---inconsistent-indentation-for-list-items-at-the-same-level">MD005 - Inconsistent indentation for list items at the same level</h2>
<ul>
<li>同一级的列表缩进必须一致</li>
<li>在有序列表中，前面的数字序号可以左对齐，也可以右对齐</li>
</ul>
<h2 id="md006---consider-starting-bulleted-lists-at-the-beginning-of-the-line"><del>MD006 - Consider starting bulleted lists at the beginning of the line</del></h2>
<p>一级列表不能缩进。</p>
<p>如下为报错：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">Some text
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">*</span> List item
</span></span><span class="line"><span class="cl">  <span class="k">*</span> List item
</span></span></code></pre></div><h2 id="md007---unordered-list-indentation">MD007 - Unordered list indentation</h2>
<p>无序列表嵌套缩进时默认采用两个空格。</p>
<h2 id="md009---trailing-spaces">MD009 - Trailing spaces</h2>
<p>行尾最多可以添加两个空格，超过会给出警告，两个空格正好可以用于换行。</p>
<h2 id="md010---hard-tabs">MD010 - Hard tabs</h2>
<p>不能使用 tab 键缩进，要使用空格。</p>
<p>原理：硬制表符通常由不同的编辑器以不一致的方式呈现，并且比空格更难处理。</p>
<h2 id="md011---reversed-link-syntax">MD011 - Reversed link syntax</h2>
<p>当遇到看似链接的文本，但语法似乎已反转（[] 和 () 反转）时，将触发此规则。</p>
<h2 id="md012---multiple-consecutive-blank-lines">MD012 - Multiple consecutive blank lines</h2>
<p>文档中不能有连续的空行，在代码块中此规则不会生效。</p>
<h2 id="md013---line-length">MD013 - Line length</h2>
<p>默认行的最大长度是 80，此规则对代码块、表格、标题也生效。</p>
<h2 id="md014---dollar-signs-used-before-commands-without-showing-output">MD014 - Dollar signs used before commands without showing output</h2>
<p>在代码块中，终端命令前不需要有美元符号 ($)
如果代码块中既有终端命令，也有命令的输出，则终端命令前可以有美元符号 ($)。</p>
<h2 id="md018---no-space-after-hash-on-atx-style-heading">MD018 - No space after hash on atx style heading</h2>
<p>在&quot;atx&quot;格式的标题中，<code>#</code>号和文字间需用一个空格隔开。</p>
<h2 id="md019---multiple-spaces-after-hash-on-atx-style-heading">MD019 - Multiple spaces after hash on atx style heading</h2>
<p>在&quot;atx&quot;格式的标题中，#号和文字间只能用一个空格隔开，不能有多余的空格。</p>
<h2 id="md020---no-space-inside-hashes-on-closed-atx-style-heading">MD020 - No space inside hashes on closed atx style heading</h2>
<p>在&quot;closed_atx&quot;格式的标题中，文字和前后的#号之间需用一个空格隔开。</p>
<h2 id="md021---multiple-spaces-inside-hashes-on-closed-atx-style-heading">MD021 - Multiple spaces inside hashes on closed atx style heading</h2>
<p>在&quot;closed_atx&quot;格式的标题中，文字和前后的#号之间只能用一个空格隔开，不能有多余的空格。</p>
<h2 id="md022---headings-should-be-surrounded-by-blank-lines">MD022 - Headings should be surrounded by blank lines</h2>
<p>标题行的上下行必须都是空行。</p>
<h2 id="md023---headings-must-start-at-the-beginning-of-the-line">MD023 - Headings must start at the beginning of the line</h2>
<p>标题行不能缩进。</p>
<h2 id="md024---multiple-headings-with-the-same-content">MD024 - Multiple headings with the same content</h2>
<p>文档不能有内容重复的标题。</p>
<h2 id="md025---multiple-top-level-headings-in-the-same-document">MD025 - Multiple top-level headings in the same document</h2>
<p>同一文档只能有一个最高级的标题，默认是只能有一个 1 级标题。</p>
<h2 id="md026---trailing-punctuation-in-heading">MD026 - Trailing punctuation in heading</h2>
<p>标题行末尾不能有以下标点符号。</p>
<h2 id="md027---multiple-spaces-after-blockquote-symbol">MD027 - Multiple spaces after blockquote symbol</h2>
<p>创建引用区块时，右尖括号 ( &gt; ) 和文字之间有且只能有一个空格。</p>
<h2 id="md028---blank-line-inside-blockquote">MD028 - Blank line inside blockquote</h2>
<p>两个引用区块间不能仅用一个空行隔开或者同一引用区块中不能有空行，如果一行中没有内容，则这一行要用&gt;开头。</p>
<h2 id="md029---ordered-list-item-prefix">MD029 - Ordered list item prefix</h2>
<p>有序列表的前缀序号格式必须只用 1 或者从 1 开始的加 1 递增数字。</p>
<h2 id="md030---spaces-after-list-markers">MD030 - Spaces after list markers</h2>
<p>列表（有序、无序）的前缀符号和文字之间用 1 个空格隔开
在列表嵌套或者同一列表项中有多个段落时，无序列表缩进两个空格，有序列表缩进 3 个空格。</p>
<h2 id="md031---fenced-code-blocks-should-be-surrounded-by-blank-lines">MD031 - Fenced code blocks should be surrounded by blank lines</h2>
<p>单独的代码块前后需要用空行隔开（除非是在文档开头或末尾），否则有些解释器不会解释为代码块</p>
<h2 id="md032---lists-should-be-surrounded-by-blank-lines">MD032 - Lists should be surrounded by blank lines</h2>
<p>列表（有序、无序）前后需要用空行隔开，否则有些解释器不会解释为列表。</p>
<p>列表的缩进必须一致。</p>
<h2 id="md033---inline-html">MD033 - Inline HTML</h2>
<p>文档中不允许使用 HTML 语句。</p>
<h2 id="md034---bare-url-used">MD034 - Bare URL used</h2>
<p>单纯的链接地址需要用尖括号 (&lt;&gt;) 包裹，否则有些解释器不会解释为链接。</p>
<h2 id="md035---horizontal-rule-style">MD035 - Horizontal rule style</h2>
<p>创建水平线时整篇文档要统一 (consistent)，要和文档中第一次创建水平线使用的符号一致。</p>
<h2 id="md036---emphasis-used-instead-of-a-heading">MD036 - Emphasis used instead of a heading</h2>
<p>不能用加粗代替标题。</p>
<h2 id="md037---spaces-inside-emphasis-markers">MD037 - Spaces inside emphasis markers</h2>
<p>用于创建强调的符号和强调的的文字之间不能有空格。</p>
<h2 id="md038---spaces-inside-code-span-elements">MD038 - Spaces inside code span elements</h2>
<p>当用单反引号创建代码段的时候，单反引号和它们之间的代码不能有空格
如果要把单反引号嵌入到代码段的首尾，创建代码段的单反引号和嵌入的单反引号间要有一个空格隔开。</p>
<h2 id="md039---spaces-inside-link-text">MD039 - Spaces inside link text</h2>
<p>链接名和包围它的中括号之间不能有空格，但链接名中间可以有空格。</p>
<h2 id="md040---fenced-code-blocks-should-have-a-language-specified">MD040 - Fenced code blocks should have a language specified</h2>
<p>单独的代码块（此处是指上下用三个反引号包围的代码块）应该指定代码块的编程语言，这一点有助于解释器对代码进行代码高亮。</p>
<h2 id="md041---first-line-in-a-file-should-be-a-top-level-heading">MD041 - First line in a file should be a top-level heading</h2>
<p>文档的第一个非空行应该是文档最高级的标题，默认是 1 级标题。</p>
<h2 id="md042---no-empty-links">MD042 - No empty links</h2>
<p>链接的地址不能为空。</p>
<h2 id="md043---required-heading-structure">MD043 - Required heading structure</h2>
<p>要求标题遵循一定的结构，默认是没有规定的结构。</p>
<h2 id="md044---proper-names-should-have-the-correct-capitalization">MD044 - Proper names should have the correct capitalization</h2>
<p>指定一些名称，会检查它是否有正确的大写。</p>
<h2 id="md045---images-should-have-alternate-text-alt-text">MD045 - Images should have alternate text (alt text)</h2>
<p>图片链接必须包含描述文本（alt text）。</p>
<h2 id="md046---code-block-style">MD046 - Code block style</h2>
<p>整篇文档采用一致的代码格式。</p>
<h2 id="md047---files-should-end-with-a-single-newline-character">MD047 - Files should end with a single newline character</h2>
<p>文档需用一个空行结尾。</p>
<h2 id="md048---code-fence-style">MD048 - Code fence style</h2>
<p>表示代码块的标记需要一直，可以是波浪号，也可以是点号。但是需要保持一致。</p>
<h2 id="md049---emphasis-style-should-be-consistent">MD049 - Emphasis style should be consistent</h2>
<p>强调符号需要一直，如斜体。</p>
<h2 id="md050---strong-style-should-be-consistent">MD050 - Strong style should be consistent</h2>
<p>加粗符号需要保持一致。</p>
<h2 id="md051---link-fragments-should-be-valid">MD051 - Link fragments should be valid</h2>
<p>锚点需要表示正确。</p>
]]></content:encoded>
    </item>
    <item>
      <title>VSCode 字体快速切换</title>
      <link>https://lifeislife.cn/posts/vscode%E5%AD%97%E4%BD%93%E5%BF%AB%E9%80%9F%E5%88%87%E6%8D%A2/</link>
      <pubDate>Mon, 12 Sep 2022 15:05:16 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/vscode%E5%AD%97%E4%BD%93%E5%BF%AB%E9%80%9F%E5%88%87%E6%8D%A2/</guid>
      <description>&lt;h2 id=&#34;需求背景&#34;&gt;需求背景&lt;/h2&gt;
&lt;p&gt;在写 MD 文档时为了追求美观，表格通常都是对齐的，这就需要字体必须等宽，但是写代码时等宽字体的因为很瘦小，不容易阅读，所以想要一个插件能够在多个字体直接快速切换。万能 VSCode 啥都有，插件中心就有一款专门切换字体的插件&lt;code&gt;Font Switcher&lt;/code&gt;。直接搜索安装。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/12/15-09-47-3c903030ae9986896c2e4c2537c77f57-20220912150947-77eec8.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/12/15-09-47-3c903030ae9986896c2e4c2537c77f57-20220912150947-77eec8.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h2 id=&#34;配置与使用&#34;&gt;配置与使用&lt;/h2&gt;
&lt;p&gt;打开配置脚本&lt;code&gt;settings.json&lt;/code&gt;，如果以前修改过字体，找到&lt;code&gt;&amp;quot;editor.fontFamily&amp;quot;&lt;/code&gt;配置项，如果没有就直接添加。&lt;/p&gt;
&lt;p&gt;这是我的字体，添加你们机器上安装的字体，每个逗号间隔都是不同的字体，可以使用&lt;code&gt;Font Switcher&lt;/code&gt;切换，需要注意的是，&lt;strong&gt;字体名没有空格不需要加单引号，加了也无妨，如果有空格，一定要加引号&lt;/strong&gt;。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;editor.fontFamily&amp;#34;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#39;Sarasa Mono SC&amp;#39;, 微软雅黑，&amp;#39;Noto Sans Mono CJK SC&amp;#39;, &amp;#39;JetBrains Mono&amp;#39;, Consolas, monospace&amp;#34;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;Ctrl+Shift+P&lt;/code&gt;打开运行窗口，输入&lt;code&gt;Switch Font&lt;/code&gt;，选择切换的字体。如图：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/12/dd742307432154f630585e05a1f57956.gif&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/12/dd742307432154f630585e05a1f57956.gif&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;![](&lt;a href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/12/15-17-44-dd742307432154f630585e05a1f57956-GIF&#34;&gt;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/12/15-17-44-dd742307432154f630585e05a1f57956-GIF&lt;/a&gt; 2022-9-12 15-17-27-836285.gif)&lt;/p&gt;
</description>
      <content:encoded><![CDATA[<h2 id="需求背景">需求背景</h2>
<p>在写 MD 文档时为了追求美观，表格通常都是对齐的，这就需要字体必须等宽，但是写代码时等宽字体的因为很瘦小，不容易阅读，所以想要一个插件能够在多个字体直接快速切换。万能 VSCode 啥都有，插件中心就有一款专门切换字体的插件<code>Font Switcher</code>。直接搜索安装。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/12/15-09-47-3c903030ae9986896c2e4c2537c77f57-20220912150947-77eec8.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/12/15-09-47-3c903030ae9986896c2e4c2537c77f57-20220912150947-77eec8.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h2 id="配置与使用">配置与使用</h2>
<p>打开配置脚本<code>settings.json</code>，如果以前修改过字体，找到<code>&quot;editor.fontFamily&quot;</code>配置项，如果没有就直接添加。</p>
<p>这是我的字体，添加你们机器上安装的字体，每个逗号间隔都是不同的字体，可以使用<code>Font Switcher</code>切换，需要注意的是，<strong>字体名没有空格不需要加单引号，加了也无妨，如果有空格，一定要加引号</strong>。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="s2">&#34;editor.fontFamily&#34;</span><span class="err">:</span> <span class="s2">&#34;&#39;Sarasa Mono SC&#39;, 微软雅黑，&#39;Noto Sans Mono CJK SC&#39;, &#39;JetBrains Mono&#39;, Consolas, monospace&#34;</span><span class="err">,</span>
</span></span></code></pre></div><p><code>Ctrl+Shift+P</code>打开运行窗口，输入<code>Switch Font</code>，选择切换的字体。如图：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/12/dd742307432154f630585e05a1f57956.gif">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/12/dd742307432154f630585e05a1f57956.gif" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>![](<a href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/12/15-17-44-dd742307432154f630585e05a1f57956-GIF">https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img//2022/09/12/15-17-44-dd742307432154f630585e05a1f57956-GIF</a> 2022-9-12 15-17-27-836285.gif)</p>
]]></content:encoded>
    </item>
    <item>
      <title>保持 SSH 连接</title>
      <link>https://lifeislife.cn/posts/%E4%BF%9D%E6%8C%81ssh%E8%BF%9E%E6%8E%A5/</link>
      <pubDate>Sat, 13 Aug 2022 20:28:57 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/%E4%BF%9D%E6%8C%81ssh%E8%BF%9E%E6%8E%A5/</guid>
      <description>&lt;p&gt;SSH 总是被强行中断，尤其是用 VSCode 代码写的好好的，突然刷新窗口，不仅效率低，更惹人恼火。&lt;/p&gt;
&lt;p&gt;可以通过配置服务端或客户端的 SSH 来保持 SSH 链接：&lt;/p&gt;
&lt;h2 id=&#34;方法一配置服务端&#34;&gt;方法一：配置服务端&lt;/h2&gt;
&lt;p&gt;可以在服务端配置，让 server 每隔 30 秒向 client 发送一个 keep-alive 包来保持连接：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;vim /etc/ssh/sshd_config
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ClientAliveInterval &lt;span class=&#34;m&#34;&gt;30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ClientAliveCountMax &lt;span class=&#34;m&#34;&gt;60&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;第二行配置表示如果发送 keep-alive 包数量达到 60 次，客户端依然没有反应，则服务端 sshd 断开连接。如果什么都不操作，该配置可以让连接保持 30s*60，30 min&lt;/p&gt;
&lt;p&gt;重启本地 ssh&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo service ssh restart
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果找不到 ssh,”Failed to restart ssh.service: Unit ssh.service not found.” ，需要安装&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo apt-get install openssh-server
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;方法二配置客户端&#34;&gt;方法二：配置客户端&lt;/h2&gt;
&lt;p&gt;如果服务端没有权限配置，或者无法配置，可以配置客户端 ssh，使客户端发起的所有会话都保持连接：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;vim /etc/ssh/ssh_config
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ServerAliveInterval &lt;span class=&#34;m&#34;&gt;30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ServerAliveCountMax &lt;span class=&#34;m&#34;&gt;60&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;本地 ssh 每隔 30s 向 server 端 sshd 发送 keep-alive 包，如果发送 60 次，server 无回应断开连接。&lt;/p&gt;
&lt;p&gt;在 VSCode 里可以直接添加配置，效果一样：


&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208132040474.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208132040474.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Host 11.22.33.44
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  HostName 11.22.33.44
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  User user
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Port &lt;span class=&#34;m&#34;&gt;112343&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ServerAliveInterval &lt;span class=&#34;m&#34;&gt;30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ServerAliveCountMax &lt;span class=&#34;m&#34;&gt;60&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <content:encoded><![CDATA[<p>SSH 总是被强行中断，尤其是用 VSCode 代码写的好好的，突然刷新窗口，不仅效率低，更惹人恼火。</p>
<p>可以通过配置服务端或客户端的 SSH 来保持 SSH 链接：</p>
<h2 id="方法一配置服务端">方法一：配置服务端</h2>
<p>可以在服务端配置，让 server 每隔 30 秒向 client 发送一个 keep-alive 包来保持连接：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">vim /etc/ssh/sshd_config
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ClientAliveInterval <span class="m">30</span>
</span></span><span class="line"><span class="cl">ClientAliveCountMax <span class="m">60</span>
</span></span></code></pre></div><p>第二行配置表示如果发送 keep-alive 包数量达到 60 次，客户端依然没有反应，则服务端 sshd 断开连接。如果什么都不操作，该配置可以让连接保持 30s*60，30 min</p>
<p>重启本地 ssh</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo service ssh restart
</span></span></code></pre></div><p>如果找不到 ssh,”Failed to restart ssh.service: Unit ssh.service not found.” ，需要安装</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt-get install openssh-server
</span></span></code></pre></div><h2 id="方法二配置客户端">方法二：配置客户端</h2>
<p>如果服务端没有权限配置，或者无法配置，可以配置客户端 ssh，使客户端发起的所有会话都保持连接：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">vim /etc/ssh/ssh_config
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ServerAliveInterval <span class="m">30</span>
</span></span><span class="line"><span class="cl">ServerAliveCountMax <span class="m">60</span>
</span></span></code></pre></div><p>本地 ssh 每隔 30s 向 server 端 sshd 发送 keep-alive 包，如果发送 60 次，server 无回应断开连接。</p>
<p>在 VSCode 里可以直接添加配置，效果一样：


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208132040474.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208132040474.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Host 11.22.33.44
</span></span><span class="line"><span class="cl">  HostName 11.22.33.44
</span></span><span class="line"><span class="cl">  User user
</span></span><span class="line"><span class="cl">  Port <span class="m">112343</span>
</span></span><span class="line"><span class="cl">  ServerAliveInterval <span class="m">30</span>
</span></span><span class="line"><span class="cl">  ServerAliveCountMax <span class="m">60</span>
</span></span></code></pre></div>]]></content:encoded>
    </item>
    <item>
      <title>使用 Syncthing 多端丝滑同步与备份</title>
      <link>https://lifeislife.cn/posts/%E4%BD%BF%E7%94%A8syncthing%E5%A4%9A%E7%AB%AF%E4%B8%9D%E6%BB%91%E5%90%8C%E6%AD%A5%E4%B8%8E%E5%A4%87%E4%BB%BD/</link>
      <pubDate>Mon, 01 Aug 2022 22:48:21 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/%E4%BD%BF%E7%94%A8syncthing%E5%A4%9A%E7%AB%AF%E4%B8%9D%E6%BB%91%E5%90%8C%E6%AD%A5%E4%B8%8E%E5%A4%87%E4%BB%BD/</guid>
      <description>&lt;h2 id=&#34;折腾背景&#34;&gt;折腾背景&lt;/h2&gt;
&lt;p&gt;一直想找一个能够快速同步手机与电脑数据的工具，因为手机云服务的空间少的可怜，所以习惯隔一段时间将手机里的照片、视频还有一些文件导出到电脑上。但是每次备份文件都得连接数据线，并且没法增量备份，得手动挑选，也还挺麻烦的。&lt;/p&gt;
&lt;p&gt;逛 GitHub 时，无意间发现了 Syncthing，几乎符合了我所有的预期。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;开源，免费，自己电脑就可以当服务器，以后入了 NAS，可以自己搭建本地服务器。&lt;/li&gt;
&lt;li&gt;同步速度快，取决 WIFI 的速度，目前使用 30M/s，基本满速。&lt;/li&gt;
&lt;li&gt;多端支持，除了 IOS（反正我也没有 iOS 设备，嘿嘿），几乎全平台支持，包括 NAS 及路由器。&lt;/li&gt;
&lt;li&gt;增量同步，再也不用挑文件备份了。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;话不多说，开整。&lt;/p&gt;
&lt;h2 id=&#34;下载安装&#34;&gt;下载安装&lt;/h2&gt;
&lt;p&gt;直接进入&lt;a href=&#34;https://syncthing.net/&#34;&gt;Syncthing&lt;/a&gt;官网，下载安装。在 Ubuntu 下安装&lt;a href=&#34;https://apt.syncthing.net/&#34;&gt;参考这里&lt;/a&gt;。Android 版本下载&lt;a href=&#34;https://f-droid.org/packages/com.nutomic.syncthingandroid/&#34;&gt;Syncthing&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;接下来以 Windows 与 Android 手机同步为例，下载安装后，打开&lt;code&gt;syncthing.exe&lt;/code&gt;，即可打开管理界面，或者浏览器输入&lt;code&gt;http://127.0.0.1:8384&lt;/code&gt;也可进入管理界面。&lt;/p&gt;
&lt;p&gt;Windows 界面：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131917716.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131917716.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;Android 界面：


&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131920202.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131920202.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h2 id=&#34;设备配对&#34;&gt;设备配对&lt;/h2&gt;
&lt;p&gt;Windows 管理页面-&amp;gt;操作-&amp;gt;显示 ID，会显示本机的二维码：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131922624.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131922624.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;Android 手机打开应用，切换到&lt;strong&gt;设备&lt;/strong&gt;界面，点击右上角&lt;strong&gt;加号&lt;/strong&gt;，点击二维码标识，即可扫描二维码，完成设备添加。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131927893.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131927893.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;如果正确添加，Windows 管理界面会显示 Android 设备：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131928172.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131928172.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h2 id=&#34;android-同步至-windows&#34;&gt;Android 同步至 Windows&lt;/h2&gt;
&lt;p&gt;打开 Android 应用，切换到&lt;strong&gt;文件夹&lt;/strong&gt;界面，点击右上角&lt;strong&gt;加号&lt;/strong&gt;，配置同步的文件夹：


&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131931912.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131931912.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;根据下图提示，配置应用，记得保存：


&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131934895.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131934895.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
目录列表显示刚刚的配置：


&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131937682.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131937682.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;点击打开，开启与远程设备 Windows 同步：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131938899.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131938899.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;当返回时，Windows 端将会弹出通知，提示有 Android 设备的文件要分享到电脑，点击&lt;strong&gt;添加&lt;/strong&gt;：


&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131939273.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131939273.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131941549.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131941549.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;至此，Android 同步至 Windows 完成。此时在 Android 设备的文件夹中添加任意文件，都会同步到 Windows。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果是局域网内，发现设备的速度很慢，可以尝试设置静态的 IP。手机端 -&amp;gt; 设备 -&amp;gt; 链接图标。默认为 dynamic，将其改为 Windows 的 IP 和 syncthing 的端口。如&lt;code&gt;tcp://192.168.1.9:22000&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;也可以在服务端配置手机的IP，手机IP可以通过设置中心-&amp;gt;关于手机-&amp;gt;状态-&amp;gt;IP地址查看。比如192.168.1.16，那么可以配置为&lt;code&gt;tcp://192.168.1.16:22000&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;windows-同步至-android&#34;&gt;Windows 同步至 Android&lt;/h2&gt;
&lt;p&gt;Windows 管理界面，添加文件夹：


&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131945074.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131945074.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131947601.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131947601.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131948844.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131948844.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;点击保存后，与之前类似，Android 会提示有 Windows 设备的文件要分享到 Android，点击&lt;strong&gt;添加&lt;/strong&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果 Android 设备没有弹出提示添加共享文件夹，那么打开应用侧边栏-&amp;gt;网页管理页面，将会有弹窗，如下图&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208132019765.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208132019765.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;点击添加，配置文件夹目录等与之前类似。&lt;/p&gt;
&lt;p&gt;至此，Windows 同步至 Android 完成。此时在 Windows 设备的文件夹中添加任意文件，都会同步到 Android。&lt;/p&gt;
&lt;h2 id=&#34;使用技巧&#34;&gt;使用技巧&lt;/h2&gt;
&lt;h3 id=&#34;syncthing-支持三种工作模式&#34;&gt;Syncthing 支持三种工作模式&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;发送和接收，Send &amp;amp; Receive Folder，这是文件夹的默认模式，对文件夹的修改会发送，其他设备的修改也会同步回来。&lt;/li&gt;
&lt;li&gt;仅发送 Send Only，这种模式表示仅仅将当前设备上的文件夹的改动发送到其他设备，用来隐式地表示其他同步设备上的文件不会被修改，或者其他设备上的修改可以被忽略。这种模式非常适合，将当前设备设定为工作设备，然后设定一台设备作为此设备的备份。
&lt;ul&gt;
&lt;li&gt;在 Send Only 模式下，集群中其他设备的修改都会被忽略，修改依然会接收，文件夹可能会出现 「out of sync」，但是没有修改会被应用到本地。&lt;/li&gt;
&lt;li&gt;当 Send Only 文件夹出现 out of sync，那么一个红色的 Override Changes 会出现在文件夹详情中，点击该按钮会强制将当前主机的状态同步到其他剩余节点。任何对文件的修改，都会被当前主机上的版本所覆盖，任何不存在于当前主机节点的文件都会被删除，其他类似。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;仅接收 Receive Only，这种模式下所有的修改都会被接收并应用，然后重新分发给其他使用 send-receive 模式的设备。但是本地的修改不会被分发给其他设备。这种模式适合于建立备份镜像（replication mirrors），或者备份目的主机的场景，这些情况下不期望有本地修改或者本地的修改是不允许的
&lt;ul&gt;
&lt;li&gt;当本地文件被删除时，Syncthing 会显示一个 Revert Local Changes 按钮。使用这个按钮会将本地的修改回撤，所有添加的文件会被删除，修改或删除的文件会重新从其他节点同步，比较容易理解，但是假如 A 设备设置仅发送，B 设备设置发送和接收，A 是不会同步 B 的更改的！&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;忽略特定文件目录&#34;&gt;忽略特定文件、目录&lt;/h3&gt;
&lt;p&gt;忽略列表，和 gitignore 类似。每一台设备上的 &lt;code&gt;.stignore&lt;/code&gt; 都是分别设置的，不会进行同步。&lt;/p&gt;
&lt;p&gt;如果 A 的&lt;code&gt;.stignore&lt;/code&gt;忽略了 &lt;code&gt;test&lt;/code&gt; ，而 B 没有这样做，实际上会发生这样的事情：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A 不会扫描和通知 B（广播）关于 test 的变动；&lt;/li&gt;
&lt;li&gt;B 对关于 test 的变动持开放的姿态，但不会收到任何关于 A 上面 test 的变动信息（可能接收到其它同步设备的）；&lt;/li&gt;
&lt;li&gt;B 会扫描 test 以及推送其关于 test 变动的信息，但会被 A 忽略，A 也会忽略其它同步设备关于 test 的信息；&lt;/li&gt;
&lt;li&gt;B 会接收来自其它同步设备推送的关于 test 的信息；&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;参考资料&#34;&gt;参考资料&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.einverne.info/post/2019/10/syncthing.html&#34;&gt;Syncthing 又一款同步工具 | Verne in GitHub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://docs.syncthing.net/users/foldertypes.html&#34;&gt;Folder Types — Syncthing documentation&lt;/a&gt;&lt;/p&gt;
</description>
      <content:encoded><![CDATA[<h2 id="折腾背景">折腾背景</h2>
<p>一直想找一个能够快速同步手机与电脑数据的工具，因为手机云服务的空间少的可怜，所以习惯隔一段时间将手机里的照片、视频还有一些文件导出到电脑上。但是每次备份文件都得连接数据线，并且没法增量备份，得手动挑选，也还挺麻烦的。</p>
<p>逛 GitHub 时，无意间发现了 Syncthing，几乎符合了我所有的预期。</p>
<ul>
<li>开源，免费，自己电脑就可以当服务器，以后入了 NAS，可以自己搭建本地服务器。</li>
<li>同步速度快，取决 WIFI 的速度，目前使用 30M/s，基本满速。</li>
<li>多端支持，除了 IOS（反正我也没有 iOS 设备，嘿嘿），几乎全平台支持，包括 NAS 及路由器。</li>
<li>增量同步，再也不用挑文件备份了。</li>
</ul>
<p>话不多说，开整。</p>
<h2 id="下载安装">下载安装</h2>
<p>直接进入<a href="https://syncthing.net/">Syncthing</a>官网，下载安装。在 Ubuntu 下安装<a href="https://apt.syncthing.net/">参考这里</a>。Android 版本下载<a href="https://f-droid.org/packages/com.nutomic.syncthingandroid/">Syncthing</a>。</p>
<p>接下来以 Windows 与 Android 手机同步为例，下载安装后，打开<code>syncthing.exe</code>，即可打开管理界面，或者浏览器输入<code>http://127.0.0.1:8384</code>也可进入管理界面。</p>
<p>Windows 界面：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131917716.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131917716.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>Android 界面：


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131920202.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131920202.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h2 id="设备配对">设备配对</h2>
<p>Windows 管理页面-&gt;操作-&gt;显示 ID，会显示本机的二维码：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131922624.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131922624.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>Android 手机打开应用，切换到<strong>设备</strong>界面，点击右上角<strong>加号</strong>，点击二维码标识，即可扫描二维码，完成设备添加。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131927893.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131927893.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>如果正确添加，Windows 管理界面会显示 Android 设备：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131928172.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131928172.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h2 id="android-同步至-windows">Android 同步至 Windows</h2>
<p>打开 Android 应用，切换到<strong>文件夹</strong>界面，点击右上角<strong>加号</strong>，配置同步的文件夹：


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131931912.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131931912.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>根据下图提示，配置应用，记得保存：


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131934895.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131934895.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html>
目录列表显示刚刚的配置：


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131937682.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131937682.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>点击打开，开启与远程设备 Windows 同步：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131938899.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131938899.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>当返回时，Windows 端将会弹出通知，提示有 Android 设备的文件要分享到电脑，点击<strong>添加</strong>：


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131939273.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131939273.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131941549.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131941549.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>至此，Android 同步至 Windows 完成。此时在 Android 设备的文件夹中添加任意文件，都会同步到 Windows。</p>
<blockquote>
<p>如果是局域网内，发现设备的速度很慢，可以尝试设置静态的 IP。手机端 -&gt; 设备 -&gt; 链接图标。默认为 dynamic，将其改为 Windows 的 IP 和 syncthing 的端口。如<code>tcp://192.168.1.9:22000</code>。</p>
</blockquote>
<blockquote>
<p>也可以在服务端配置手机的IP，手机IP可以通过设置中心-&gt;关于手机-&gt;状态-&gt;IP地址查看。比如192.168.1.16，那么可以配置为<code>tcp://192.168.1.16:22000</code>。</p>
</blockquote>
<h2 id="windows-同步至-android">Windows 同步至 Android</h2>
<p>Windows 管理界面，添加文件夹：


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131945074.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131945074.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131947601.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131947601.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131948844.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208131948844.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>点击保存后，与之前类似，Android 会提示有 Windows 设备的文件要分享到 Android，点击<strong>添加</strong>：</p>
<blockquote>
<p>如果 Android 设备没有弹出提示添加共享文件夹，那么打开应用侧边栏-&gt;网页管理页面，将会有弹窗，如下图</p>
</blockquote>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208132019765.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202208132019765.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>点击添加，配置文件夹目录等与之前类似。</p>
<p>至此，Windows 同步至 Android 完成。此时在 Windows 设备的文件夹中添加任意文件，都会同步到 Android。</p>
<h2 id="使用技巧">使用技巧</h2>
<h3 id="syncthing-支持三种工作模式">Syncthing 支持三种工作模式</h3>
<ul>
<li>发送和接收，Send &amp; Receive Folder，这是文件夹的默认模式，对文件夹的修改会发送，其他设备的修改也会同步回来。</li>
<li>仅发送 Send Only，这种模式表示仅仅将当前设备上的文件夹的改动发送到其他设备，用来隐式地表示其他同步设备上的文件不会被修改，或者其他设备上的修改可以被忽略。这种模式非常适合，将当前设备设定为工作设备，然后设定一台设备作为此设备的备份。
<ul>
<li>在 Send Only 模式下，集群中其他设备的修改都会被忽略，修改依然会接收，文件夹可能会出现 「out of sync」，但是没有修改会被应用到本地。</li>
<li>当 Send Only 文件夹出现 out of sync，那么一个红色的 Override Changes 会出现在文件夹详情中，点击该按钮会强制将当前主机的状态同步到其他剩余节点。任何对文件的修改，都会被当前主机上的版本所覆盖，任何不存在于当前主机节点的文件都会被删除，其他类似。</li>
</ul>
</li>
<li>仅接收 Receive Only，这种模式下所有的修改都会被接收并应用，然后重新分发给其他使用 send-receive 模式的设备。但是本地的修改不会被分发给其他设备。这种模式适合于建立备份镜像（replication mirrors），或者备份目的主机的场景，这些情况下不期望有本地修改或者本地的修改是不允许的
<ul>
<li>当本地文件被删除时，Syncthing 会显示一个 Revert Local Changes 按钮。使用这个按钮会将本地的修改回撤，所有添加的文件会被删除，修改或删除的文件会重新从其他节点同步，比较容易理解，但是假如 A 设备设置仅发送，B 设备设置发送和接收，A 是不会同步 B 的更改的！</li>
</ul>
</li>
</ul>
<h3 id="忽略特定文件目录">忽略特定文件、目录</h3>
<p>忽略列表，和 gitignore 类似。每一台设备上的 <code>.stignore</code> 都是分别设置的，不会进行同步。</p>
<p>如果 A 的<code>.stignore</code>忽略了 <code>test</code> ，而 B 没有这样做，实际上会发生这样的事情：</p>
<ul>
<li>A 不会扫描和通知 B（广播）关于 test 的变动；</li>
<li>B 对关于 test 的变动持开放的姿态，但不会收到任何关于 A 上面 test 的变动信息（可能接收到其它同步设备的）；</li>
<li>B 会扫描 test 以及推送其关于 test 变动的信息，但会被 A 忽略，A 也会忽略其它同步设备关于 test 的信息；</li>
<li>B 会接收来自其它同步设备推送的关于 test 的信息；</li>
</ul>
<h2 id="参考资料">参考资料</h2>
<p><a href="https://blog.einverne.info/post/2019/10/syncthing.html">Syncthing 又一款同步工具 | Verne in GitHub</a></p>
<p><a href="https://docs.syncthing.net/users/foldertypes.html">Folder Types — Syncthing documentation</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>Gerrit 批量添加抄送提醒</title>
      <link>https://lifeislife.cn/posts/gerrit%E6%89%B9%E9%87%8F%E6%B7%BB%E5%8A%A0%E6%8A%84%E9%80%81%E6%8F%90%E9%86%92/</link>
      <pubDate>Fri, 29 Jul 2022 13:58:27 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/gerrit%E6%89%B9%E9%87%8F%E6%B7%BB%E5%8A%A0%E6%8A%84%E9%80%81%E6%8F%90%E9%86%92/</guid>
      <description>&lt;h2 id=&#34;背景&#34;&gt;背景&lt;/h2&gt;
&lt;p&gt;公司使用 Gerrit 作为 Review 平台，但是每次提交代码都需要手动添加 Reviewer，还要抄送组内成员，这种重复性劳动，程序员是绝不能容忍的。gerrit 提供了发送邮件的功能。&lt;/p&gt;
&lt;h2 id=&#34;解决方法&#34;&gt;解决方法&lt;/h2&gt;
&lt;p&gt;官方示例：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git push ssh://john.doe@git.example.com:29418/kernel/common HEAD:refs/for/experimental%r=a@a.com,cc=b@o.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;最后的&lt;code&gt;%&lt;/code&gt;是个分隔符，&lt;code&gt;r=&#39;a@a.com&lt;/code&gt;表示 Reviewer 是&lt;code&gt;a@a.com&lt;/code&gt;，&lt;code&gt;cc=b@o.com&lt;/code&gt;表示抄送组内成员是&lt;code&gt;b@o.com&lt;/code&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;注意！邮箱之间不能有空格！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;以一个仓库为例：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;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
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但是要这么写，岂不是把操作搞更复杂了。&lt;/p&gt;
&lt;p&gt;终极办法，打开项目路径下的&lt;code&gt;.git&lt;/code&gt;目录。编辑&lt;code&gt;config&lt;/code&gt;文件：&lt;/p&gt;
&lt;p&gt;原文件里有如下字段：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[core]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; repositoryformatversion = 0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; filemode = false
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; bare = false
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; logallrefupdates = true
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; ignorecase = true
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[remote &amp;#34;origin&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; url = git@github.com:Dunky-Z/Dunky-Z.github.io.git
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; fetch = +refs/heads/*:refs/remotes/origin/*
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们可以将远程仓库名换成容易区分的名字，自己随意：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[core]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; repositoryformatversion = 0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; filemode = false
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; bare = false
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; logallrefupdates = true
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; ignorecase = true
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[remote &amp;#34;origin&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; url = git@github.com:Dunky-Z/Dunky-Z.github.io.git
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; fetch = +refs/heads/*:refs/remotes/origin/*
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# 以下为新增内容
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[remote &amp;#34;review&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; url = git@github.com:Dunky-Z/Dunky-Z.github.io.git
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; fetch = +refs/heads/*:refs/remotes/origin/*
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; push =  HEAD:refs/for/%cc=zhangsan@qq.com,
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; cc=lisi@qq.com,
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; cc=wangerma@qq.com,
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; cc=chenwu@qq.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;下次想要推送需要 review 的代码，就直接执行&lt;code&gt;git push review&lt;/code&gt;，其中&lt;code&gt;push&lt;/code&gt;就相当于：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;push HEAD:refs/for/%cc=zhangsan@qq.com,cc=lisi@qq.com,cc=wangerma@qq.com,cc=chenwu@qq.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;参考资料&#34;&gt;参考资料&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://gerrit-review.googlesource.com/Documentation/user-upload.html#push_create,&#34;&gt;Gerrit Code Review - Uploading Changes&lt;/a&gt;&lt;/p&gt;
</description>
      <content:encoded><![CDATA[<h2 id="背景">背景</h2>
<p>公司使用 Gerrit 作为 Review 平台，但是每次提交代码都需要手动添加 Reviewer，还要抄送组内成员，这种重复性劳动，程序员是绝不能容忍的。gerrit 提供了发送邮件的功能。</p>
<h2 id="解决方法">解决方法</h2>
<p>官方示例：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">git push ssh://john.doe@git.example.com:29418/kernel/common HEAD:refs/for/experimental%r=a@a.com,cc=b@o.com
</span></span></code></pre></div><p>最后的<code>%</code>是个分隔符，<code>r='a@a.com</code>表示 Reviewer 是<code>a@a.com</code>，<code>cc=b@o.com</code>表示抄送组内成员是<code>b@o.com</code>。</p>
<blockquote>
<p>注意！邮箱之间不能有空格！</p>
</blockquote>
<p>以一个仓库为例：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">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
</span></span></code></pre></div><p>但是要这么写，岂不是把操作搞更复杂了。</p>
<p>终极办法，打开项目路径下的<code>.git</code>目录。编辑<code>config</code>文件：</p>
<p>原文件里有如下字段：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[core]
</span></span><span class="line"><span class="cl"> repositoryformatversion = 0
</span></span><span class="line"><span class="cl"> filemode = false
</span></span><span class="line"><span class="cl"> bare = false
</span></span><span class="line"><span class="cl"> logallrefupdates = true
</span></span><span class="line"><span class="cl"> ignorecase = true
</span></span><span class="line"><span class="cl">[remote &#34;origin&#34;]
</span></span><span class="line"><span class="cl"> url = git@github.com:Dunky-Z/Dunky-Z.github.io.git
</span></span><span class="line"><span class="cl"> fetch = +refs/heads/*:refs/remotes/origin/*
</span></span></code></pre></div><p>我们可以将远程仓库名换成容易区分的名字，自己随意：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[core]
</span></span><span class="line"><span class="cl"> repositoryformatversion = 0
</span></span><span class="line"><span class="cl"> filemode = false
</span></span><span class="line"><span class="cl"> bare = false
</span></span><span class="line"><span class="cl"> logallrefupdates = true
</span></span><span class="line"><span class="cl"> ignorecase = true
</span></span><span class="line"><span class="cl">[remote &#34;origin&#34;]
</span></span><span class="line"><span class="cl"> url = git@github.com:Dunky-Z/Dunky-Z.github.io.git
</span></span><span class="line"><span class="cl"> fetch = +refs/heads/*:refs/remotes/origin/*
</span></span><span class="line"><span class="cl"># 以下为新增内容
</span></span><span class="line"><span class="cl">[remote &#34;review&#34;]
</span></span><span class="line"><span class="cl"> url = git@github.com:Dunky-Z/Dunky-Z.github.io.git
</span></span><span class="line"><span class="cl"> fetch = +refs/heads/*:refs/remotes/origin/*
</span></span><span class="line"><span class="cl"> push =  HEAD:refs/for/%cc=zhangsan@qq.com,
</span></span><span class="line"><span class="cl"> cc=lisi@qq.com,
</span></span><span class="line"><span class="cl"> cc=wangerma@qq.com,
</span></span><span class="line"><span class="cl"> cc=chenwu@qq.com
</span></span></code></pre></div><p>下次想要推送需要 review 的代码，就直接执行<code>git push review</code>，其中<code>push</code>就相当于：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">push HEAD:refs/for/%cc=zhangsan@qq.com,cc=lisi@qq.com,cc=wangerma@qq.com,cc=chenwu@qq.com
</span></span></code></pre></div><h2 id="参考资料">参考资料</h2>
<p><a href="https://gerrit-review.googlesource.com/Documentation/user-upload.html#push_create,">Gerrit Code Review - Uploading Changes</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>密码管理器-KeePass</title>
      <link>https://lifeislife.cn/posts/%E5%AF%86%E7%A0%81%E7%AE%A1%E7%90%86%E5%99%A8-keepass/</link>
      <pubDate>Sat, 09 Jul 2022 19:11:40 +0000</pubDate>
      <guid>https://lifeislife.cn/posts/%E5%AF%86%E7%A0%81%E7%AE%A1%E7%90%86%E5%99%A8-keepass/</guid>
      <description>&lt;h2 id=&#34;keepass-安装&#34;&gt;&lt;strong&gt;KeePass 安装&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;下载与安装&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;官网： &lt;a href=&#34;https://keepass.info/download.html&#34;&gt;https://keepass.info/download.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;下载完成后进行安装，默认安装位置是：&lt;code&gt;C:\Program Files (x86)\KeePass Password Safe 2&lt;/code&gt;文件夹下，可以根据自己需要选择安装路径。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;更改中文语言&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;中文语言包： &lt;a href=&#34;https://www.keepass.com.cn/language#:~:text=%E5%9C%A8keepass%E4%B8%AD%EF%BC%8C%E5%8D%95%E5%87%BB,%E9%87%8D%E6%96%B0%E5%90%AF%E5%8A%A8Keepass%E3%80%82&#34;&gt;KeePass-Chinese_Simplified&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;将语言包下载后复制到安装路径下的&lt;strong&gt;Languages&lt;/strong&gt;文件夹下，默认为：&lt;strong&gt;C:\Program Files (x86)\KeePass Password Safe 2\Languages。&lt;strong&gt;&lt;strong&gt;重启软件&lt;/strong&gt;&lt;/strong&gt;。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;点击 &lt;strong&gt;View&lt;/strong&gt;-&amp;gt;&lt;strong&gt;Change Language&lt;/strong&gt;. 选择中文简体（Chinese-Simplified）。&lt;strong&gt;重启软件&lt;/strong&gt;，即可完成语言更改。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091913508.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091913508.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;中文界面：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091913034.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091913034.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h2 id=&#34;基本使用&#34;&gt;&lt;strong&gt;基本使用&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;1.创建一个数据库&lt;/p&gt;
&lt;p&gt;点击 文件-》新建。弹出对话框为数据库创建管理密码。这个密码是唯一需要记忆的密码。当然如果追求更高的安全性，可以点击&lt;strong&gt;显示高级选项&lt;/strong&gt;，提供更多的密码选项。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091913919.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091913919.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;2.添加记录&lt;/p&gt;
&lt;p&gt;点击添加记录，在弹出的窗口填入相关信息。即可完成密码添加。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091914888.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091914888.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091914656.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091914656.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;如果是第一次使用的网站，第一次注册密码。可以通过密码生成器，生成一个高强度的密码来添加记录。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091914597.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091914597.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;3.创建一个密码生成模板&lt;/p&gt;
&lt;p&gt;正常国内的网站可以使用的密码长度 6-16 位，可以使用大小写，数字，下划线。我们把这些选项勾选，密码长度设置 16 位。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091915434.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091915434.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;点击保存并给模板设置个名字方便下次使用&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091915338.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091915338.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091915241.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091915241.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;如果保存后想更改一下，比如再加个可以使用空格，可以重新勾选刚刚的选项，保存时点击小三角，选择刚刚保存的方案就可以覆盖。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;导入 Chrome 已保存的密码&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;很多小伙伴在使用 KeePass 之前肯定在 Chrome 等浏览器里也保存了很多密码。想将其导入 KeePass 方便管理。Chrome 是可以导出密码的，KeePass 也可以导入密码。&lt;/p&gt;
&lt;p&gt;点击浏览器右上角，打开设置界面。找到&lt;strong&gt;密码&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091915807.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091915807.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;找到已保存的密码-》导出密码。选择方便找到的路径，保存密码记录。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091915014.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091915014.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;打开 KeePass，点击文件-》导入，选择 Chrome 浏览器的格式。点击文件夹图标找到刚刚导出的密码文件。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091916436.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091916436.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;h2 id=&#34;高级配置&#34;&gt;高级配置&lt;/h2&gt;
&lt;h3 id=&#34;keepass-搭配坚果云实现云同步&#34;&gt;&lt;strong&gt;KeePass 搭配坚果云实现云同步&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.jianguoyun.com/&#34;&gt;登录坚果云&lt;/a&gt;创建个人同步文件夹，若没有先注册。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091916293.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091916293.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;最好单独建一个专门的文件夹&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091916684.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091916684.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;将已经生成的数据库上传到这个文件夹下&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091916021.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091916021.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;点击右上角进入&lt;strong&gt;账户信息，&lt;strong&gt;点击&lt;/strong&gt;安全选项：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091916935.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091916935.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;点击添加应用&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091917760.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091917760.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;输入应用名称，应用名称只是方便区分作用，所以和要同步的应用名称一致就好：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091917877.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091917877.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;点击&lt;strong&gt;生成密码&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091917649.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091917649.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;此时云盘端配置完成，切回到 KeePass 进行客户端配置。点击&lt;strong&gt;文件&lt;/strong&gt;-》&lt;strong&gt;同步&lt;/strong&gt;-》&lt;strong&gt;与网址（URL）同步&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091917478.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091917478.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;网址：&lt;/strong&gt; &lt;a href=&#34;https://dav.jianguoyun.com/dav/&#34;&gt;https://dav.jianguoyun.com/dav/&lt;/a&gt;&lt;strong&gt;KeePass&lt;/strong&gt;/&lt;strong&gt;keepassData.kdbx&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意：红色部分是个人同步文件夹的名称，绿色部分是上传的数据库全称，一定别忘了后缀&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**用户名：**你的坚果云登录名（邮箱或者手机号）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;密码&lt;/strong&gt;：生成应用的密码，（&lt;strong&gt;不是登录坚果云的密码&lt;/strong&gt;）&lt;/p&gt;
&lt;p&gt;点击确定，此时已经可以完成同步，但是每次同步仍然需要手动确定。参考了&lt;a href=&#34;https://post.smzdm.com/p/660417/&#34;&gt;什么值得买上小乐 CSN&lt;/a&gt;的方法，通过触发器实现自动同步。&lt;/p&gt;
&lt;p&gt;触发器代码：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;utf-8&amp;#34;?&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;TriggerCollection xmlns:xsd=&amp;#34;http://www.w3.org/2001/XMLSchema&amp;#34; xmlns:xsi=&amp;#34;http://www.w3.org/2001/XMLSchema-instance&amp;#34;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &amp;lt;Triggers&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &amp;lt;Trigger&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &amp;lt;Guid&amp;gt;L2euC7Mr/EKh7nPjueuZvQ==&amp;lt;/Guid&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &amp;lt;Name&amp;gt;SaveSync&amp;lt;/Name&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &amp;lt;Events&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                &amp;lt;Event&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                        &amp;lt;TypeGuid&amp;gt;s6j9/ngTSmqcXdW6hDqbjg==&amp;lt;/TypeGuid&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                        &amp;lt;Parameters&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                &amp;lt;Parameter&amp;gt;1&amp;lt;/Parameter&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                &amp;lt;Parameter&amp;gt;kdbx&amp;lt;/Parameter&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                        &amp;lt;/Parameters&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                &amp;lt;/Event&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &amp;lt;/Events&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &amp;lt;Conditions /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &amp;lt;Actions&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                &amp;lt;Action&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                        &amp;lt;TypeGuid&amp;gt;tkamn96US7mbrjykfswQ6g==&amp;lt;/TypeGuid&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                        &amp;lt;Parameters&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                &amp;lt;Parameter&amp;gt;SaveSync&amp;lt;/Parameter&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                &amp;lt;Parameter&amp;gt;0&amp;lt;/Parameter&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                        &amp;lt;/Parameters&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                &amp;lt;/Action&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                &amp;lt;Action&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                        &amp;lt;TypeGuid&amp;gt;Iq135Bd4Tu2ZtFcdArOtTQ==&amp;lt;/TypeGuid&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                        &amp;lt;Parameters&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                &amp;lt;Parameter&amp;gt;https://dav.jianguoyun.com/dav/keePass/passwordSync.kdbx&amp;lt;/Parameter&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                &amp;lt;Parameter&amp;gt;123456&amp;lt;/Parameter&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                &amp;lt;Parameter&amp;gt;123456&amp;lt;/Parameter&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                        &amp;lt;/Parameters&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                &amp;lt;/Action&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                &amp;lt;Action&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                        &amp;lt;TypeGuid&amp;gt;tkamn96US7mbrjykfswQ6g==&amp;lt;/TypeGuid&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                        &amp;lt;Parameters&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                &amp;lt;Parameter&amp;gt;SaveSync&amp;lt;/Parameter&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                                &amp;lt;Parameter&amp;gt;1&amp;lt;/Parameter&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                        &amp;lt;/Parameters&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                &amp;lt;/Action&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &amp;lt;/Actions&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &amp;lt;/Trigger&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &amp;lt;/Triggers&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;/TriggerCollection&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;复制触发器代码，点击&lt;strong&gt;工具&lt;/strong&gt;-》&lt;strong&gt;触发器&lt;/strong&gt;，点击&lt;strong&gt;工具&lt;/strong&gt;-》&lt;strong&gt;从剪切板粘贴触发器&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091918521.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091918521.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091918858.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091918858.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091918743.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091918743.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;导入成功后，在触发器页面会多一个触发器：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091918790.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091918790.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;双击打开&lt;strong&gt;SaveSync&lt;/strong&gt;,打开最后一个&lt;strong&gt;动作&lt;/strong&gt;窗口：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091918061.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091918061.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;双击中间的条目：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091919250.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091919250.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;将信息换成同步云盘的信息：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;文件/网址：&lt;/strong&gt; &lt;a href=&#34;https://dav.jianguoyun.com/dav/&#34;&gt;https://dav.jianguoyun.com/dav/&lt;/a&gt;&lt;strong&gt;KeePass&lt;/strong&gt;/&lt;strong&gt;keepassData.kdbx&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意：红色部分是个人同步文件夹的名称，绿色部分是上传的数据库全称，一定别忘了后缀&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**IO 连接 - 用户名：**你的坚果云登录名（邮箱或者手机号）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IO 连接 - 密码&lt;/strong&gt;：生成应用的密码，（&lt;strong&gt;不是登录坚果云的密码&lt;/strong&gt;）&lt;/p&gt;
&lt;p&gt;点击确定，回到主页面，点击&lt;strong&gt;工具&lt;/strong&gt;-》&lt;strong&gt;选项&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091919251.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091919251.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;找到 &lt;strong&gt;高级&lt;/strong&gt;，向下翻，在&lt;strong&gt;文件输入/输出连接&lt;/strong&gt; 栏目里找到 &lt;strong&gt;写入数据库时使用文件交换&lt;/strong&gt; 此项不勾选&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091919398.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091919398.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;点击确定，返回主页面。此时点击保存按钮或者 Ctrl+S。即可与云盘进行同步。&lt;/p&gt;
&lt;h3 id=&#34;chrome-上使用插件实现密码自动填充与同步&#34;&gt;&lt;strong&gt;Chrome 上使用插件实现密码自动填充与同步&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;在 KeePass 客户端安装&lt;a href=&#34;https://github.com/kee-org/keepassrpc/releases&#34;&gt;KeePassRPC 插件&lt;/a&gt;：&lt;/p&gt;
&lt;p&gt;将其放入安装目录（.\KeePass\Plugins）文件夹下，退出软件，重启即可自动安装。&lt;/p&gt;
&lt;p&gt;在浏览器客户端安装&lt;a href=&#34;https://chrome.google.com/webstore/detail/kee-password-manager/mmhlniccooihdimnnjhamobppdhaolme&#34;&gt;浏览器插件&lt;/a&gt;Kee，若无法科学上网，可能需要自行百度搜索 Kee 插件&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091919168.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091919168.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;安装完成后会跳出窗口提示授权，将 KeePass 客户端跳出的窗口中的红色授权码填入即可连接浏览器：&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091920270.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091920270.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;使用 Kee&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091920016.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091920016.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;再次使用浏览器填写密码是可以看到文本框会有 logo，Kee 会自动填写已保存的密码。如果第一次登陆，在登录后可以点击浏览器插件图标，找到 Save latest login，保存刚刚输入的密码。&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091920687.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091920687.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
&lt;p&gt;密码管理器的重要作用之一就是生成高强度密码，可以用 KeePass 客户端来生成，也可以是 Kee 这个插件的一个生成密码功能生成。英文版的是&lt;strong&gt;Generate new password&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;Responsive Image&lt;/title&gt;
    &lt;style&gt;
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;div class=&#34;post-img-view&#34;&gt;
        &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091920769.png&#34;&gt;
            &lt;img class=&#34;responsive-image&#34; src=&#34;https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091920769.png&#34; alt=&#34;&#34;  style=&#34;margin: 0 auto;&#34;/&gt;
        &lt;/a&gt;
    &lt;/div&gt;
    

    &lt;script&gt;
        document.addEventListener(&#34;DOMContentLoaded&#34;, function() {
            var images = document.querySelectorAll(&#34;.responsive-image&#34;);
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + &#34;px&#34;;
            });
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;/p&gt;
</description>
      <content:encoded><![CDATA[<h2 id="keepass-安装"><strong>KeePass 安装</strong></h2>
<p><strong>下载与安装</strong></p>
<p>官网： <a href="https://keepass.info/download.html">https://keepass.info/download.html</a></p>
<p>下载完成后进行安装，默认安装位置是：<code>C:\Program Files (x86)\KeePass Password Safe 2</code>文件夹下，可以根据自己需要选择安装路径。</p>
<p><strong>更改中文语言</strong></p>
<p>中文语言包： <a href="https://www.keepass.com.cn/language#:~:text=%E5%9C%A8keepass%E4%B8%AD%EF%BC%8C%E5%8D%95%E5%87%BB,%E9%87%8D%E6%96%B0%E5%90%AF%E5%8A%A8Keepass%E3%80%82">KeePass-Chinese_Simplified</a></p>
<p>将语言包下载后复制到安装路径下的<strong>Languages</strong>文件夹下，默认为：<strong>C:\Program Files (x86)\KeePass Password Safe 2\Languages。<strong><strong>重启软件</strong></strong>。</strong></p>
<p>点击 <strong>View</strong>-&gt;<strong>Change Language</strong>. 选择中文简体（Chinese-Simplified）。<strong>重启软件</strong>，即可完成语言更改。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091913508.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091913508.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>中文界面：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091913034.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091913034.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h2 id="基本使用"><strong>基本使用</strong></h2>
<p>1.创建一个数据库</p>
<p>点击 文件-》新建。弹出对话框为数据库创建管理密码。这个密码是唯一需要记忆的密码。当然如果追求更高的安全性，可以点击<strong>显示高级选项</strong>，提供更多的密码选项。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091913919.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091913919.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>2.添加记录</p>
<p>点击添加记录，在弹出的窗口填入相关信息。即可完成密码添加。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091914888.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091914888.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091914656.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091914656.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>如果是第一次使用的网站，第一次注册密码。可以通过密码生成器，生成一个高强度的密码来添加记录。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091914597.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091914597.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>3.创建一个密码生成模板</p>
<p>正常国内的网站可以使用的密码长度 6-16 位，可以使用大小写，数字，下划线。我们把这些选项勾选，密码长度设置 16 位。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091915434.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091915434.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>点击保存并给模板设置个名字方便下次使用</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091915338.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091915338.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091915241.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091915241.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>如果保存后想更改一下，比如再加个可以使用空格，可以重新勾选刚刚的选项，保存时点击小三角，选择刚刚保存的方案就可以覆盖。</p>
<p><strong>导入 Chrome 已保存的密码</strong></p>
<p>很多小伙伴在使用 KeePass 之前肯定在 Chrome 等浏览器里也保存了很多密码。想将其导入 KeePass 方便管理。Chrome 是可以导出密码的，KeePass 也可以导入密码。</p>
<p>点击浏览器右上角，打开设置界面。找到<strong>密码</strong></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091915807.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091915807.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>找到已保存的密码-》导出密码。选择方便找到的路径，保存密码记录。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091915014.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091915014.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>打开 KeePass，点击文件-》导入，选择 Chrome 浏览器的格式。点击文件夹图标找到刚刚导出的密码文件。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091916436.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091916436.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<h2 id="高级配置">高级配置</h2>
<h3 id="keepass-搭配坚果云实现云同步"><strong>KeePass 搭配坚果云实现云同步</strong></h3>
<p><a href="https://www.jianguoyun.com/">登录坚果云</a>创建个人同步文件夹，若没有先注册。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091916293.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091916293.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>最好单独建一个专门的文件夹</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091916684.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091916684.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>将已经生成的数据库上传到这个文件夹下</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091916021.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091916021.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>点击右上角进入<strong>账户信息，<strong>点击</strong>安全选项：</strong></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091916935.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091916935.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>点击添加应用</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091917760.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091917760.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>输入应用名称，应用名称只是方便区分作用，所以和要同步的应用名称一致就好：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091917877.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091917877.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>点击<strong>生成密码</strong>：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091917649.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091917649.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>此时云盘端配置完成，切回到 KeePass 进行客户端配置。点击<strong>文件</strong>-》<strong>同步</strong>-》<strong>与网址（URL）同步</strong></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091917478.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091917478.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p><strong>网址：</strong> <a href="https://dav.jianguoyun.com/dav/">https://dav.jianguoyun.com/dav/</a><strong>KeePass</strong>/<strong>keepassData.kdbx</strong></p>
<p><strong>注意：红色部分是个人同步文件夹的名称，绿色部分是上传的数据库全称，一定别忘了后缀</strong></p>
<p>**用户名：**你的坚果云登录名（邮箱或者手机号）</p>
<p><strong>密码</strong>：生成应用的密码，（<strong>不是登录坚果云的密码</strong>）</p>
<p>点击确定，此时已经可以完成同步，但是每次同步仍然需要手动确定。参考了<a href="https://post.smzdm.com/p/660417/">什么值得买上小乐 CSN</a>的方法，通过触发器实现自动同步。</p>
<p>触发器代码：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">&lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34;?&gt;
</span></span><span class="line"><span class="cl">&lt;TriggerCollection xmlns:xsd=&#34;http://www.w3.org/2001/XMLSchema&#34; xmlns:xsi=&#34;http://www.w3.org/2001/XMLSchema-instance&#34;&gt;
</span></span><span class="line"><span class="cl">        &lt;Triggers&gt;
</span></span><span class="line"><span class="cl">                &lt;Trigger&gt;
</span></span><span class="line"><span class="cl">                        &lt;Guid&gt;L2euC7Mr/EKh7nPjueuZvQ==&lt;/Guid&gt;
</span></span><span class="line"><span class="cl">                        &lt;Name&gt;SaveSync&lt;/Name&gt;
</span></span><span class="line"><span class="cl">                        &lt;Events&gt;
</span></span><span class="line"><span class="cl">                                &lt;Event&gt;
</span></span><span class="line"><span class="cl">                                        &lt;TypeGuid&gt;s6j9/ngTSmqcXdW6hDqbjg==&lt;/TypeGuid&gt;
</span></span><span class="line"><span class="cl">                                        &lt;Parameters&gt;
</span></span><span class="line"><span class="cl">                                                &lt;Parameter&gt;1&lt;/Parameter&gt;
</span></span><span class="line"><span class="cl">                                                &lt;Parameter&gt;kdbx&lt;/Parameter&gt;
</span></span><span class="line"><span class="cl">                                        &lt;/Parameters&gt;
</span></span><span class="line"><span class="cl">                                &lt;/Event&gt;
</span></span><span class="line"><span class="cl">                        &lt;/Events&gt;
</span></span><span class="line"><span class="cl">                        &lt;Conditions /&gt;
</span></span><span class="line"><span class="cl">                        &lt;Actions&gt;
</span></span><span class="line"><span class="cl">                                &lt;Action&gt;
</span></span><span class="line"><span class="cl">                                        &lt;TypeGuid&gt;tkamn96US7mbrjykfswQ6g==&lt;/TypeGuid&gt;
</span></span><span class="line"><span class="cl">                                        &lt;Parameters&gt;
</span></span><span class="line"><span class="cl">                                                &lt;Parameter&gt;SaveSync&lt;/Parameter&gt;
</span></span><span class="line"><span class="cl">                                                &lt;Parameter&gt;0&lt;/Parameter&gt;
</span></span><span class="line"><span class="cl">                                        &lt;/Parameters&gt;
</span></span><span class="line"><span class="cl">                                &lt;/Action&gt;
</span></span><span class="line"><span class="cl">                                &lt;Action&gt;
</span></span><span class="line"><span class="cl">                                        &lt;TypeGuid&gt;Iq135Bd4Tu2ZtFcdArOtTQ==&lt;/TypeGuid&gt;
</span></span><span class="line"><span class="cl">                                        &lt;Parameters&gt;
</span></span><span class="line"><span class="cl">                                                &lt;Parameter&gt;https://dav.jianguoyun.com/dav/keePass/passwordSync.kdbx&lt;/Parameter&gt;
</span></span><span class="line"><span class="cl">                                                &lt;Parameter&gt;123456&lt;/Parameter&gt;
</span></span><span class="line"><span class="cl">                                                &lt;Parameter&gt;123456&lt;/Parameter&gt;
</span></span><span class="line"><span class="cl">                                        &lt;/Parameters&gt;
</span></span><span class="line"><span class="cl">                                &lt;/Action&gt;
</span></span><span class="line"><span class="cl">                                &lt;Action&gt;
</span></span><span class="line"><span class="cl">                                        &lt;TypeGuid&gt;tkamn96US7mbrjykfswQ6g==&lt;/TypeGuid&gt;
</span></span><span class="line"><span class="cl">                                        &lt;Parameters&gt;
</span></span><span class="line"><span class="cl">                                                &lt;Parameter&gt;SaveSync&lt;/Parameter&gt;
</span></span><span class="line"><span class="cl">                                                &lt;Parameter&gt;1&lt;/Parameter&gt;
</span></span><span class="line"><span class="cl">                                        &lt;/Parameters&gt;
</span></span><span class="line"><span class="cl">                                &lt;/Action&gt;
</span></span><span class="line"><span class="cl">                        &lt;/Actions&gt;
</span></span><span class="line"><span class="cl">                &lt;/Trigger&gt;
</span></span><span class="line"><span class="cl">        &lt;/Triggers&gt;
</span></span><span class="line"><span class="cl">&lt;/TriggerCollection&gt;
</span></span></code></pre></div><p>复制触发器代码，点击<strong>工具</strong>-》<strong>触发器</strong>，点击<strong>工具</strong>-》<strong>从剪切板粘贴触发器</strong>：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091918521.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091918521.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091918858.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091918858.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091918743.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091918743.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>导入成功后，在触发器页面会多一个触发器：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091918790.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091918790.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>双击打开<strong>SaveSync</strong>,打开最后一个<strong>动作</strong>窗口：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091918061.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091918061.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>双击中间的条目：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091919250.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091919250.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>将信息换成同步云盘的信息：</p>
<p><strong>文件/网址：</strong> <a href="https://dav.jianguoyun.com/dav/">https://dav.jianguoyun.com/dav/</a><strong>KeePass</strong>/<strong>keepassData.kdbx</strong></p>
<p><strong>注意：红色部分是个人同步文件夹的名称，绿色部分是上传的数据库全称，一定别忘了后缀</strong></p>
<p>**IO 连接 - 用户名：**你的坚果云登录名（邮箱或者手机号）</p>
<p><strong>IO 连接 - 密码</strong>：生成应用的密码，（<strong>不是登录坚果云的密码</strong>）</p>
<p>点击确定，回到主页面，点击<strong>工具</strong>-》<strong>选项</strong></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091919251.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091919251.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>找到 <strong>高级</strong>，向下翻，在<strong>文件输入/输出连接</strong> 栏目里找到 <strong>写入数据库时使用文件交换</strong> 此项不勾选</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091919398.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091919398.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>点击确定，返回主页面。此时点击保存按钮或者 Ctrl+S。即可与云盘进行同步。</p>
<h3 id="chrome-上使用插件实现密码自动填充与同步"><strong>Chrome 上使用插件实现密码自动填充与同步</strong></h3>
<p>在 KeePass 客户端安装<a href="https://github.com/kee-org/keepassrpc/releases">KeePassRPC 插件</a>：</p>
<p>将其放入安装目录（.\KeePass\Plugins）文件夹下，退出软件，重启即可自动安装。</p>
<p>在浏览器客户端安装<a href="https://chrome.google.com/webstore/detail/kee-password-manager/mmhlniccooihdimnnjhamobppdhaolme">浏览器插件</a>Kee，若无法科学上网，可能需要自行百度搜索 Kee 插件</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091919168.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091919168.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>安装完成后会跳出窗口提示授权，将 KeePass 客户端跳出的窗口中的红色授权码填入即可连接浏览器：</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091920270.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091920270.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>使用 Kee</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091920016.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091920016.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>再次使用浏览器填写密码是可以看到文本框会有 logo，Kee 会自动填写已保存的密码。如果第一次登陆，在登录后可以点击浏览器插件图标，找到 Save latest login，保存刚刚输入的密码。</p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091920687.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091920687.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
<p>密码管理器的重要作用之一就是生成高强度密码，可以用 KeePass 客户端来生成，也可以是 Kee 这个插件的一个生成密码功能生成。英文版的是<strong>Generate new password</strong></p>
<p>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Image</title>
    <style>
        .post-img-view {
            text-align: center;
        }
        .responsive-image {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    
    <div class="post-img-view">
        <a data-fancybox="gallery" href="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091920769.png">
            <img class="responsive-image" src="https://picbed-1311007548.cos.ap-shanghai.myqcloud.com/markdown_picbed/img/202207091920769.png" alt=""  style="margin: 0 auto;"/>
        </a>
    </div>
    

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var images = document.querySelectorAll(".responsive-image");
            var maxHeight = window.innerHeight / 3;
            images.forEach(function(image) {
                image.style.maxHeight = maxHeight + "px";
            });
        });
    </script>
</body>
</html></p>
]]></content:encoded>
    </item>
  </channel>
</rss>
