<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh">
  <title>红枫吟 - 技术</title>
    <subtitle>风落花语风落天，花落风雨花落田.</subtitle>
  <link href="https://honmaple.me/posts/tech/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="https://honmaple.me/posts/tech/"/>
  <generator uri="https://github.com/honmaple/snow">Snow</generator>
    <updated>Sun, 22 Feb 2026 22:20:06 +0000</updated>
  <id>https://honmaple.me</id>
    <entry xml:lang="zh">
      <title>ubuntu24.04环境配置</title>
      <link href="https://honmaple.me/posts/2026/01/ubuntu-note/" rel="alternate"></link>
      <published>Fri, 02 Jan 2026 18:51:48 +0000</published>
      <updated>Sun, 22 Feb 2026 22:20:06 +0000</updated>
      <author>
        <name>honmaple</name>
      </author>
      <link rel="alternate" href="https://honmaple.me/posts/2026/01/ubuntu-note/" type="text/html"/>
      <id>https://honmaple.me/posts/2026/01/ubuntu-note/</id>
      <summary type="html">
&lt;blockquote&gt;
&lt;p&gt;
最近我在腾讯云的服务器快过期了，但是续费又太贵，所以趁着活动又买了一台3年的轻量云。其实这台服务器上也没有什么服务，主要还是因为有一个已经备案的域名需要保一下，否则备案掉了之后再次备案太过麻烦。
&lt;/p&gt;

&lt;p&gt;
我之前的服务器还在用着 &lt;b&gt;ubuntu18.04 LTS&lt;/b&gt;，此次迁移准备升级一下系统到 &lt;b&gt;ubuntu24.04 LTS&lt;/b&gt;，故此记录
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;
注意: 以下命令以 &lt;code&gt;#&lt;/code&gt; 开头则使用的是root账户，以 &lt;code&gt;$&lt;/code&gt; 开头则为普通账户
&lt;/p&gt;

&lt;h2 id=&quot;heading-1&quot;&gt;系统设置&lt;/h2&gt;
&lt;h3 id=&quot;heading-1.1&quot;&gt;修改主机名称&lt;/h3&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;# hostnamectl set-hostname [名称]&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h3 id=&quot;heading-1.2&quot;&gt;创建新用户&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 删除已存在的用户
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;# deluser --remove-home ubuntu
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2...&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ul&gt;</summary>
      <content type="html">
&lt;blockquote&gt;
&lt;p&gt;
最近我在腾讯云的服务器快过期了，但是续费又太贵，所以趁着活动又买了一台3年的轻量云。其实这台服务器上也没有什么服务，主要还是因为有一个已经备案的域名需要保一下，否则备案掉了之后再次备案太过麻烦。
&lt;/p&gt;

&lt;p&gt;
我之前的服务器还在用着 &lt;b&gt;ubuntu18.04 LTS&lt;/b&gt;，此次迁移准备升级一下系统到 &lt;b&gt;ubuntu24.04 LTS&lt;/b&gt;，故此记录
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;
注意: 以下命令以 &lt;code&gt;#&lt;/code&gt; 开头则使用的是root账户，以 &lt;code&gt;$&lt;/code&gt; 开头则为普通账户
&lt;/p&gt;

&lt;h2 id=&quot;heading-1&quot;&gt;系统设置&lt;/h2&gt;
&lt;h3 id=&quot;heading-1.1&quot;&gt;修改主机名称&lt;/h3&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;# hostnamectl set-hostname [名称]&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h3 id=&quot;heading-1.2&quot;&gt;创建新用户&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 删除已存在的用户
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;# deluser --remove-home ubuntu
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;# deluser --remove-home lighthouse&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 添加新用户
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;# adduser myuser&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
      用户信息比如全名、房间号等，这些可以直接按 &lt;code&gt;Enter&lt;/code&gt; 跳过
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 添加sudo权限
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;# usermod -aG sudo myuser&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 添加公钥
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;# su - 用户名
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;$ mkdir ~/.ssh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;$ chmod 700 ~/.ssh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;$ vi ~/.ssh/authorized_keys
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;5&lt;/span&gt;&lt;span&gt;$ chmod 600 ~/.ssh/authorized_keys&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;heading-1.3&quot;&gt;连接数限制&lt;/h3&gt;
&lt;p&gt;
    编辑文件 &lt;code&gt;/etc/security/limits.conf&lt;/code&gt;，在文件末尾添加以下内容：
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;* soft nofile 65535
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;* hard nofile 65535
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;* soft nproc 20480
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;* hard nproc 20480&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
    注：&lt;b&gt;nofile&lt;/b&gt; 是文件打开数，&lt;b&gt;nproc&lt;/b&gt; 是最大进程数。&lt;code&gt;*&lt;/code&gt; 代表除 &lt;b&gt;root&lt;/b&gt; 外的所有用户，如果需要添加 &lt;b&gt;root&lt;/b&gt;，则增加
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;root soft nofile 65535
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;root hard nofile 65535&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h3 id=&quot;heading-1.4&quot;&gt;交换内存&lt;/h3&gt;
&lt;p&gt;
    默认的 &lt;code&gt;vm.swappiness&lt;/code&gt; 为 &lt;b&gt;60&lt;/b&gt;，表示内存使用率超过 &lt;b&gt;100%-60%=40%&lt;/b&gt; 时就开始使用交换分区
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 查看当前swappiness
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;$ cat /proc/sys/vm/swappiness&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 临时修改
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;$ sudo sysctl vm.swappiness=10
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;$ cat /proc/sys/vm/swappiness&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 永久修改
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;$ echo &amp;#34;vm.swappiness=10&amp;#34; | sudo tee -a /etc/sysctl.conf
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;$ sudo sysctl -p&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;heading-1.5&quot;&gt;启用BBR&lt;/h3&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;$ echo &amp;#34;net.core.default_qdisc=fq&amp;#34; | sudo tee -a /etc/sysctl.conf
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;$ echo &amp;#34;net.ipv4.tcp_congestion_control=bbr&amp;#34; | sudo tee -a /etc/sysctl.conf
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;$ sudo sysctl -p&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h2 id=&quot;heading-2&quot;&gt;系统服务&lt;/h2&gt;
&lt;h3 id=&quot;heading-2.1&quot;&gt;motd&lt;/h3&gt;
&lt;p&gt;
    禁用终端广告
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;sudo sed -i &amp;#39;s/ENABLED=1/ENABLED=0/&amp;#39; /etc/default/motd-news&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h3 id=&quot;heading-2.2&quot;&gt;pro&lt;/h3&gt;
&lt;p&gt;
    禁用 &lt;b&gt;pro&lt;/b&gt; 和 &lt;b&gt;esm&lt;/b&gt; 的相关提示
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;$ sudo chmod -x /etc/update-motd.d/10-help-text
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;$ sudo chmod -x /etc/update-motd.d/91-contract-ua-esm-status
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;$ sudo chmod -x /etc/update-motd.d/90-updates-available&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
    只清空，不删除文件
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;sudo truncate -s 0 /etc/apt/apt.conf.d/20apt-esm-hook.conf&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h3 id=&quot;heading-2.3&quot;&gt;ssh&lt;/h3&gt;
&lt;p&gt;
    修改配置 &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 修改端口
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;Port 22&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
      取消注释并修改为想要的端口，然后在腾讯云控制台防火墙添加放行策略
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 禁用root登陆
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;PermitRootLogin no&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
      请在添加完成&lt;b&gt;普通用户&lt;/b&gt;后再操作
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 重启服务
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;$ sudo systemctl restart ssh&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
      如果修改 &lt;code&gt;sshd_config&lt;/code&gt; 不生效
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;$ sudo systemctl stop ssh.socket
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;$ sudo systemctl disable ssh.socket
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;$ sudo systemctl restart ssh&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;heading-2.4&quot;&gt;unattended-upgrades&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 停止服务
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;$ sudo systemctl stop unattended-upgrades
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;$ sudo systemctl disable unattended-upgrades&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 卸载
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;$ sudo apt remove --purge unattended-upgrades&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;heading-2.5&quot;&gt;snap&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 停止服务
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;$ sudo systemctl stop snapd.service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;$ sudo systemctl disable snapd.service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;$ sudo systemctl mask snapd.service&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 查看已安装软件
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;$ snap list&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 卸载安装软件(把使用 &lt;b&gt;snap&lt;/b&gt; 安装的软件依次卸载)
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;$ sudo snap remove --purge [软件名称]&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 卸载 &lt;b&gt;snap&lt;/b&gt;
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;$ sudo apt autoremove --purge snapd&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
      清理目录
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;$&lt;/span&gt; sudo rm &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;rf &lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;cache&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;snapd
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;$&lt;/span&gt; sudo rm &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;rf &lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;snap
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;$&lt;/span&gt; sudo rm &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;rf &lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;lib&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;snapd&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 阻止 &lt;b&gt;snapd&lt;/b&gt; 被自动重新安装
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;$ sudo cat &amp;lt;&amp;lt;EOF | sudo tee /etc/apt/preferences.d/nosnap.pref
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;Package: snapd
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;Pin: release a=*
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;Pin-Priority: -10
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;5&lt;/span&gt;&lt;span&gt;EOF&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;heading-3&quot;&gt;其它服务&lt;/h2&gt;
&lt;h3 id=&quot;heading-3.1&quot;&gt;docker&lt;/h3&gt;
&lt;p&gt;
    官方文档: &lt;a href=&quot;https://docs.docker.com/engine/install/ubuntu/&quot;&gt;https://docs.docker.com/engine/install/ubuntu/&lt;/a&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 设置apt仓库
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;$&lt;/span&gt; sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;$&lt;/span&gt; sudo apt install ca&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;certificates curl
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;$&lt;/span&gt; sudo install &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;m &lt;span style=&quot;color:#ae81ff&quot;&gt;0755&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;d &lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;etc&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;apt&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;keyrings
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;$&lt;/span&gt; sudo curl &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;fsSL https:&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;download&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;docker&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;com&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;linux&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;ubuntu&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;gpg &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;o &lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;etc&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;apt&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;keyrings&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;docker&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;asc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 5&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;$&lt;/span&gt; sudo chmod a&lt;span style=&quot;color:#f92672&quot;&gt;+&lt;/span&gt;r &lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;etc&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;apt&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;keyrings&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;docker&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;asc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 6&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;$&lt;/span&gt; sudo tee &lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;etc&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;apt&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;sources&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;list&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;d&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;docker&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;sources &lt;span style=&quot;color:#f92672&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;EOF
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 7&lt;/span&gt;&lt;span&gt;Types: deb
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 8&lt;/span&gt;&lt;span&gt;URIs: https:&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;download&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;docker&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;com&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;linux&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;ubuntu
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 9&lt;/span&gt;&lt;span&gt;Suites: &lt;span style=&quot;color:#f92672&quot;&gt;$&lt;/span&gt;(&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;etc&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;os&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;release &lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; echo &lt;span style=&quot;color:#e6db74&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;${UBUNTU_CODENAME:-$VERSION_CODENAME}&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;10&lt;/span&gt;&lt;span&gt;Components: stable
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;11&lt;/span&gt;&lt;span&gt;Signed&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;By: &lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;etc&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;apt&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;keyrings&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;docker&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;asc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;12&lt;/span&gt;&lt;span&gt;EOF
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;13&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;$&lt;/span&gt; sudo apt update&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 安装
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;$ sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 普通用户权限
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;$ sudo usermod -aG docker [用户名]&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 镜像
      由于官方仓库无法连接，修改 &lt;code&gt;/etc/docker/daemon.json&lt;/code&gt; 添加下面配置
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#f92672&quot;&gt;&amp;#34;registry-mirrors&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;        &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;https://mirror.ccs.tencentyun.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;    ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;5&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
      然后重启docker即可
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;$ sudo systemctl restart docker&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;heading-3.2&quot;&gt;other&lt;/h3&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;$ sudo apt install tree&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h3 id=&quot;heading-3.3&quot;&gt;腾讯云组件&lt;/h3&gt;
&lt;p&gt;
    卸载腾讯云内置的组件
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;$ sudo /usr/local/qcloud/monitor/barad/admin/uninstall.sh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;$ sudo /usr/local/qcloud/stargate/admin/uninstall.sh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;$ sudo /usr/local/qcloud/YunJing/uninst.sh&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;</content>
        <category term="Linux"></category>
    </entry>
    <entry xml:lang="zh">
      <title>让Eglot支持tailwindcss以及多个LSP服务</title>
      <link href="https://honmaple.me/posts/2026/01/eglot-multi-lsp-language-server/" rel="alternate"></link>
      <published>Fri, 02 Jan 2026 00:39:44 +0000</published>
      <updated>Tue, 14 Jul 2026 16:59:40 +0000</updated>
      <author>
        <name>honmaple</name>
      </author>
      <link rel="alternate" href="https://honmaple.me/posts/2026/01/eglot-multi-lsp-language-server/" type="text/html"/>
      <id>https://honmaple.me/posts/2026/01/eglot-multi-lsp-language-server/</id>
      <summary type="html">
&lt;h2 id=&quot;heading-1&quot;&gt;前言&lt;/h2&gt;
&lt;p&gt;
   虽然我不是专业的前端开发人员，但偶尔还是会写一下 &lt;code&gt;HTML/CSS/Javascript&lt;/code&gt; 或者&lt;code&gt;Vue&lt;/code&gt;。在一个 &lt;b&gt;HTML&lt;/b&gt; 文件中，我需要使用多个 &lt;b&gt;LSP服务&lt;/b&gt;，比如使用 &lt;code&gt;vscode-html-language-server&lt;/code&gt; 补全css样式，使用&lt;code&gt;tailwindcss-language-server&lt;/code&gt; 补全tailwindcss的class名称，使用 &lt;code&gt;vscode-eslint-language-server&lt;/code&gt; 检查语法
&lt;/p&gt;

&lt;p&gt;
   但我目前使用的Emacs lSP客户端 &lt;b&gt;Eglot&lt;/b&gt; 一直不支持多个LSP服务，目前的解决方式有两种，一是把...&lt;/p&gt;</summary>
      <content type="html">
&lt;h2 id=&quot;heading-1&quot;&gt;前言&lt;/h2&gt;
&lt;p&gt;
   虽然我不是专业的前端开发人员，但偶尔还是会写一下 &lt;code&gt;HTML/CSS/Javascript&lt;/code&gt; 或者&lt;code&gt;Vue&lt;/code&gt;。在一个 &lt;b&gt;HTML&lt;/b&gt; 文件中，我需要使用多个 &lt;b&gt;LSP服务&lt;/b&gt;，比如使用 &lt;code&gt;vscode-html-language-server&lt;/code&gt; 补全css样式，使用&lt;code&gt;tailwindcss-language-server&lt;/code&gt; 补全tailwindcss的class名称，使用 &lt;code&gt;vscode-eslint-language-server&lt;/code&gt; 检查语法
&lt;/p&gt;

&lt;p&gt;
   但我目前使用的Emacs lSP客户端 &lt;b&gt;Eglot&lt;/b&gt; 一直不支持多个LSP服务，目前的解决方式有两种，一是把 &lt;b&gt;Eglot&lt;/b&gt; 更换为 &lt;b&gt;lsp-mode&lt;/b&gt; 或者 &lt;b&gt;lsp-bridge&lt;/b&gt;， 二是使用第三方命令行代理服务，比如:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;a href=&quot;https://github.com/thefrontside/lspx&quot;&gt;https://github.com/thefrontside/lspx&lt;/a&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;a href=&quot;https://github.com/joaotavora/rassumfrassum&quot;&gt;https://github.com/joaotavora/rassumfrassum&lt;/a&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
   &lt;b&gt;lspx&lt;/b&gt; 是因为我的电脑上没有相关环境，无法编译，&lt;b&gt;rass&lt;/b&gt; 是由 &lt;b&gt;Eglot&lt;/b&gt; 的作者开发，不过看情况他是准备把 &lt;b&gt;rass&lt;/b&gt; 作为一个通用的LSP代理，所以配置文件会单独放置到 &lt;b&gt;HOME&lt;/b&gt; 目录，这一点我不是很喜欢
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;
   算了，找来找去还不如自己写一个(轮子+1)，&lt;a href=&quot;https://github.com/honmaple/eglot-lspx&quot;&gt;eglot-lspx&lt;/a&gt;，一个多LSP代理服务，用于解决 &lt;b&gt;Eglot&lt;/b&gt; 无法使用 &lt;code&gt;tailwindcss&lt;/code&gt; 以及不支持多个LSP服务的问题
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;heading-2&quot;&gt;如何使用？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 编译
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;git clone https://github.com/honmaple/eglot-lspx
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;cd eglot-lspx
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;go build .&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
     然后把编译好的 &lt;code&gt;eglot-lspx&lt;/code&gt; 文件放到可执行路径下，比如我放到了 &lt;code&gt;~/.emacs.d/bin&lt;/code&gt; 目录，并添加路径到Emacs配置
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;(add-to-list &amp;#39;exec-path (expand-file-name &amp;#34;bin&amp;#34; user-emacs-directory) t)&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 配置Eglot
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;(defvar eglot-lspx-command (executable-find &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;eglot-lspx&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;(when eglot-lspx-command
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt;  (add-to-list &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;eglot-server-programs&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;`&lt;/span&gt;((web-mode :language-id &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 5&lt;/span&gt;&lt;span&gt;                                        &lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt; (&lt;span style=&quot;color:#f92672&quot;&gt;,&lt;/span&gt;eglot-lspx-command
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 6&lt;/span&gt;&lt;span&gt;                                           &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;--&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;vscode-html-language-server&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;--stdio&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 7&lt;/span&gt;&lt;span&gt;                                           &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;--&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;tailwindcss-language-server&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;--stdio&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 8&lt;/span&gt;&lt;span&gt;  (add-to-list &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;eglot-server-programs&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;`&lt;/span&gt;((vue-mode :language-id &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 9&lt;/span&gt;&lt;span&gt;                                        &lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt; (&lt;span style=&quot;color:#f92672&quot;&gt;,&lt;/span&gt;eglot-lspx-command
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;10&lt;/span&gt;&lt;span&gt;                                           &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;--&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;vue-language-server&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;--stdio&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;11&lt;/span&gt;&lt;span&gt;                                           &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;--&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;vscode-html-language-server&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;--stdio&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;12&lt;/span&gt;&lt;span&gt;                                           &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;--&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;tailwindcss-language-server&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;--stdio&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;13&lt;/span&gt;&lt;span&gt;                                           :initializationOptions
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;14&lt;/span&gt;&lt;span&gt;                                           (lambda (server) (&lt;span style=&quot;color:#a6e22e&quot;&gt;list&lt;/span&gt; :vue-language-server (eglot-volar-options server)))))))&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 合并补全信息
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;--provider completion=0,tailwindcss-language-server&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
     可以使用LSP服务名或者索引名，使用逗号分隔，索引名即第n个LSP服务，从0开始，未设置将合并全部
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;heading-3&quot;&gt;示例&lt;/h2&gt;
&lt;p&gt;
   
  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2026/01/eglot-lspx-02.png-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2026/01/eglot-lspx-02.png-thumb&quot;
         alt=&quot;eglot-lspx-02.png&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;
  &lt;link rel=&quot;stylesheet&quot; href=&quot;https://honmaple.me/libs/glightbox/glightbox.min.css&quot;&gt;
  &lt;script src=&quot;https://honmaple.me/libs/vanilla-lazyload/lazyload.min.js&quot; defer&gt;&lt;/script&gt;
  &lt;script src=&quot;https://honmaple.me/libs/glightbox/glightbox.min.js&quot; defer&gt;&lt;/script&gt;
    &lt;script src=&quot;https://honmaple.me/js/lazyload.js&quot; defer&gt;&lt;/script&gt;
    &lt;script src=&quot;https://honmaple.me/js/lightbox.js&quot; defer&gt;&lt;/script&gt;

   
  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2026/01/eglot-lspx-01.png-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2026/01/eglot-lspx-01.png-thumb&quot;
         alt=&quot;eglot-lspx-01.png&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;

&lt;/p&gt;</content>
        <category term="Tech/Linux/Emacs"></category>
    </entry>
    <entry xml:lang="zh">
      <title>关于Android模拟器无法连接网络</title>
      <link href="https://honmaple.me/posts/2025/06/guan-yu-androidmo-ni-qi-wu-fa-lian-jie-wang-luo/" rel="alternate"></link>
      <published>Tue, 03 Jun 2025 13:55:08 +0000</published>
      <updated>Sat, 02 May 2026 14:53:24 +0000</updated>
      <author>
        <name>honmaple</name>
      </author>
      <link rel="alternate" href="https://honmaple.me/posts/2025/06/guan-yu-androidmo-ni-qi-wu-fa-lian-jie-wang-luo/" type="text/html"/>
      <id>https://honmaple.me/posts/2025/06/guan-yu-androidmo-ni-qi-wu-fa-lian-jie-wang-luo/</id>
      <summary type="html">&lt;p&gt;一个很奇怪的问题，在模拟器测试安卓应用是总是显示&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;Post &amp;#34;https://xxx&amp;#34;: EOF
&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;但偶尔又变得正常，通过一番查找，原来是设置 &lt;strong&gt;Android Studio&lt;/strong&gt; 使用代理之后，通过其创建的模拟器也会默认使用代理。解决方式也很简单，只要打开模拟器设置然后取消代理即可

  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2025/06/android-studio-proxy.png-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2025/06/android-studio-proxy.png-thumb&quot;
         alt=&quot;android-studio-proxy.png&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;
  &lt;link rel=&quot;stylesheet&quot; href=&quot;https://honmaple.me/libs/glightbox/glightbox.min.css&quot;&gt;
  &lt;script src=&quot;https://honmaple.me/libs/vanilla-lazyload/lazyload.min.js&quot; defer&gt;&lt;/script&gt;
  &lt;script src=&quot;https://honmaple.me/libs/glightbox/glightbox.min.js&quot; defer&gt;&lt;/script&gt;
    &lt;script src=&quot;https://honmaple.me/js/lazyload.js&quot; defer&gt;&lt;/script&gt;
    &lt;script src=&quot;https://honmaple.me/js/lightbox.js&quot; defer&gt;&lt;/script&gt;
&lt;/p&gt;
</summary>
      <content type="html">&lt;p&gt;一个很奇怪的问题，在模拟器测试安卓应用是总是显示&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;Post &amp;#34;https://xxx&amp;#34;: EOF
&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;但偶尔又变得正常，通过一番查找，原来是设置 &lt;strong&gt;Android Studio&lt;/strong&gt; 使用代理之后，通过其创建的模拟器也会默认使用代理。解决方式也很简单，只要打开模拟器设置然后取消代理即可

  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2025/06/android-studio-proxy.png-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2025/06/android-studio-proxy.png-thumb&quot;
         alt=&quot;android-studio-proxy.png&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;
  &lt;link rel=&quot;stylesheet&quot; href=&quot;https://honmaple.me/libs/glightbox/glightbox.min.css&quot;&gt;
  &lt;script src=&quot;https://honmaple.me/libs/vanilla-lazyload/lazyload.min.js&quot; defer&gt;&lt;/script&gt;
  &lt;script src=&quot;https://honmaple.me/libs/glightbox/glightbox.min.js&quot; defer&gt;&lt;/script&gt;
    &lt;script src=&quot;https://honmaple.me/js/lazyload.js&quot; defer&gt;&lt;/script&gt;
    &lt;script src=&quot;https://honmaple.me/js/lightbox.js&quot; defer&gt;&lt;/script&gt;
&lt;/p&gt;
</content>
        <category term="Tech"></category>
    </entry>
    <entry xml:lang="zh">
      <title>Flutter实现本地化多语言</title>
      <link href="https://honmaple.me/posts/2024/10/fluttershi-xian-ben-di-hua-duo-yu-yan/" rel="alternate"></link>
      <published>Wed, 02 Oct 2024 13:12:27 +0000</published>
      <updated>Sat, 05 Oct 2024 20:13:59 +0000</updated>
      <author>
        <name>honmaple</name>
      </author>
      <link rel="alternate" href="https://honmaple.me/posts/2024/10/fluttershi-xian-ben-di-hua-duo-yu-yan/" type="text/html"/>
      <id>https://honmaple.me/posts/2024/10/fluttershi-xian-ben-di-hua-duo-yu-yan/</id>
      <summary type="html">
&lt;h2 id=&quot;heading-1&quot;&gt;内置组件本地化&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;
 添加依赖
&lt;/p&gt;

&lt;p&gt;
      Flutter默认组件的本地化只需要添加
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;flutter_localizations&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;sdk&lt;/span&gt;: &lt;span style=&quot;color:#ae81ff&quot;&gt;flutter&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
      使用命令行添加就是
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;flutter pub add flutter_localizations --sdk=flutter&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 修改入口组件 &lt;b&gt;main.dart&lt;/b&gt;
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;package:flutter_localizations/flutter_localizations.dart&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;const&lt;/span&gt; MaterialApp(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;  title: &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;Localizations Sample...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ol&gt;</summary>
      <content type="html">
&lt;h2 id=&quot;heading-1&quot;&gt;内置组件本地化&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;
 添加依赖
&lt;/p&gt;

&lt;p&gt;
      Flutter默认组件的本地化只需要添加
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;flutter_localizations&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;sdk&lt;/span&gt;: &lt;span style=&quot;color:#ae81ff&quot;&gt;flutter&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
      使用命令行添加就是
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;flutter pub add flutter_localizations --sdk=flutter&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 修改入口组件 &lt;b&gt;main.dart&lt;/b&gt;
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;package:flutter_localizations/flutter_localizations.dart&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;const&lt;/span&gt; MaterialApp(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;  title: &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;Localizations Sample App&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;  localizationsDelegates: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt;    GlobalMaterialLocalizations.delegate,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 5&lt;/span&gt;&lt;span&gt;    GlobalWidgetsLocalizations.delegate,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 6&lt;/span&gt;&lt;span&gt;    GlobalCupertinoLocalizations.delegate,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 7&lt;/span&gt;&lt;span&gt;  ],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 8&lt;/span&gt;&lt;span&gt;  supportedLocales: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 9&lt;/span&gt;&lt;span&gt;    Locale(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;en&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;), &lt;span style=&quot;color:#75715e&quot;&gt;// English
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;10&lt;/span&gt;&lt;span&gt;    Locale(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;zh&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;), &lt;span style=&quot;color:#75715e&quot;&gt;// Chinese
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;11&lt;/span&gt;&lt;span&gt;  ],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;12&lt;/span&gt;&lt;span&gt;  home: MyHomePage(),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;13&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
      这样Flutter内置组件所显示的语言就能和系统语言保持一致，如果想要手动修改，只需要添加参数
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;const&lt;/span&gt; MaterialApp(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;  ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;  locale: Locale(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;zh&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
      如果想要修改指定的组件，需要使用到 &lt;code&gt;Localizations.override&lt;/code&gt;
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;Widget build(BuildContext context) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;return&lt;/span&gt; Scaffold(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;    appBar: AppBar(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt;      title: Text(widget.title),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 5&lt;/span&gt;&lt;span&gt;    ),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 6&lt;/span&gt;&lt;span&gt;    body: Center(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 7&lt;/span&gt;&lt;span&gt;      child: Column(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 8&lt;/span&gt;&lt;span&gt;        mainAxisAlignment: MainAxisAlignment.center,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 9&lt;/span&gt;&lt;span&gt;        children: &lt;span style=&quot;color:#f92672&quot;&gt;&amp;lt;&lt;/span&gt;Widget&lt;span style=&quot;color:#f92672&quot;&gt;&amp;gt;&lt;/span&gt;[
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;10&lt;/span&gt;&lt;span&gt;          Localizations.override(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;11&lt;/span&gt;&lt;span&gt;            context: context,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;12&lt;/span&gt;&lt;span&gt;            locale: &lt;span style=&quot;color:#66d9ef&quot;&gt;const&lt;/span&gt; Locale(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;zh&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;13&lt;/span&gt;&lt;span&gt;            child: Builder(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;14&lt;/span&gt;&lt;span&gt;              builder: (context) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;15&lt;/span&gt;&lt;span&gt;                &lt;span style=&quot;color:#66d9ef&quot;&gt;return&lt;/span&gt; CalendarDatePicker(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;16&lt;/span&gt;&lt;span&gt;                  initialDate: DateTime.now(),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;17&lt;/span&gt;&lt;span&gt;                  firstDate: DateTime(&lt;span style=&quot;color:#ae81ff&quot;&gt;1900&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;18&lt;/span&gt;&lt;span&gt;                  lastDate: DateTime(&lt;span style=&quot;color:#ae81ff&quot;&gt;2100&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;19&lt;/span&gt;&lt;span&gt;                  onDateChanged: (value) {},
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;20&lt;/span&gt;&lt;span&gt;                );
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;21&lt;/span&gt;&lt;span&gt;              },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;22&lt;/span&gt;&lt;span&gt;            ),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;23&lt;/span&gt;&lt;span&gt;          ),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;24&lt;/span&gt;&lt;span&gt;        ],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;25&lt;/span&gt;&lt;span&gt;      ),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;26&lt;/span&gt;&lt;span&gt;    ),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;27&lt;/span&gt;&lt;span&gt;  );
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;28&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;heading-2&quot;&gt;自定义本地化&lt;/h2&gt;
&lt;p&gt;
   根据官方文档，可以利用 &lt;code&gt;flutter_localozations&lt;/code&gt; 和 &lt;code&gt;intl&lt;/code&gt; 来实现。但是如果根据官方文档，那可不是一般的麻烦，而是相当麻烦，操作步骤包括但不限于
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 修改 &lt;code&gt;pubsepc.yaml&lt;/code&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 添加 &lt;code&gt;l10n.yaml&lt;/code&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 添加 &lt;code&gt;.arb&lt;/code&gt; 文件
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
   当然，这一切也不能说是很麻烦，毕竟只要第一次改好，后续只用修改 &lt;code&gt;.arb&lt;/code&gt; 文件就能自动运行，但根据这个流程生成的多语言本地化，我觉得有几个问题：
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;
 自动生成的 &lt;code&gt;.dart&lt;/code&gt; 文件是保存在 &lt;code&gt;{项目目录}/.dart_tool/flutter_gen/gen_l10n&lt;/code&gt; 目录下的，这会导致项目默认的代码没有多语言相关，只有一些不知所谓的 &lt;code&gt;.arb&lt;/code&gt; 文件，毕竟与多语言相关的代码都是自动生成的
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 也是最重要的一点， 我为什么要在默认语言下重复定义一个不能带空格，只允许定义符合 &lt;b&gt;dart方法名称&lt;/b&gt; 的关键字以供调用，比如一个简单的字符串
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;Text(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;Hello World&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
      我必须在默认语言定义一个
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;// app_es.arb
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;&amp;#34;helloWorld&amp;#34;: &amp;#34;Hello World&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
      然后在其它语言定义
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;// app_zh.arb
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;&amp;#34;helloWorld&amp;#34;: &amp;#34;你好 世界&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
      最后再修改默认的调用
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;Text(AppLocations.of(context).helloWorld)&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
      我为什么不能直接使用原有的字符串呢，这样就不用再为默认的语言添加额外的翻译，比如
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;Text(AppLocations.of(context).tr(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;Hello World&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
   所以，我仔细研究了一下，大抵不用如此麻烦
&lt;/p&gt;

&lt;h2 id=&quot;heading-3&quot;&gt;自定义本地化(非代码自动生成)&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;
 首先添加 &lt;b&gt;l10n.dart&lt;/b&gt;
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;dart:async&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;package:flutter/foundation.dart&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;package:flutter/widgets.dart&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 5&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;package:flutter_localizations/flutter_localizations.dart&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 6&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;package:intl/intl.dart&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;as&lt;/span&gt; intl;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 7&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 8&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;l10n_en.dart&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 9&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;l10n_zh.dart&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;10&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;11&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;abstract&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;L10n&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;12&lt;/span&gt;&lt;span&gt;  L10n(&lt;span style=&quot;color:#66d9ef&quot;&gt;String&lt;/span&gt; locale)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;13&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;:&lt;/span&gt; localeName &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; intl.Intl.canonicalizedLocale(locale.toString());
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;14&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;15&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;final&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;String&lt;/span&gt; localeName;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;16&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;17&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;static&lt;/span&gt; L10n&lt;span style=&quot;color:#f92672&quot;&gt;?&lt;/span&gt; of(BuildContext context) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;18&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;return&lt;/span&gt; Localizations.of&lt;span style=&quot;color:#f92672&quot;&gt;&amp;lt;&lt;/span&gt;L10n&lt;span style=&quot;color:#f92672&quot;&gt;&amp;gt;&lt;/span&gt;(context, L10n);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;19&lt;/span&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;20&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;21&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;const&lt;/span&gt; LocalizationsDelegate&lt;span style=&quot;color:#f92672&quot;&gt;&amp;lt;&lt;/span&gt;L10n&lt;span style=&quot;color:#f92672&quot;&gt;&amp;gt;&lt;/span&gt; delegate &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; _L10nDelegate();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;22&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;23&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;const&lt;/span&gt; List&lt;span style=&quot;color:#f92672&quot;&gt;&amp;lt;&lt;/span&gt;LocalizationsDelegate&lt;span style=&quot;color:#f92672&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;dynamic&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;&amp;gt;&lt;/span&gt; localizationsDelegates &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;24&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;&amp;lt;&lt;/span&gt;LocalizationsDelegate&lt;span style=&quot;color:#f92672&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;dynamic&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;&amp;gt;&lt;/span&gt;[
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;25&lt;/span&gt;&lt;span&gt;    delegate,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;26&lt;/span&gt;&lt;span&gt;    GlobalMaterialLocalizations.delegate,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;27&lt;/span&gt;&lt;span&gt;    GlobalCupertinoLocalizations.delegate,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;28&lt;/span&gt;&lt;span&gt;    GlobalWidgetsLocalizations.delegate,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;29&lt;/span&gt;&lt;span&gt;  ];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;30&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;31&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;const&lt;/span&gt; List&lt;span style=&quot;color:#f92672&quot;&gt;&amp;lt;&lt;/span&gt;Locale&lt;span style=&quot;color:#f92672&quot;&gt;&amp;gt;&lt;/span&gt; supportedLocales &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;&amp;lt;&lt;/span&gt;Locale&lt;span style=&quot;color:#f92672&quot;&gt;&amp;gt;&lt;/span&gt;[
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;32&lt;/span&gt;&lt;span&gt;    Locale(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;en&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;33&lt;/span&gt;&lt;span&gt;    Locale(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;zh&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;34&lt;/span&gt;&lt;span&gt;  ];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;35&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;36&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;String&lt;/span&gt; tr(&lt;span style=&quot;color:#66d9ef&quot;&gt;String&lt;/span&gt; key);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;37&lt;/span&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;38&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;39&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;_L10nDelegate&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;extends&lt;/span&gt; LocalizationsDelegate&lt;span style=&quot;color:#f92672&quot;&gt;&amp;lt;&lt;/span&gt;L10n&lt;span style=&quot;color:#f92672&quot;&gt;&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;40&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;const&lt;/span&gt; _L10nDelegate();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;41&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;42&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;@&lt;/span&gt;override
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;43&lt;/span&gt;&lt;span&gt;  Future&lt;span style=&quot;color:#f92672&quot;&gt;&amp;lt;&lt;/span&gt;L10n&lt;span style=&quot;color:#f92672&quot;&gt;&amp;gt;&lt;/span&gt; load(Locale locale) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;44&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;return&lt;/span&gt; SynchronousFuture&lt;span style=&quot;color:#f92672&quot;&gt;&amp;lt;&lt;/span&gt;L10n&lt;span style=&quot;color:#f92672&quot;&gt;&amp;gt;&lt;/span&gt;(lookupL10n(locale));
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;45&lt;/span&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;46&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;47&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;@&lt;/span&gt;override
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;48&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;bool&lt;/span&gt; isSupported(Locale locale) &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;49&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;&amp;gt;&lt;/span&gt;[&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;en&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;, &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;zh&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;].contains(locale.languageCode);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;50&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;51&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;@&lt;/span&gt;override
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;52&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;bool&lt;/span&gt; shouldReload(_L10nDelegate old) &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;53&lt;/span&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;54&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;55&lt;/span&gt;&lt;span&gt;L10n lookupL10n(Locale locale) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;56&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#75715e&quot;&gt;// Lookup logic when only language code is specified.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;57&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;switch&lt;/span&gt; (locale.languageCode) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;58&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;case&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;en&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;59&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;return&lt;/span&gt; L10nEn();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;60&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;case&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;zh&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;61&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;return&lt;/span&gt; L10nZh();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;62&lt;/span&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;63&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;64&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;throw&lt;/span&gt; FlutterError(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;65&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;L10n.delegate failed to load unsupported locale &amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;$&lt;/span&gt;locale&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;. This is likely &lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;66&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;an issue with the localizations generation tool. Please file an issue &lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;67&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;on GitHub with a reproducible sample app and the gen-l10n configuration &lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;68&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;that was used.&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;69&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
      上述代码其实是由根据官方文档自动生成的 &lt;code&gt;.dart&lt;/code&gt; 文件转化而来
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 添加默认语言的翻译
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;// l10n_en.dart
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;l10n.dart&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;L10nEn&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;extends&lt;/span&gt; L10n {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 5&lt;/span&gt;&lt;span&gt;  L10nEn([&lt;span style=&quot;color:#66d9ef&quot;&gt;String&lt;/span&gt; locale &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;en&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;]) &lt;span style=&quot;color:#f92672&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;super&lt;/span&gt;(locale);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 6&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 7&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;@&lt;/span&gt;override
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 8&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;String&lt;/span&gt; tr(&lt;span style=&quot;color:#66d9ef&quot;&gt;String&lt;/span&gt; key) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 9&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;return&lt;/span&gt; translations[key] &lt;span style=&quot;color:#f92672&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;?&lt;/span&gt; key;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;10&lt;/span&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;11&lt;/span&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;12&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;13&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;const&lt;/span&gt; translations &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; {};&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
      对的，你没有看错， &lt;code&gt;translations&lt;/code&gt; 甚至可以是空的，这样就不用重复定义默认语言的翻译
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 添加其它语言的翻译
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;// l10n_zh.dart
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;l10n.dart&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;L10nZh&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;extends&lt;/span&gt; L10n {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 5&lt;/span&gt;&lt;span&gt;  L10nZh([&lt;span style=&quot;color:#66d9ef&quot;&gt;String&lt;/span&gt; locale &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;zh&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;]) &lt;span style=&quot;color:#f92672&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;super&lt;/span&gt;(locale);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 6&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 7&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;@&lt;/span&gt;override
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 8&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;String&lt;/span&gt; tr(&lt;span style=&quot;color:#66d9ef&quot;&gt;String&lt;/span&gt; key) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 9&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;return&lt;/span&gt; translations[key] &lt;span style=&quot;color:#f92672&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;?&lt;/span&gt; key;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;10&lt;/span&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;11&lt;/span&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;12&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;13&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;const&lt;/span&gt; translations &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;14&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;Settings&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;设置&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;15&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;Basic Settings&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;基础设置&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;16&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;Theme&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;主题&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;17&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;Language&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;语言&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;18&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;About&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;关于&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;19&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;Help&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;帮助&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;20&lt;/span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 修改 &lt;b&gt;main.dart&lt;/b&gt; 入口组件
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;app/l10n/l10n.dart&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;const&lt;/span&gt; MaterialApp(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;  title: &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;Localizations Sample App&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;5&lt;/span&gt;&lt;span&gt;  localizationsDelegates: L10n.localizationsDelegates,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;6&lt;/span&gt;&lt;span&gt;  supportedLocales: L10n.supportedLocales,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;7&lt;/span&gt;&lt;span&gt;  home: MyHomePage(),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;8&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
      这样就能使用自定义的翻译了
&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;heading-4&quot;&gt;本地化多语言的使用&lt;/h2&gt;
&lt;p&gt;
   最常用的是在 &lt;code&gt;Text&lt;/code&gt; 组件里
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;Text(L10n.of(context)&lt;span style=&quot;color:#f92672&quot;&gt;!&lt;/span&gt;.tr(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;Hello World&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
   但是所有的字符都要添加 &lt;code&gt;L10n.of(context)!&lt;/code&gt; 未免有些麻烦，所以我增加了自定义扩展
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;code&gt;BuildContext&lt;/code&gt;
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;extension L10nContext on BuildContext {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;String&lt;/span&gt; tr(&lt;span style=&quot;color:#66d9ef&quot;&gt;String&lt;/span&gt; key) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;final&lt;/span&gt; t &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; L10n.of(&lt;span style=&quot;color:#66d9ef&quot;&gt;this&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;if&lt;/span&gt; (t &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;null&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;5&lt;/span&gt;&lt;span&gt;      &lt;span style=&quot;color:#66d9ef&quot;&gt;return&lt;/span&gt; key;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;6&lt;/span&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;7&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;return&lt;/span&gt; t.tr(key);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;8&lt;/span&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;9&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
     使用方式
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;Text(context.tr(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;Hello World&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;code&gt;String&lt;/code&gt;
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;extension L10nString on &lt;span style=&quot;color:#66d9ef&quot;&gt;String&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;String&lt;/span&gt; tr(BuildContext context) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;final&lt;/span&gt; t &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; L10n.of(context);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;if&lt;/span&gt; (t &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;null&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;5&lt;/span&gt;&lt;span&gt;      &lt;span style=&quot;color:#66d9ef&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;this&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;6&lt;/span&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;7&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;return&lt;/span&gt; t.tr(&lt;span style=&quot;color:#66d9ef&quot;&gt;this&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;8&lt;/span&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;9&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
     使用方式
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;Text(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;Hello World&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;.tr(context))&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;code&gt;Text&lt;/code&gt;
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;extension L10nText on Text {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;  Text tr(BuildContext context) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;final&lt;/span&gt; t &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; L10n.of(context);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;if&lt;/span&gt; (t &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;null&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;|&lt;/span&gt; data &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;null&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 5&lt;/span&gt;&lt;span&gt;      &lt;span style=&quot;color:#66d9ef&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;this&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 6&lt;/span&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 7&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;return&lt;/span&gt; Text(t.tr(data &lt;span style=&quot;color:#f92672&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;?&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 8&lt;/span&gt;&lt;span&gt;      key: key,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 9&lt;/span&gt;&lt;span&gt;      style: style,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;10&lt;/span&gt;&lt;span&gt;      strutStyle: strutStyle,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;11&lt;/span&gt;&lt;span&gt;      textAlign: textAlign,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;12&lt;/span&gt;&lt;span&gt;      textDirection: textDirection,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;13&lt;/span&gt;&lt;span&gt;      locale: locale,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;14&lt;/span&gt;&lt;span&gt;      softWrap: softWrap,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;15&lt;/span&gt;&lt;span&gt;      overflow: overflow,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;16&lt;/span&gt;&lt;span&gt;      textScaler: textScaler,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;17&lt;/span&gt;&lt;span&gt;      maxLines: maxLines,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;18&lt;/span&gt;&lt;span&gt;      semanticsLabel: semanticsLabel,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;19&lt;/span&gt;&lt;span&gt;      textWidthBasis: textWidthBasis);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;20&lt;/span&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;21&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
     使用方式
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;Text(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;Hello World&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;).tr(context)&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
     如此，就能最大限度的较少对原有代码的侵略性修改
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;heading-5&quot;&gt;优化多语言选择&lt;/h2&gt;
&lt;p&gt;
   我这里选用的是 &lt;b&gt;riverpod&lt;/b&gt; 进行状态管理，首先定义一个本地语言的状态
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;final&lt;/span&gt; localeProvider &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; StateProvider&lt;span style=&quot;color:#f92672&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;&amp;gt;&lt;/span&gt;((ref) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;zh&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
   接着修改 &lt;b&gt;main.dart&lt;/b&gt;
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;MyApp&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;extends&lt;/span&gt; ConsumerWidget {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;const&lt;/span&gt; MyApp({&lt;span style=&quot;color:#66d9ef&quot;&gt;super&lt;/span&gt;.key});
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;@&lt;/span&gt;override
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 5&lt;/span&gt;&lt;span&gt;  Widget build(BuildContext context, WidgetRef ref) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 6&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;final&lt;/span&gt; localeCode &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; ref.watch(localeProvider);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 7&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 8&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;return&lt;/span&gt; MaterialApp(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 9&lt;/span&gt;&lt;span&gt;      locale: L10n.delegate.isSupported(localeCode) &lt;span style=&quot;color:#f92672&quot;&gt;?&lt;/span&gt; Locale(localeCode) &lt;span style=&quot;color:#f92672&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;null&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;10&lt;/span&gt;&lt;span&gt;      ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;11&lt;/span&gt;&lt;span&gt;    );
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;12&lt;/span&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;13&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
   这样就能很方便地修改应用的显示语言
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;ref.read(localeProvider.notifier).state &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;zh&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h2 id=&quot;heading-6&quot;&gt;参考文档&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;a href=&quot;https://docs.flutter.dev/ui/accessibility-and-internationalization/internationalization&quot;&gt;https://docs.flutter.dev/ui/accessibility-and-internationalization/internationalization&lt;/a&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;a href=&quot;https://docs.flutter.cn/ui/accessibility-and-internationalization/internationalization&quot;&gt;https://docs.flutter.cn/ui/accessibility-and-internationalization/internationalization&lt;/a&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
        <category term="Tech/Coding/Flutter"></category>
    </entry>
    <entry xml:lang="zh">
      <title>为maple-translate增加更友好的sdcv离线翻译</title>
      <link href="https://honmaple.me/posts/2024/04/wei-maple-translatezeng-jia-geng-you-hao-de-sdcvchi-xian-fan-yi/" rel="alternate"></link>
      <published>Mon, 22 Apr 2024 21:51:27 +0000</published>
      <updated>Mon, 22 Apr 2024 23:14:41 +0000</updated>
      <author>
        <name>honmaple</name>
      </author>
      <link rel="alternate" href="https://honmaple.me/posts/2024/04/wei-maple-translatezeng-jia-geng-you-hao-de-sdcvchi-xian-fan-yi/" type="text/html"/>
      <id>https://honmaple.me/posts/2024/04/wei-maple-translatezeng-jia-geng-you-hao-de-sdcvchi-xian-fan-yi/</id>
      <summary type="html">
&lt;blockquote&gt;
&lt;p&gt;
之前我写的Emacs翻译插件 &lt;b&gt;maple-translate&lt;/b&gt; 有一个 &lt;b&gt;sdcv&lt;/b&gt; 离线翻译的功能，它使用了 &lt;code&gt;Elisp&lt;/code&gt; 解析 &lt;b&gt;StarDict&lt;/b&gt; 的字典文件，所以不需要安装其它任何依赖。但是也是因为此原因，首次使用离线翻译需要等待字典文件加载到内存，这不是很友好，此次我将添加 &lt;b&gt;sdcv&lt;/b&gt; 二进制文件的支持，使离线翻译能够更加快捷方便
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;
首先是安装 &lt;b&gt;sdcv&lt;/b&gt; 二进制文件
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;└──╼ brew install sdcv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;└──╼ sdcv --help
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;用法：
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt;  sdcv [选项...&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;</summary>
      <content type="html">
&lt;blockquote&gt;
&lt;p&gt;
之前我写的Emacs翻译插件 &lt;b&gt;maple-translate&lt;/b&gt; 有一个 &lt;b&gt;sdcv&lt;/b&gt; 离线翻译的功能，它使用了 &lt;code&gt;Elisp&lt;/code&gt; 解析 &lt;b&gt;StarDict&lt;/b&gt; 的字典文件，所以不需要安装其它任何依赖。但是也是因为此原因，首次使用离线翻译需要等待字典文件加载到内存，这不是很友好，此次我将添加 &lt;b&gt;sdcv&lt;/b&gt; 二进制文件的支持，使离线翻译能够更加快捷方便
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;
首先是安装 &lt;b&gt;sdcv&lt;/b&gt; 二进制文件
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;└──╼ brew install sdcv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;└──╼ sdcv --help
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;用法：
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt;  sdcv [选项…]  words
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 5&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 6&lt;/span&gt;&lt;span&gt;帮助选项：
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 7&lt;/span&gt;&lt;span&gt;  -h, --help                     显示帮助选项
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 8&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 9&lt;/span&gt;&lt;span&gt;应用程序选项：
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;10&lt;/span&gt;&lt;span&gt;  -v, --version                  display version information and exit
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;11&lt;/span&gt;&lt;span&gt;  -l, --list-dicts               display list of available dictionaries and exit
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;12&lt;/span&gt;&lt;span&gt;  -u, --use-dict=bookname        for search use only dictionary with this bookname
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;13&lt;/span&gt;&lt;span&gt;  -n, --non-interactive          for use in scripts
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;14&lt;/span&gt;&lt;span&gt;  -j, --json-output              print the result formatted as JSON
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;15&lt;/span&gt;&lt;span&gt;  --json                         print the result formatted as JSON
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;16&lt;/span&gt;&lt;span&gt;  -e, --exact-search             do not fuzzy-search for similar words, only return exact matches
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;17&lt;/span&gt;&lt;span&gt;  -0, --utf8-output              output must be in utf8
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;18&lt;/span&gt;&lt;span&gt;  -1, --utf8-input               input of sdcv in utf8
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;19&lt;/span&gt;&lt;span&gt;  -2, --data-dir=path/to/dir     use this directory as path to stardict data directory
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;20&lt;/span&gt;&lt;span&gt;  -x, --only-data-dir            only use the dictionaries in data-dir, do not search in user and system directories
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;21&lt;/span&gt;&lt;span&gt;  -c, --color                    colorize the output&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
然后定义二进制文件的路径，如果 &lt;b&gt;sdcv&lt;/b&gt; 未安装，则返回为 &lt;code&gt;nil&lt;/code&gt;
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;(defvar maple-translate-sdcv-program (executable-find &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;sdcv&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
接着修改之前写好的 &lt;code&gt;maple-translate-sdcv&lt;/code&gt; 函数，通过判断 &lt;code&gt;maple-translate-sdcv-program&lt;/code&gt; 是否为空采取不同的翻译操作
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;(defun maple-translate-sdcv(word &lt;span style=&quot;color:#66d9ef&quot;&gt;&amp;amp;optional&lt;/span&gt; callback)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;Search WORD with sdcv, use async request if CALLBACK non-nil.&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;  (if maple-translate-sdcv-program
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt;      (maple-translate-execute maple-translate-sdcv-program
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 5&lt;/span&gt;&lt;span&gt;        :args (&lt;span style=&quot;color:#a6e22e&quot;&gt;append&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;&amp;#39;&lt;/span&gt;(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;-n&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;-x&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;-j&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;-0&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;-1&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;-2&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 6&lt;/span&gt;&lt;span&gt;                      (cl-loop for dict in maple-translate-sdcv-dicts
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 7&lt;/span&gt;&lt;span&gt;                               collect (&lt;span style=&quot;color:#a6e22e&quot;&gt;expand-file-name&lt;/span&gt; (&lt;span style=&quot;color:#a6e22e&quot;&gt;cdr&lt;/span&gt; dict) maple-translate-sdcv-dir))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 8&lt;/span&gt;&lt;span&gt;                      (&lt;span style=&quot;color:#a6e22e&quot;&gt;list&lt;/span&gt; word))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 9&lt;/span&gt;&lt;span&gt;        :format (maple-translate-sdcv-format)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;10&lt;/span&gt;&lt;span&gt;        :callback callback)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;11&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#75715e&quot;&gt;;; ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;12&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#75715e&quot;&gt;;; 使用ELisp解析并翻译&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;13&lt;/span&gt;&lt;span&gt;    ))&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
需要说明的是，由于该函数接收一个 &lt;code&gt;callback&lt;/code&gt; 的变量，用于处理异步翻译，如果是同步翻译，可以直接使用 &lt;code&gt;call-process&lt;/code&gt; 获取结果
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;(with-temp-buffer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;  (&lt;span style=&quot;color:#a6e22e&quot;&gt;apply&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;call-process&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;sdcv&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;nil&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;t&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;nil&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;&amp;#39;&lt;/span&gt;(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;-n&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;-x&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;-j&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;-0&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;-1&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;-2&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;/Users/xxx/.emacs.d/stardict/stardict-lazyworm-ec-2.4.2&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;word&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;  (&lt;span style=&quot;color:#a6e22e&quot;&gt;buffer-string&lt;/span&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
但如果是异步翻译，则需要使用 &lt;code&gt;start-process&lt;/code&gt; ，再通过监听进程状态在进程结束后再获取翻译结果
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;(let ((name (&lt;span style=&quot;color:#a6e22e&quot;&gt;format&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;maple-translate-process %s&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;,&lt;/span&gt;program)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;  (&lt;span style=&quot;color:#a6e22e&quot;&gt;set-process-sentinel&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;   (&lt;span style=&quot;color:#a6e22e&quot;&gt;apply&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;start-process&lt;/span&gt; name (&lt;span style=&quot;color:#a6e22e&quot;&gt;format&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;*%s*&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; name) &lt;span style=&quot;color:#f92672&quot;&gt;,&lt;/span&gt;program &lt;span style=&quot;color:#f92672&quot;&gt;,&lt;/span&gt;args)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;   (lambda(process _)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;5&lt;/span&gt;&lt;span&gt;     (unless (process-live-p process)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;6&lt;/span&gt;&lt;span&gt;       (with-current-buffer (&lt;span style=&quot;color:#a6e22e&quot;&gt;process-buffer&lt;/span&gt; process)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;7&lt;/span&gt;&lt;span&gt;         (prog1 (&lt;span style=&quot;color:#a6e22e&quot;&gt;funcall&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;,&lt;/span&gt;callback &lt;span style=&quot;color:#f92672&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;format&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;8&lt;/span&gt;&lt;span&gt;           (&lt;span style=&quot;color:#a6e22e&quot;&gt;kill-buffer&lt;/span&gt; (&lt;span style=&quot;color:#a6e22e&quot;&gt;current-buffer&lt;/span&gt;))))))))&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
这里的 &lt;b&gt;buffer&lt;/b&gt; 名称也可以通过 &lt;code&gt;(generate-new-buffer &quot; *temp*&quot; t)&lt;/code&gt; 生成一个临时 &lt;b&gt;buffer&lt;/b&gt;
&lt;/p&gt;

&lt;p&gt;
最后就是翻译结果的展示，由于输出的是多行 &lt;b&gt;json&lt;/b&gt;，比如:
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;[]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;[{&amp;#34;dict&amp;#34;: &amp;#34;懒虫简明英汉词典&amp;#34;,&amp;#34;word&amp;#34;:&amp;#34;word&amp;#34;,&amp;#34;definition&amp;#34;:&amp;#34;\n[wә:d]\nn.\n字, 词, 话, 消息, 诺言, 命令\nvt.\n为...措辞&amp;#34;}]&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
所以我在解析翻译结果时取了个巧，没有使用 &lt;code&gt;(buffer-string)&lt;/code&gt; 而是直接在 &lt;b&gt;buffer&lt;/b&gt; 里操作，每次都跳到开始位置，再依次向下移动 &lt;b&gt;n&lt;/b&gt; 行，这个 &lt;b&gt;n&lt;/b&gt; 即是字典的数量，最后使用 &lt;code&gt;(thing-at-point &#39;line t)&lt;/code&gt; 获取当前行的数据
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;(defun maple-translate-sdcv-format()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;Format result with sdcv output.&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;  (let ((results (cl-loop for index from &lt;span style=&quot;color:#ae81ff&quot;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt;                          for dicts in maple-translate-sdcv-dicts
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 5&lt;/span&gt;&lt;span&gt;                          collect
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 6&lt;/span&gt;&lt;span&gt;                          (progn
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 7&lt;/span&gt;&lt;span&gt;                            (&lt;span style=&quot;color:#a6e22e&quot;&gt;goto-char&lt;/span&gt; (&lt;span style=&quot;color:#a6e22e&quot;&gt;point-min&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 8&lt;/span&gt;&lt;span&gt;                            (&lt;span style=&quot;color:#a6e22e&quot;&gt;forward-line&lt;/span&gt; index)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 9&lt;/span&gt;&lt;span&gt;                            (string-join (cl-loop for child across-ref (json-read-from-string (&lt;span style=&quot;color:#a6e22e&quot;&gt;decode-coding-string&lt;/span&gt; (thing-at-point &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;line&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;t&lt;/span&gt;) &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;utf-8&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;10&lt;/span&gt;&lt;span&gt;                                                  collect (&lt;span style=&quot;color:#a6e22e&quot;&gt;format&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;%s: %s&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;11&lt;/span&gt;&lt;span&gt;                                                                  (alist-get &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;dict&lt;/span&gt; child)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;12&lt;/span&gt;&lt;span&gt;                                                                  (alist-get &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;definition&lt;/span&gt; child)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;13&lt;/span&gt;&lt;span&gt;                                         &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;)))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;14&lt;/span&gt;&lt;span&gt;    (unless (&lt;span style=&quot;color:#a6e22e&quot;&gt;null&lt;/span&gt; results)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;15&lt;/span&gt;&lt;span&gt;      (string-join (cl-remove &lt;span style=&quot;color:#66d9ef&quot;&gt;nil&lt;/span&gt; results) &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;))))&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
最终效果
&lt;/p&gt;
&lt;video width=&quot;100%&quot; controls&gt;
  &lt;source src=&quot;https://s.libforest.com/images/2024/04/maple-translate-sdcv.mov&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;p&gt;
&lt;b&gt;maple-translate&lt;/b&gt;的具体修改可见: &lt;a href=&quot;https://github.com/honmaple/emacs-maple-translate/commit/dfd0eae6486d62c26a3fa3fb07ee7e5f4640eb16&quot;&gt;dfd0eae&lt;/a&gt;
&lt;/p&gt;</content>
        <category term="Tech/Linux/Emacs"></category>
    </entry>
    <entry xml:lang="zh">
      <title>使用Homebrew Tap发布个人工具</title>
      <link href="https://honmaple.me/posts/2024/03/shi-yong-homebrew-tapfa-bu-ge-ren-gong-ju/" rel="alternate"></link>
      <published>Thu, 28 Mar 2024 09:31:23 +0000</published>
      <updated>Wed, 09 Oct 2024 10:35:59 +0000</updated>
      <author>
        <name>honmaple</name>
      </author>
      <link rel="alternate" href="https://honmaple.me/posts/2024/03/shi-yong-homebrew-tapfa-bu-ge-ren-gong-ju/" type="text/html"/>
      <id>https://honmaple.me/posts/2024/03/shi-yong-homebrew-tapfa-bu-ge-ren-gong-ju/</id>
      <summary type="html">
&lt;blockquote&gt;
&lt;p&gt;
作为MacOS用户，&lt;b&gt;Homebrew&lt;/b&gt; 是必不可少的工具之一，正如它的描述所示 &lt;code&gt;The missing package manager for macOS&lt;/code&gt; —— 它提供了很多 &lt;b&gt;App Store&lt;/b&gt; 没有的软件和工具。
&lt;/p&gt;

&lt;p&gt;
而什么是 &lt;b&gt;Tap&lt;/b&gt;？&lt;b&gt;Tap&lt;/b&gt; 全称 &lt;code&gt;Third-Party Repositories&lt;/code&gt;，顾名思义为第三方仓库，它可以创建属于自己的软件集合，不用将软件发布到官方仓库，避免了和官方仓库的其它软件同名，也不用发PR，等审核等诸多优势。此次，我将创建一个 &lt;b&gt;Homebrew Tap&lt;/b&gt;，用于为我自己开发的部分软件和工具提供更加方便的安装方式。
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;heading-1&quot;&gt;创建Tap&lt;/h2&gt;
&lt;p&gt;
   使用 &lt;code&gt;brew&lt;/code&gt; 命令创建...&lt;/p&gt;</summary>
      <content type="html">
&lt;blockquote&gt;
&lt;p&gt;
作为MacOS用户，&lt;b&gt;Homebrew&lt;/b&gt; 是必不可少的工具之一，正如它的描述所示 &lt;code&gt;The missing package manager for macOS&lt;/code&gt; —— 它提供了很多 &lt;b&gt;App Store&lt;/b&gt; 没有的软件和工具。
&lt;/p&gt;

&lt;p&gt;
而什么是 &lt;b&gt;Tap&lt;/b&gt;？&lt;b&gt;Tap&lt;/b&gt; 全称 &lt;code&gt;Third-Party Repositories&lt;/code&gt;，顾名思义为第三方仓库，它可以创建属于自己的软件集合，不用将软件发布到官方仓库，避免了和官方仓库的其它软件同名，也不用发PR，等审核等诸多优势。此次，我将创建一个 &lt;b&gt;Homebrew Tap&lt;/b&gt;，用于为我自己开发的部分软件和工具提供更加方便的安装方式。
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;heading-1&quot;&gt;创建Tap&lt;/h2&gt;
&lt;p&gt;
   使用 &lt;code&gt;brew&lt;/code&gt; 命令创建
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;└──╼ brew tap-new honmaple/tap
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/honmaple/homebrew-tap/.git/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;[main (root-commit) 7d893ca] Create honmaple/tap tap
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt; 3 files changed, 90 insertions(+)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 5&lt;/span&gt;&lt;span&gt; create mode 100644 .github/workflows/publish.yml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 6&lt;/span&gt;&lt;span&gt; create mode 100644 .github/workflows/tests.yml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 7&lt;/span&gt;&lt;span&gt; create mode 100644 README.md
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 8&lt;/span&gt;&lt;span&gt;==&amp;gt; Created honmaple/tap
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 9&lt;/span&gt;&lt;span&gt;/usr/local/Homebrew/Library/Taps/honmaple/homebrew-tap
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;10&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;11&lt;/span&gt;&lt;span&gt;When a pull request making changes to a formula (or formulae) becomes green
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;12&lt;/span&gt;&lt;span&gt;(all checks passed), then you can publish the built bottles.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;13&lt;/span&gt;&lt;span&gt;To do so, label your PR as `pr-pull` and the workflow will be triggered.&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
   创建后会提示在 &lt;code&gt;/usr/local/Homebrew/Library/Taps/honmaple/homebrew-tap/&lt;/code&gt; 目录生成一个 &lt;b&gt;Git&lt;/b&gt; 仓库
&lt;/p&gt;

&lt;h2 id=&quot;heading-2&quot;&gt;生成模版&lt;/h2&gt;
&lt;p&gt;
   比如我想要为已经打包好的工具 &lt;b&gt;Snow 0.1.2&lt;/b&gt; 生成模版，注意指定 &lt;code&gt;--tap&lt;/code&gt; 参数
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;└&lt;/span&gt;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;─&lt;/span&gt;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;─&lt;/span&gt;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;╼&lt;/span&gt; brew create https:&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;github&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;com&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;honmaple&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;snow&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;releases&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;download&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;v0&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#ae81ff&quot;&gt;1.2&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;snow&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;darwin&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;tar&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;gz &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;tap honmaple&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;tap
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;Formula name [snow]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
   在输入提示的工具名称后（也可以保持默认），这时会生成并使用默认编辑器打开 &lt;code&gt;/usr/local/Homebrew/Library/Taps/honmaple/homebrew-tap/Formula/snow.rb&lt;/code&gt;，内容如下:
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;# Documentation: https://docs.brew.sh/Formula-Cookbook&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;#                https://rubydoc.brew.sh/Formula&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;# PLEASE REMOVE ALL GENERATED COMMENTS BEFORE SUBMITTING YOUR PULL REQUEST!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;Snow&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;Formula&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 5&lt;/span&gt;&lt;span&gt;  desc &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;static site generator&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 6&lt;/span&gt;&lt;span&gt;  homepage &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 7&lt;/span&gt;&lt;span&gt;  url &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;https://github.com/honmaple/snow/releases/download/v0.1.2/snow-darwin.tar.gz&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 8&lt;/span&gt;&lt;span&gt;  sha256 &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;78a65c740eff24193132e063654bd1d7023f6687c94ce852e50a03a43eaba558&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 9&lt;/span&gt;&lt;span&gt;  license &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;BSD-3-Clause&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;10&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;11&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#75715e&quot;&gt;# depends_on &amp;#34;cmake&amp;#34; =&amp;gt; :build&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;12&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;13&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;install&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;14&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#75715e&quot;&gt;# Remove unrecognized options if they cause configure to fail&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;15&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#75715e&quot;&gt;# https://rubydoc.brew.sh/Formula.html#std_configure_args-instance_method&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;16&lt;/span&gt;&lt;span&gt;    system &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;./configure&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;, &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;--disable-silent-rules&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;, &lt;span style=&quot;color:#f92672&quot;&gt;*&lt;/span&gt;std_configure_args
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;17&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#75715e&quot;&gt;# system &amp;#34;cmake&amp;#34;, &amp;#34;-S&amp;#34;, &amp;#34;.&amp;#34;, &amp;#34;-B&amp;#34;, &amp;#34;build&amp;#34;, *std_cmake_args&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;18&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;19&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;20&lt;/span&gt;&lt;span&gt;  test &lt;span style=&quot;color:#66d9ef&quot;&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;21&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#75715e&quot;&gt;# `test do` will create, run in and delete a temporary directory.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;22&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#75715e&quot;&gt;# ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;23&lt;/span&gt;&lt;span&gt;    system &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;24&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;25&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h2 id=&quot;heading-3&quot;&gt;修改模版&lt;/h2&gt;
&lt;p&gt;
   因为我此次发布的只是一个 &lt;b&gt;Go&lt;/b&gt; 编译的二进制文件，只用将文件添加到可执行目录即可。如需其它操作，请查阅&lt;a href=&quot;https://docs.brew.sh/Taps&quot;&gt;Homebrew Tap官方文档&lt;/a&gt;。
&lt;/p&gt;

&lt;p&gt;
   修改模版后内容如下：
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;Snow&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;Formula&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;  homepage &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;https://github.com/honmaple/snow&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;  desc &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;static site generator&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt;  url &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;https://github.com/honmaple/snow/releases/download/v0.1.2/snow-darwin.tar.gz&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 5&lt;/span&gt;&lt;span&gt;  sha256 &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;78a65c740eff24193132e063654bd1d7023f6687c94ce852e50a03a43eaba558&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 6&lt;/span&gt;&lt;span&gt;  license &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;BSD-3-Clause&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 7&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 8&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;install&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 9&lt;/span&gt;&lt;span&gt;    bin&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;install &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;snow&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;10&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;11&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;12&lt;/span&gt;&lt;span&gt;  test &lt;span style=&quot;color:#66d9ef&quot;&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;13&lt;/span&gt;&lt;span&gt;    assert_match &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;snow version &lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;#{&lt;/span&gt;version&lt;span style=&quot;color:#e6db74&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;, shell_output(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;#{&lt;/span&gt;bin&lt;span style=&quot;color:#e6db74&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;/snow --version&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;14&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;15&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
   从模版文件中就能看出，如果我们需要发布下一版本，只需要修改 &lt;code&gt;url&lt;/code&gt; 和 &lt;code&gt;sha256&lt;/code&gt; 两个参数，其中 &lt;code&gt;sha256&lt;/code&gt; 可以使用 &lt;code&gt;sha256sum v0.1.2/snow-darwin.tar.gz&lt;/code&gt; 获得
&lt;/p&gt;

&lt;h2 id=&quot;heading-4&quot;&gt;安装软件&lt;/h2&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;brew install honmaple/tap/snow&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
   &lt;b&gt;注意&lt;/b&gt;：不能直接使用 &lt;code&gt;brew install snow&lt;/code&gt;，因为如果在 &lt;code&gt;homebrew/core&lt;/code&gt; 有相同名称的包，默认将会安装 &lt;code&gt;homebrew/core&lt;/code&gt; 上的包，所以必须指明使用哪个 &lt;b&gt;Tap&lt;/b&gt;
&lt;/p&gt;

&lt;h2 id=&quot;heading-5&quot;&gt;上传到Github&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;
 首先需要到 &lt;b&gt;Github&lt;/b&gt; 创建一个公共仓库，取名 &lt;code&gt;homebrew-{Tap名称}&lt;/code&gt;, 比如我的是 &lt;code&gt;honmaple/homebrew-tap&lt;/code&gt;，注意名称必须是 &lt;code&gt;homebrew-&lt;/code&gt; 开头，方便后续直接使用 &lt;code&gt;{用户名}/{Tap名称}&lt;/code&gt;。创建好后先不要克隆到本地
      
  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2024/03/homebrew-tap-01.jpg-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2024/03/homebrew-tap-01.jpg-thumb&quot;
         alt=&quot;homebrew-tap-01.jpg&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;
  &lt;link rel=&quot;stylesheet&quot; href=&quot;https://honmaple.me/libs/glightbox/glightbox.min.css&quot;&gt;
  &lt;script src=&quot;https://honmaple.me/libs/vanilla-lazyload/lazyload.min.js&quot; defer&gt;&lt;/script&gt;
  &lt;script src=&quot;https://honmaple.me/libs/glightbox/glightbox.min.js&quot; defer&gt;&lt;/script&gt;
    &lt;script src=&quot;https://honmaple.me/js/lazyload.js&quot; defer&gt;&lt;/script&gt;
    &lt;script src=&quot;https://honmaple.me/js/lightbox.js&quot; defer&gt;&lt;/script&gt;

&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 复制之前创建好的 &lt;code&gt;honmaple/tap&lt;/code&gt; 目录，方便后续维护
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;cp -r /usr/local/Homebrew/Library/Taps/honmaple/homebrew-tap ~/Git/&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 修改仓库
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;cd ~/Git/homebrew-tap
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;# 删除默认的Github Action
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;rm -rf .github
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;# 添加远程
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;5&lt;/span&gt;&lt;span&gt;git remote add origin git@github.com:honmaple/homebrew-tap.git
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;6&lt;/span&gt;&lt;span&gt;# 添加软件
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;7&lt;/span&gt;&lt;span&gt;git add Formula/snow.rb
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;8&lt;/span&gt;&lt;span&gt;git commit -m &amp;#34;add snow.rb&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;9&lt;/span&gt;&lt;span&gt;git push origin master&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 重置本地tap，首先需要卸载之前创建好的 &lt;code&gt;honmaple/tap&lt;/code&gt;
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;brew untap honmaple/tap&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
      如果已经安装了 &lt;code&gt;homebrew/tap/snow&lt;/code&gt;, 需要先卸载
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;brew uninstall honmaple/tap/snow&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
      在执行完 &lt;b&gt;修改仓库&lt;/b&gt; 这一步后，就可以重新添加 &lt;b&gt;tap&lt;/b&gt;
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;brew tap honmaple/tap&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
      并重新安装想要的软件
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;brew install honample/tap/snow&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;heading-6&quot;&gt;结语&lt;/h2&gt;
&lt;p&gt;
   至此，创建一个私人使用的 MacOS 软件包集合就此结束，我可以往里面添加一些自己写的软件和工具，可以是 &lt;b&gt;Bash&lt;/b&gt; 脚本，也可以是 &lt;b&gt;Go&lt;/b&gt; 编译好的二进制等，后面就不用再指定具体目录或者手动复制文件到 &lt;code&gt;$PATH/bin&lt;/code&gt; 目录下了。OK
&lt;/p&gt;</content>
        <category term="Tech"></category>
    </entry>
    <entry xml:lang="zh">
      <title>使用Go重写MetingJS的API</title>
      <link href="https://honmaple.me/posts/2023/12/shi-yong-gozhong-xie-metingjsde-api/" rel="alternate"></link>
      <published>Tue, 26 Dec 2023 13:23:00 +0000</published>
      <updated>Thu, 09 Jul 2026 01:46:12 +0000</updated>
      <author>
        <name>honmaple</name>
      </author>
      <link rel="alternate" href="https://honmaple.me/posts/2023/12/shi-yong-gozhong-xie-metingjsde-api/" type="text/html"/>
      <id>https://honmaple.me/posts/2023/12/shi-yong-gozhong-xie-metingjsde-api/</id>
      <summary type="html">
&lt;blockquote&gt;
&lt;p&gt;
&lt;b&gt;MetingJS&lt;/b&gt; 是一款通过获取网易云音乐或者QQ音乐等服务的歌单、歌手、歌曲、歌词等信息，然后使用开源HTML5播放器 &lt;b&gt;APlayer&lt;/b&gt; 进行播放的插件。而 &lt;b&gt;MetingJS&lt;/b&gt; 是一段很小的JS代码，它提供了一个默认的API接口：&lt;a href=&quot;https://api.i-meto.com/meting/api&quot;&gt;https://api.i-meto.com/meting/api&lt;/a&gt; , 但很不幸，该接口偶尔会出问题，作者也很久没有回复issue了。
&lt;/p&gt;

&lt;p&gt;
现在也有一个开源的 &lt;a href=&quot;https://github.com/injahow/meting-api&quot;&gt;injahow/meting-api&lt;/a&gt;，该服务同样使用PHP编写，我不太懂PHP，我只是想要设置一个缓存，来缓存所有的歌曲信息，而不仅仅是歌单列表，另外是可以支持内存缓存和本地磁盘缓存，而不是直接从本地文件中读取。
&lt;/p&gt;

&lt;p&gt;
基于此，与其自己改不是太懂的PHP，说不定会出现一些意想不到的漏洞...&lt;/p&gt;&lt;/blockquote&gt;</summary>
      <content type="html">
&lt;blockquote&gt;
&lt;p&gt;
&lt;b&gt;MetingJS&lt;/b&gt; 是一款通过获取网易云音乐或者QQ音乐等服务的歌单、歌手、歌曲、歌词等信息，然后使用开源HTML5播放器 &lt;b&gt;APlayer&lt;/b&gt; 进行播放的插件。而 &lt;b&gt;MetingJS&lt;/b&gt; 是一段很小的JS代码，它提供了一个默认的API接口：&lt;a href=&quot;https://api.i-meto.com/meting/api&quot;&gt;https://api.i-meto.com/meting/api&lt;/a&gt; , 但很不幸，该接口偶尔会出问题，作者也很久没有回复issue了。
&lt;/p&gt;

&lt;p&gt;
现在也有一个开源的 &lt;a href=&quot;https://github.com/injahow/meting-api&quot;&gt;injahow/meting-api&lt;/a&gt;，该服务同样使用PHP编写，我不太懂PHP，我只是想要设置一个缓存，来缓存所有的歌曲信息，而不仅仅是歌单列表，另外是可以支持内存缓存和本地磁盘缓存，而不是直接从本地文件中读取。
&lt;/p&gt;

&lt;p&gt;
基于此，与其自己改不是太懂的PHP，说不定会出现一些意想不到的漏洞(源自某安全公司多次CTF换来的教训)，不如使用熟悉的Go重写实现，毕竟核心代码也不是太多
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;heading-1&quot;&gt;功能&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 支持网易云音乐，QQ音乐
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 支持新服务接口扩展
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 支持所有请求结果的缓存
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 更方便的配置(环境变量+配置文件)，而不用修改源文件
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 基于 &lt;b&gt;Go&lt;/b&gt; 编写，一次编译，到处运行
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;heading-2&quot;&gt;使用&lt;/h2&gt;
&lt;h3 id=&quot;heading-2.1&quot;&gt;手动部署&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 下载仓库
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;git clone https://github.com/honmaple/meting-api&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 编译可执行文件
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;go mod download
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;go build &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;o meting&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;api &lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
      或者使用 &lt;b&gt;Docker&lt;/b&gt; 进行编译, 编译后的文件在 &lt;code&gt;/usr/bin/meting-api&lt;/code&gt;
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;docker build -t meting-api .&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 运行
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;./meting-api -D&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;heading-2.2&quot;&gt;Docker部署&lt;/h3&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;docker run --name meting-api --restart=always -d -p 8000:8000 -v /tmp/meting-cache:/opt/meting-api/cache honmaple/meting-api&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;h3 id=&quot;heading-2.3&quot;&gt;配置说明&lt;/h3&gt;
&lt;p&gt;
    配置可以使用环境变量或者配置文件设置
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 环境变量: 使用 &lt;code&gt;METING_XXXX&lt;/code&gt;, 比如 &lt;code&gt;METING_CACHE_TTL&lt;/code&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 配置文件: 默认使用当前目录下的 &lt;code&gt;config.yaml&lt;/code&gt;, 如果使用 &lt;b&gt;Docker&lt;/b&gt; 部署，需要文件挂载到 &lt;code&gt;/opt/meting-api/config.yaml&lt;/code&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 具体配置:
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;# 缓存过期时间&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;cache.ttl&lt;/span&gt;:                  &lt;span style=&quot;color:#ae81ff&quot;&gt;3600&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;# 缓存路径，设置为空是禁用缓存&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;cache.path&lt;/span&gt;:                 &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;./cache&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 5&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;# 是否激活缓存&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 6&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;cache.enabled&lt;/span&gt;:              &lt;span style=&quot;color:#66d9ef&quot;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 7&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 8&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;# 服务监听地址，:8000 表示监听 0.0.0.0:8000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 9&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;server.addr&lt;/span&gt;:                &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;:8000&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;10&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;# 对外服务地址，比如 https://api.xxxx.com/meting&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;11&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;server.host&lt;/span&gt;:                &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;12&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;13&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;## cors设置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;14&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;server.cors.allow_headers&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;15&lt;/span&gt;&lt;span&gt;  - &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;*&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;16&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;server.cors.allow_origins&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;17&lt;/span&gt;&lt;span&gt;  - &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;*&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;18&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;server.cors.allow_methods&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;19&lt;/span&gt;&lt;span&gt;  - &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;*&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;20&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;21&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;# 日志相关, out可选stdout,stderr,file，或者使用|分隔多个，比如stderr|file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;22&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;logger.out&lt;/span&gt;:                 &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;stdout&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;23&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;# 日志级别&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;24&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;logger.level&lt;/span&gt;:               &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;info&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;25&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;# 日志文件名格式&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;26&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;logger.file_format&lt;/span&gt;:         &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;%Y%m%d&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;27&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;# 日志文件保留数量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;28&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;logger.file_rotation_count&lt;/span&gt;: &lt;span style=&quot;color:#ae81ff&quot;&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;heading-2.4&quot;&gt;命令行参数&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 查看支持的服务
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;./meting-api --list&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 指定监听地址
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;./meting-api -a :8001
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;./meting-api --addr :8001&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 显示请求记录
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;./meting-api -D
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;./meting-api --debug&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 指定配置文件
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;./meting-api -c /etc/meting.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;./meting-api --config /etc/meting.yaml&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 显示当前配置
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;./meting-api config&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 删除指定缓存
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;./meting-api delete-cache &amp;#39;server:netease:type:${type}:id:${id}&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;heading-2.5&quot;&gt;网页端设置&lt;/h3&gt;
&lt;p&gt;
    其中 &lt;code&gt;http://localhost:8000/&lt;/code&gt; 是对外服务的接口
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;span style=&quot;color:#f92672&quot;&gt;meting-js&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#a6e22e&quot;&gt;server&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;netease&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#a6e22e&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;artist&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#a6e22e&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;6452&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 5&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;span style=&quot;color:#f92672&quot;&gt;meting-js&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 6&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;span style=&quot;color:#f92672&quot;&gt;script&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;text/javascript&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 7&lt;/span&gt;&lt;span&gt;  &lt;span style=&quot;color:#66d9ef&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;meting&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;_api&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;http://localhost:8000/?server=:server&amp;amp;type=:type&amp;amp;id=:id&amp;amp;auth=:auth&amp;amp;r=:r&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 8&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;span style=&quot;color:#f92672&quot;&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 9&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;span style=&quot;color:#f92672&quot;&gt;script&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;src&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&quot;color:#f92672&quot;&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;10&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;span style=&quot;color:#f92672&quot;&gt;script&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;src&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;https://cdn.jsdelivr.net/npm/meting@2/dist/Meting.min.js&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&quot;color:#f92672&quot;&gt;script&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h2 id=&quot;heading-3&quot;&gt;演示&lt;/h2&gt;
   
  &lt;meting-js
    id=&quot;9085878380&quot;
    type=&quot;playlist&quot;
    server=&quot;netease&quot;
    preload=&quot;none&quot;
    api=&quot;https://api.honmaple.com/meting?server=:server&amp;type=:type&amp;id=:id&amp;auth=:auth&amp;r=:r&quot;&gt;&lt;/meting-js&gt;
    &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css&quot;&gt;
    &lt;script src=&quot;https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js&quot; defer&gt;&lt;/script&gt;
    &lt;script src=&quot;https://cdn.jsdelivr.net/npm/meting@2/dist/Meting.min.js&quot; defer&gt;&lt;/script&gt;
</content>
        <category term="Tech"></category>
    </entry>
    <entry xml:lang="zh">
      <title>重复造轮子之Emacs翻译插件maple-translate</title>
      <link href="https://honmaple.me/posts/2023/11/zhong-fu-zao-lun-zi-zhi-emacsfan-yi-cha-jian-maple-translate/" rel="alternate"></link>
      <published>Fri, 03 Nov 2023 22:19:03 +0000</published>
      <updated>Wed, 15 Nov 2023 15:21:38 +0000</updated>
      <author>
        <name>honmaple</name>
      </author>
      <link rel="alternate" href="https://honmaple.me/posts/2023/11/zhong-fu-zao-lun-zi-zhi-emacsfan-yi-cha-jian-maple-translate/" type="text/html"/>
      <id>https://honmaple.me/posts/2023/11/zhong-fu-zao-lun-zi-zhi-emacsfan-yi-cha-jian-maple-translate/</id>
      <summary type="html">
&lt;blockquote&gt;
&lt;p&gt;
我之前一直都在使用 &lt;a href=&quot;https://github.com/xuchunyang/youdao-dictionary.el&quot;&gt;youdao-dictionary&lt;/a&gt; 这个插件，虽然没有配置过秘钥，这时会有使用次数的限制(反正是每天1000次还是多少来着，有些忘了)，但是我平时使用次数不多，所以也不会达到使用限制，不管是单词翻译还是长句翻译都很不错。但最近几个月 &lt;b&gt;youdao-dictionary&lt;/b&gt; 如果不配置私钥，处于一个完全不可用的状态。
&lt;/p&gt;

&lt;p&gt;
我曾寻找过它的替代品，并且使用过一段时间的 &lt;a href=&quot;https://github.com/condy0919/fanyi.el&quot;&gt;fanyi.el&lt;/a&gt;，不可否认，这同样是一个非常不错的插件，不管是UI还是功能，但是，可能是因为 &lt;b&gt;fanyi.el&lt;/b&gt; 使用异步请求的原因，偶尔会出现一些意想不到的报错，更重要的是它不支持长句翻译和离线翻译。
&lt;/p&gt;

&lt;p&gt;
考虑再三，还是决定自己造一个轮子，主要功能就按照我之前使用 &lt;b&gt;youdao-dictionary&lt;/b&gt; 的习惯...&lt;/p&gt;&lt;/blockquote&gt;</summary>
      <content type="html">
&lt;blockquote&gt;
&lt;p&gt;
我之前一直都在使用 &lt;a href=&quot;https://github.com/xuchunyang/youdao-dictionary.el&quot;&gt;youdao-dictionary&lt;/a&gt; 这个插件，虽然没有配置过秘钥，这时会有使用次数的限制(反正是每天1000次还是多少来着，有些忘了)，但是我平时使用次数不多，所以也不会达到使用限制，不管是单词翻译还是长句翻译都很不错。但最近几个月 &lt;b&gt;youdao-dictionary&lt;/b&gt; 如果不配置私钥，处于一个完全不可用的状态。
&lt;/p&gt;

&lt;p&gt;
我曾寻找过它的替代品，并且使用过一段时间的 &lt;a href=&quot;https://github.com/condy0919/fanyi.el&quot;&gt;fanyi.el&lt;/a&gt;，不可否认，这同样是一个非常不错的插件，不管是UI还是功能，但是，可能是因为 &lt;b&gt;fanyi.el&lt;/b&gt; 使用异步请求的原因，偶尔会出现一些意想不到的报错，更重要的是它不支持长句翻译和离线翻译。
&lt;/p&gt;

&lt;p&gt;
考虑再三，还是决定自己造一个轮子，主要功能就按照我之前使用 &lt;b&gt;youdao-dictionary&lt;/b&gt; 的习惯:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;
 翻译光标下的单词，以及选中的单词或句子
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 翻译的内容输出到 &lt;code&gt;echoarea&lt;/code&gt; 或者新的 &lt;code&gt;buffer&lt;/code&gt;，方便复制
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 增加一个离线翻译的功能，并且可以不依赖外部工具
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;
基于上述，所以有了这个新的轮子 &lt;a href=&quot;https://github.com/honmaple/emacs-maple-translate&quot;&gt;maple-translate&lt;/a&gt;
&lt;/p&gt;

&lt;h2 id=&quot;heading-1&quot;&gt;如何使用?&lt;/h2&gt;
&lt;p&gt;
   可以使用 &lt;b&gt;quelpa&lt;/b&gt; 安装
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;(use-package maple-translate
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;  :quelpa (:fetcher github :repo &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;honmaple/emacs-maple-translate&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;  :commands (maple-translate maple-translate+))&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
   或者手动下载仓库
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;git clone https://github.com/honmaple/emacs-maple-translate ~/.emacs.d/site-lisp/maple-translate&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
   然后进行配置
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;(use-package maple-translate
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;  :ensure &lt;span style=&quot;color:#66d9ef&quot;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;  :commands (maple-translate maple-translate+))&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h2 id=&quot;heading-2&quot;&gt;长句翻译&lt;/h2&gt;
&lt;p&gt;
   &lt;del&gt;目前长句翻译仅支持 &lt;code&gt;youdao&lt;/code&gt;&lt;/del&gt;, 目前支持 &lt;code&gt;youdao&lt;/code&gt; 和 &lt;code&gt;google&lt;/code&gt; 两种翻译引擎，可以修改设置
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;(setq maple-translate-engine &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;youdao&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;;; 或者&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;(setq maple-translate-engine &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;google&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h2 id=&quot;heading-3&quot;&gt;谷歌翻译&lt;/h2&gt;
&lt;p&gt;
   国内无法直接使用，但是可以单独为谷歌翻译设置代理
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;(setq maple-translate-google-url &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;https://translate.googleapis.com/translate_a/single&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;(setq maple-translate-google-proxies
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;      &lt;span style=&quot;color:#f92672&quot;&gt;&amp;#39;&lt;/span&gt;((&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;http&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;127.0.0.1:1086&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;        (&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;https&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;127.0.0.1:1086&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;)))&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h2 id=&quot;heading-4&quot;&gt;离线翻译&lt;/h2&gt;
&lt;p&gt;
   我个人平时在使用 &lt;b&gt;Emacs&lt;/b&gt; 时不太习惯依赖外部的工具，比如我之前就写过一个markdown，org-mode实时预览插件 &lt;a href=&quot;https://github.com/honmaple/emacs-maple-preview&quot;&gt;maple-preview&lt;/a&gt;，它区别于其它插件，并不会依赖外部的工具，比如 &lt;b&gt;Pandoc&lt;/b&gt;，甚至不会生出任何文件到我的本地环境
&lt;/p&gt;

&lt;p&gt;
   同样的，我也不希望使用离线翻译时还要依赖外部诸如 &lt;b&gt;sdcv，goldendict&lt;/b&gt; 等工具，我想要直接使用 &lt;code&gt;Elisp&lt;/code&gt; 来对词典进行解析。所幸前人栽树，后人乘凉，已经有了一个纯 &lt;code&gt;Elisp&lt;/code&gt; 实现的解析器 &lt;a href=&quot;https://www.emacswiki.org/emacs/stardict.el&quot;&gt;https://www.emacswiki.org/emacs/stardict.el&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
   我所需要做的，就是下载需要的词典到本地(这个步骤是必须的，即使我不喜欢)，然后设置
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;;; 离线词典所在的目录&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;(setq maple-translate-sdcv-dir &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;~/.stardict/dicts&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;;; 所使用的词典 -&amp;gt; (词典名词 . 词典具体目录)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;(setq maple-translate-sdcv-dicts
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;5&lt;/span&gt;&lt;span&gt;      &lt;span style=&quot;color:#f92672&quot;&gt;&amp;#39;&lt;/span&gt;((&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;lazyworm-ec&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;stardict-lazyworm-ec-2.4.2&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;6&lt;/span&gt;&lt;span&gt;        (&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;lazyworm-ce&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;stardict-lazyworm-ce-2.4.2&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;)))&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
   最后修改翻译引擎
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;(setq maple-translate-engine &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;sdcv&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
   注意：&lt;b&gt;第一次使用离线翻译需要等待词典初始化，这会需要耗费一段时间，后面就快了&lt;/b&gt;
&lt;/p&gt;

&lt;h2 id=&quot;heading-5&quot;&gt;多引擎翻译&lt;/h2&gt;
&lt;p&gt;
   &lt;b&gt;maple-translate&lt;/b&gt; 同样支持&lt;b&gt;多引擎&lt;/b&gt;，需要修改设置为一个列表
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;(setq maple-translate-engine &lt;span style=&quot;color:#f92672&quot;&gt;&amp;#39;&lt;/span&gt;(youdao dictcn sdcv))&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h2 id=&quot;heading-6&quot;&gt;翻译原理&lt;/h2&gt;
&lt;p&gt;
   目前支持的几个引擎: &lt;code&gt;youdao(有道)&lt;/code&gt;、&lt;code&gt;dictcn(海词)&lt;/code&gt;、&lt;code&gt;iciba(金山词霸)&lt;/code&gt;、&lt;code&gt;bing(必应)&lt;/code&gt;、&lt;code&gt;google(谷歌)&lt;/code&gt;、&lt;code&gt;sdcv(离线)&lt;/code&gt;。除 &lt;code&gt;sdcv&lt;/code&gt; 外，其它几个都依赖于网络，&lt;b&gt;maple-translate&lt;/b&gt; 可以看作是一个爬虫，通过爬取翻译页面，然后使用Emacs内置的 &lt;code&gt;dom&lt;/code&gt; 对HTML进行解析，最后获取到想要的内容(谷歌使用API获取)。基于此，我还写了一个超简单的 &lt;code&gt;类xpath&lt;/code&gt; 解析器
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;(defun maple-translate-dom-by-key(dom key)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;  (let (func num)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;    (when (&lt;span style=&quot;color:#a6e22e&quot;&gt;string-match&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;([0-9]+&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; key)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt;      (setq num (match-string &lt;span style=&quot;color:#ae81ff&quot;&gt;1&lt;/span&gt; key))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 5&lt;/span&gt;&lt;span&gt;      (setq key (&lt;span style=&quot;color:#a6e22e&quot;&gt;substring&lt;/span&gt; key &lt;span style=&quot;color:#ae81ff&quot;&gt;0&lt;/span&gt; (&lt;span style=&quot;color:#a6e22e&quot;&gt;-&lt;/span&gt; (&lt;span style=&quot;color:#a6e22e&quot;&gt;length&lt;/span&gt; key) (&lt;span style=&quot;color:#a6e22e&quot;&gt;length&lt;/span&gt; num) &lt;span style=&quot;color:#ae81ff&quot;&gt;2&lt;/span&gt;))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 6&lt;/span&gt;&lt;span&gt;    (cond ((string-prefix-p &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; key)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 7&lt;/span&gt;&lt;span&gt;           (setq key (&lt;span style=&quot;color:#a6e22e&quot;&gt;substring&lt;/span&gt; key &lt;span style=&quot;color:#ae81ff&quot;&gt;1&lt;/span&gt;) func &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;dom-by-class&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 8&lt;/span&gt;&lt;span&gt;          ((string-prefix-p &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; key)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 9&lt;/span&gt;&lt;span&gt;           (setq key (&lt;span style=&quot;color:#a6e22e&quot;&gt;substring&lt;/span&gt; key &lt;span style=&quot;color:#ae81ff&quot;&gt;1&lt;/span&gt;) func &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;dom-by-id&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;10&lt;/span&gt;&lt;span&gt;          ((string-prefix-p &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt; key)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;11&lt;/span&gt;&lt;span&gt;           (setq func (lambda(p _) (dom-children p))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;12&lt;/span&gt;&lt;span&gt;          (&lt;span style=&quot;color:#66d9ef&quot;&gt;t&lt;/span&gt; (setq key (&lt;span style=&quot;color:#a6e22e&quot;&gt;intern&lt;/span&gt; key) func &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;dom-by-tag&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;13&lt;/span&gt;&lt;span&gt;    (if (&lt;span style=&quot;color:#a6e22e&quot;&gt;null&lt;/span&gt; num)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;14&lt;/span&gt;&lt;span&gt;        (&lt;span style=&quot;color:#a6e22e&quot;&gt;funcall&lt;/span&gt; func dom key)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;15&lt;/span&gt;&lt;span&gt;      (&lt;span style=&quot;color:#a6e22e&quot;&gt;nth&lt;/span&gt; (&lt;span style=&quot;color:#a6e22e&quot;&gt;string-to-number&lt;/span&gt; num) (&lt;span style=&quot;color:#a6e22e&quot;&gt;funcall&lt;/span&gt; func dom key)))))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;16&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;17&lt;/span&gt;&lt;span&gt;(defun maple-translate-dom-find(dom xpath)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;18&lt;/span&gt;&lt;span&gt;  (cl-loop for key in (string-split (string-trim xpath) &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;19&lt;/span&gt;&lt;span&gt;           if (&lt;span style=&quot;color:#a6e22e&quot;&gt;consp&lt;/span&gt; dom)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;20&lt;/span&gt;&lt;span&gt;           do (setq dom (maple-translate-dom-by-key dom key))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;21&lt;/span&gt;&lt;span&gt;           else return dom)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;22&lt;/span&gt;&lt;span&gt;  dom)&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
   这样，我就能通过一些简单的语法来定位想要的内容，比如在有道里面使用
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;(maple-translate-dom-find dom &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;.simple dict-module/.trans-container/.word-exp&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
   获取到 &lt;b&gt;class&lt;/b&gt; 名称为 &lt;code&gt;simple dict-module&lt;/code&gt; 下的 &lt;b&gt;class&lt;/b&gt; 名称为 &lt;code&gt;trans-container&lt;/code&gt; 下的 &lt;b&gt;class&lt;/b&gt; 名称为 &lt;code&gt;word-exp&lt;/code&gt; 的所有元素, 也就是&lt;b&gt;基本释义&lt;/b&gt;
&lt;/p&gt;</content>
        <category term="Tech/Linux/Emacs"></category>
    </entry>
    <entry xml:lang="zh">
      <title>使用acme.sh申请SSL证书</title>
      <link href="https://honmaple.me/posts/2023/09/shi-yong-acme-shshen-qing-sslzheng-shu/" rel="alternate"></link>
      <published>Sun, 24 Sep 2023 13:57:51 +0000</published>
      <updated>Sun, 24 Sep 2023 19:06:00 +0000</updated>
      <author>
        <name>honmaple</name>
      </author>
      <link rel="alternate" href="https://honmaple.me/posts/2023/09/shi-yong-acme-shshen-qing-sslzheng-shu/" type="text/html"/>
      <id>https://honmaple.me/posts/2023/09/shi-yong-acme-shshen-qing-sslzheng-shu/</id>
      <summary type="html">
&lt;h2 id=&quot;heading-1&quot;&gt;部署教程&lt;/h2&gt;
&lt;h3 id=&quot;heading-1.1&quot;&gt;安装并配置acme.sh&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;
 安装&lt;br /&gt;
       这里使用 &lt;b&gt;Docker&lt;/b&gt; 安装，方便环境隔离。&lt;code&gt;/opt/acme.sh&lt;/code&gt; 为挂载目录
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;docker run -d --name acme.sh \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;-e AUTO_UPGRADE=0 \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;-e TZ=Asia/Shanghai \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;-v /opt/acme.sh:/acme.sh \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;5&lt;/span&gt;&lt;span&gt;neilpang...&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ol&gt;</summary>
      <content type="html">
&lt;h2 id=&quot;heading-1&quot;&gt;部署教程&lt;/h2&gt;
&lt;h3 id=&quot;heading-1.1&quot;&gt;安装并配置acme.sh&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;
 安装&lt;br /&gt;
       这里使用 &lt;b&gt;Docker&lt;/b&gt; 安装，方便环境隔离。&lt;code&gt;/opt/acme.sh&lt;/code&gt; 为挂载目录
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;docker run -d --name acme.sh \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;-e AUTO_UPGRADE=0 \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;-e TZ=Asia/Shanghai \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;-v /opt/acme.sh:/acme.sh \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;5&lt;/span&gt;&lt;span&gt;neilpang/acme.sh daemon&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 配置&lt;br /&gt;
       &lt;b&gt;acme.sh&lt;/b&gt; 默认使用的是 &lt;b&gt;ZeroSSL&lt;/b&gt;，我这里修改为 &lt;b&gt;Let&#39;s Encrypt&lt;/b&gt;
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;docker exec acme.sh --set-default-ca --server letsencrypt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;docker exec acme.sh --set-default-chain --preferred-chain &amp;#34;ISRG&amp;#34; --server letsencrypt&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
       注：&lt;code&gt;--preferred-chain &quot;ISRG&quot;&lt;/code&gt; 表示设置根证书为 &lt;b&gt;ISRG Root X1&lt;/b&gt;, 它与 &lt;b&gt;DST Root CA X3&lt;/b&gt; 的区别主要是
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;b&gt;ISRG Root X1&lt;/b&gt; 会更新一些，&lt;b&gt;DST Root CA X3&lt;/b&gt; 已于2021年9月30日到期
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 一些旧的设备（例如，iPhone 4 或 HTC Dream）不会信任 &lt;b&gt;ISRG Root X1&lt;/b&gt;，因为它们没有获得软件更新
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 虽说 &lt;b&gt;DST Root CA X3&lt;/b&gt; 已到期，但Android设备仍能够继续正常访问使用 Let’s Encrypt 证书加密的网站，其它旧设备将会得到证书过期警告
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 注册账号(&lt;b&gt;记得修改为自己的邮箱&lt;/b&gt;)
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;docker exec acme.sh --register-account --server letsencrypt -m i@example.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;[Sun Sep 24 15:49:59 CST 2023] Create account key ok.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;[Sun Sep 24 15:49:59 CST 2023] Registering account: https://acme-v02.api.letsencrypt.org/directory
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;[Sun Sep 24 15:50:05 CST 2023] Registered
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;5&lt;/span&gt;&lt;span&gt;[Sun Sep 24 15:50:05 CST 2023] ACCOUNT_THUMBPRINT=&amp;#39;xxx&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
       这时会在 &lt;code&gt;/acme.sh&lt;/code&gt; 目录下生成一个 &lt;code&gt;http.header&lt;/code&gt; 文件，申请证书时会使用该文件
&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;heading-1.2&quot;&gt;固定域名(webroot)&lt;/h3&gt;
&lt;p&gt;
    如果只有少数几个固定的域名，这时可以使用 &lt;b&gt;webroot&lt;/b&gt; 方式申请SSL证书。&lt;b&gt;webroot&lt;/b&gt; 方式会在本地生成一个验证文件，申请证书时通过验证该文件验证域名所有权
&lt;/p&gt;

&lt;h4 id=&quot;heading-1.2.1&quot;&gt;申请证书&lt;/h4&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;docker exec acme.sh --issue -d example.com -d www.example.com,nas.example.com -w /acme.sh/example.com&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
     执行后会在挂载目录 &lt;code&gt;/opt/acme.sh&lt;/code&gt; 下生成SSL证书相关的 &lt;b&gt;cert&lt;/b&gt; 文件和 &lt;b&gt;key&lt;/b&gt; 文件
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;$ ls example.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;ca.cer  fullchain.cer  example.com.cer  example.com.conf  example.com.csr  example.com.csr.conf  example.com.key&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;h4 id=&quot;heading-1.2.2&quot;&gt;配置SSL证书&lt;/h4&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;ssl_certificate&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;/opt/acme.sh/example.com/fullchain.cer&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;ssl_certificate_key&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;/opt/acme.sh/example.com/example.com.key&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;ssl_dhparam&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;/opt/acme.sh/example.com/dhparam.pem&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 5&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;ssl_session_cache&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;shared:SSL:1m&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 6&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;ssl_session_timeout&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;5m&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 7&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 8&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;ssl_protocols&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;TLSv1&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;TLSv1.1&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;TLSv1.2&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;TLSv1.3&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 9&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;ssl_ciphers&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;10&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;ssl_prefer_server_ciphers&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;on&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
     如何生成 &lt;b&gt;dhparam&lt;/b&gt; 的证书?
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;openssl dhparam -out /opt/acme.sh/example.com/dhparam.pem 2048&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;h4 id=&quot;heading-1.2.3&quot;&gt;配置NGINX&lt;/h4&gt;
&lt;p&gt;
     &lt;b&gt;Let&#39;s Encrypt&lt;/b&gt; 只会在 &lt;b&gt;80&lt;/b&gt; 端口验证域名所有权，所以只需要在 &lt;b&gt;80&lt;/b&gt; 端口添加一个 &lt;b&gt;location&lt;/b&gt;
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;server&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#f92672&quot;&gt;listen&lt;/span&gt;       &lt;span style=&quot;color:#ae81ff&quot;&gt;80&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#f92672&quot;&gt;listen&lt;/span&gt;  &lt;span style=&quot;color:#e6db74&quot;&gt;[::]:80&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#f92672&quot;&gt;server_name&lt;/span&gt;  &lt;span style=&quot;color:#e6db74&quot;&gt;www.example.com&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;nas.example.com&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 5&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 6&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#f92672&quot;&gt;location&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;/&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 7&lt;/span&gt;&lt;span&gt;        &lt;span style=&quot;color:#f92672&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;301&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;https://example.com&lt;/span&gt;$request_uri;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 8&lt;/span&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 9&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#f92672&quot;&gt;location&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;^~&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;/.well-known/acme-challenge&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;10&lt;/span&gt;&lt;span&gt;        &lt;span style=&quot;color:#f92672&quot;&gt;alias&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;/opt/acme.sh/example.com/.well-known/acme-challenge&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;11&lt;/span&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;12&lt;/span&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;13&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;14&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;server&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;15&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#f92672&quot;&gt;listen&lt;/span&gt;       &lt;span style=&quot;color:#ae81ff&quot;&gt;443&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;ssl&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;16&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#f92672&quot;&gt;listen&lt;/span&gt;       &lt;span style=&quot;color:#e6db74&quot;&gt;[::]:443&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;ssl&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;17&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#f92672&quot;&gt;server_name&lt;/span&gt;  &lt;span style=&quot;color:#e6db74&quot;&gt;nas.example.com&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;18&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#f92672&quot;&gt;include&lt;/span&gt;      &lt;span style=&quot;color:#e6db74&quot;&gt;/etc/nginx/conf.d/ssl/example.com.conf&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;19&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;20&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#f92672&quot;&gt;......&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;21&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;h4 id=&quot;heading-1.2.4&quot;&gt;重启NGINX&lt;/h4&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;nginx &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;t
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;nginx &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;s reload&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;h3 id=&quot;heading-1.3&quot;&gt;泛域名(DNS)&lt;/h3&gt;
&lt;p&gt;
    &lt;b&gt;webroot&lt;/b&gt; 无法申请泛域名证书，泛域名证书的申请需要利用&lt;b&gt;DNS服务提供商&lt;/b&gt;的API，动态添加一个TEXT记录，这里以 &lt;b&gt;Cloudflare&lt;/b&gt; 为例
&lt;/p&gt;
&lt;h4 id=&quot;heading-1.3.1&quot;&gt;令牌获取&lt;/h4&gt;
&lt;p&gt;
     右上角点击&lt;b&gt;我的个人资料&lt;/b&gt;, 然后点击&lt;b&gt;创建令牌&lt;/b&gt;
     
  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2023/09/cloudflare-token-01.jpg-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2023/09/cloudflare-token-01.jpg-thumb&quot;
         alt=&quot;cloudflare-token-01.jpg&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;
  &lt;link rel=&quot;stylesheet&quot; href=&quot;https://honmaple.me/libs/glightbox/glightbox.min.css&quot;&gt;
  &lt;script src=&quot;https://honmaple.me/libs/vanilla-lazyload/lazyload.min.js&quot; defer&gt;&lt;/script&gt;
  &lt;script src=&quot;https://honmaple.me/libs/glightbox/glightbox.min.js&quot; defer&gt;&lt;/script&gt;
    &lt;script src=&quot;https://honmaple.me/js/lazyload.js&quot; defer&gt;&lt;/script&gt;
    &lt;script src=&quot;https://honmaple.me/js/lightbox.js&quot; defer&gt;&lt;/script&gt;

&lt;/p&gt;

&lt;p&gt;
     然后选择&lt;b&gt;DNS模版&lt;/b&gt;
     
  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2023/09/cloudflare-token-02.jpg-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2023/09/cloudflare-token-02.jpg-thumb&quot;
         alt=&quot;cloudflare-token-02.jpg&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;

&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;b&gt;令牌名称&lt;/b&gt;可以随意
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;b&gt;权限&lt;/b&gt;设置为 &lt;code&gt;区域 -&gt; DNS -&gt; 编辑&lt;/code&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;b&gt;区域资源&lt;/b&gt;设置为 &lt;code&gt;包括 -&gt; 特定区域 -&gt; 域名(example.com)&lt;/code&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
     
  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2023/09/cloudflare-token-03.jpg-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2023/09/cloudflare-token-03.jpg-thumb&quot;
         alt=&quot;cloudflare-token-03.jpg&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;

&lt;/p&gt;

&lt;p&gt;
     继续以显示摘要, 然后创建令牌
     
  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2023/09/cloudflare-token-04.jpg-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2023/09/cloudflare-token-04.jpg-thumb&quot;
         alt=&quot;cloudflare-token-04.jpg&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;

&lt;/p&gt;

&lt;p&gt;
     最后记得保存令牌到本地
     
  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2023/09/cloudflare-token-05.jpg-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2023/09/cloudflare-token-05.jpg-thumb&quot;
         alt=&quot;cloudflare-token-05.jpg&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;

&lt;/p&gt;

&lt;h4 id=&quot;heading-1.3.2&quot;&gt;账户ID获取&lt;/h4&gt;
&lt;p&gt;
     选择对应的域名，在&lt;b&gt;概况&lt;/b&gt;的右下角会有账户ID显示
     
  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2023/09/cloudflare-token-06.jpg-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2023/09/cloudflare-token-06.jpg-thumb&quot;
         alt=&quot;cloudflare-token-06.jpg&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;

&lt;/p&gt;

&lt;h4 id=&quot;heading-1.3.3&quot;&gt;编辑配置&lt;/h4&gt;
&lt;p&gt;
     编辑 &lt;code&gt;/opt/acme.sh&lt;/code&gt; 目录下的 &lt;code&gt;account.conf&lt;/code&gt;
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;+ CF_Token=&amp;#39;xxx&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;+ CF_Account_ID=&amp;#39;xxx&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h4 id=&quot;heading-1.3.4&quot;&gt;申请证书&lt;/h4&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;docker exec acme.sh --issue --dns dns_cf -d &amp;#34;nas.example.com&amp;#34; -d &amp;#34;*.nas.example.com&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h4 id=&quot;heading-1.3.5&quot;&gt;安装证书&lt;/h4&gt;
&lt;p&gt;
     如果想要修改默认安装的目录，则可以使用 &lt;code&gt;--install-cert&lt;/code&gt; 命令
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;docker exec acme.sh --install-cert -d nas.example.com \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;--key-file /nginx/data/custom_ssl/npm-1/privkey.pem \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;--fullchain-file /nginx/data/custom_ssl/npm-1/fullchain.pem&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
     如果想要更新证书后同步重启NGINX，可以继续添加命令参数
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;reloadcmd &lt;span style=&quot;color:#e6db74&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;nginx -s reload&lt;/span&gt;&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h3 id=&quot;heading-1.4&quot;&gt;搭配NginxProxyManager&lt;/h3&gt;
&lt;p&gt;
    首先打开 &lt;b&gt;NginxProxyManager&lt;/b&gt;, 选择 &lt;b&gt;SSL Cetificates&lt;/b&gt;
    
  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2023/09/acme.sh-nginx-01.jpg-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2023/09/acme.sh-nginx-01.jpg-thumb&quot;
         alt=&quot;acme.sh-nginx-01.jpg&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;

&lt;/p&gt;

&lt;p&gt;
    然后选择 &lt;b&gt;Add SSL Cetificates -&amp;gt; Custom&lt;/b&gt;
    
  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2023/09/acme.sh-nginx-02.jpg-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2023/09/acme.sh-nginx-02.jpg-thumb&quot;
         alt=&quot;acme.sh-nginx-02.jpg&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;

&lt;/p&gt;

&lt;p&gt;
    最后添加相关文件:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;b&gt;Certificate&lt;/b&gt;: &lt;code&gt;nas.example.com.cer&lt;/code&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;b&gt;Certificate Key&lt;/b&gt;: &lt;code&gt;nas.example.com.key&lt;/code&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;b&gt;Intermediate Certificate&lt;/b&gt;: &lt;code&gt;ca.cer&lt;/code&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
    
  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2023/09/acme.sh-nginx-03.jpg-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2023/09/acme.sh-nginx-03.jpg-thumb&quot;
         alt=&quot;acme.sh-nginx-03.jpg&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;

&lt;/p&gt;

&lt;p&gt;
    为了避免证书过期后重新添加，需要把&lt;b&gt;NginxProxyManager&lt;/b&gt;挂载目录也挂载到 &lt;b&gt;acme.sh&lt;/b&gt; 容器
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;docker stop acme.sh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;docker rm acme.sh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;docker run -d --name acme.sh \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;-e AUTO_UPGRADE=0 \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;5&lt;/span&gt;&lt;span&gt;-e TZ=Asia/Shanghai \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;6&lt;/span&gt;&lt;span&gt;-v /opt/acme.sh:/acme.sh \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;7&lt;/span&gt;&lt;span&gt;-v /opt/nginx:/nginx \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;8&lt;/span&gt;&lt;span&gt;neilpang/acme.sh daemon&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
    然后修改申请证书的命令
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;docker exec acme.sh --issue --dns dns_cf -d &amp;#34;nas.example.com&amp;#34; -d &amp;#34;*.nas.example.com&amp;#34; \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;--renew-hook &amp;#34;acme.sh --install-cert -d nas.example.com \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;--key-file /nginx/data/custom_ssl/npm-1/privkey.pem \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;--fullchain-file /nginx/data/custom_ssl/npm-1/fullchain.pem&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
    如果提示 &lt;code&gt;Domains not changed&lt;/code&gt;, 则需要使用 &lt;code&gt;--force&lt;/code&gt; 重新申请
&lt;/p&gt;

&lt;h3 id=&quot;heading-1.5&quot;&gt;更新证书(手动)&lt;/h3&gt;
&lt;p&gt;
    从 &lt;b&gt;Let&#39;s Encrypt&lt;/b&gt; 申请到的证书有效期是90天，&lt;b&gt;acme.sh&lt;/b&gt; 每60天会对证书进行更新，你也可以手动强制更新：
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;# 查询证书申请信息
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;acme.sh --list
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;# 手动强制更新证书
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;5&lt;/span&gt;&lt;span&gt;acme.sh --renew -d nas.example.com -d *.nas.example.com --force&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h2 id=&quot;heading-2&quot;&gt;参考资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;a href=&quot;https://github.com/acmesh-official/acme.sh/wiki/Preferred-Chain&quot;&gt;https://github.com/acmesh-official/acme.sh/wiki/Preferred-Chain&lt;/a&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;a href=&quot;https://letsencrypt.org/zh-cn/docs/dst-root-ca-x3-expiration-september-2021/&quot;&gt;https://letsencrypt.org/zh-cn/docs/dst-root-ca-x3-expiration-september-2021/&lt;/a&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;a href=&quot;https://shiping.date/82.html&quot;&gt;https://shiping.date/82.html&lt;/a&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
        <category term="Tech"></category>
    </entry>
    <entry xml:lang="zh">
      <title>Zerotier笔记</title>
      <link href="https://honmaple.me/posts/2023/09/zerotier-note/" rel="alternate"></link>
      <published>Sun, 17 Sep 2023 15:41:40 +0000</published>
      <updated>Sun, 24 Sep 2023 16:52:48 +0000</updated>
      <author>
        <name>honmaple</name>
      </author>
      <link rel="alternate" href="https://honmaple.me/posts/2023/09/zerotier-note/" type="text/html"/>
      <id>https://honmaple.me/posts/2023/09/zerotier-note/</id>
      <summary type="html">
&lt;blockquote&gt;
&lt;p&gt;
&lt;b&gt;zerotier&lt;/b&gt; 可谓是慕名许久，但之前一直没有太多内网穿透和异地组网的需求，此次准备在外网访问家里NAS部署的部分应用，所以也调研了一些相关的应用，最终选择了 &lt;b&gt;zerotier&lt;/b&gt; 来对我现有的机器进行组网
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;b&gt;FRP&lt;/b&gt;: 需要将服务器的端口映射出去，不太喜欢这种暴力的方式。我目前的服务基本上只会在 &lt;code&gt;0.0.0.0&lt;/code&gt; 监听80、443等常用端口，其它服务一律监听 &lt;code&gt;127.0.0.1&lt;/code&gt;，通过nginx访问内部的服务
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;b&gt;DDNS&lt;/b&gt;: 家里的NAS直接暴露在公网，这非常不安全，而且家用宽带无法使用80，443端口，只能使用高位端口
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;b&gt;ZEROTIER&lt;/b&gt;: 使用 &lt;b&gt;P2P&lt;/b&gt; 的方式对多台服务器进行组网，映射的端口只允许加入组网的设备访问，这在速度和安全性上确实是我所需要的...&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;</summary>
      <content type="html">
&lt;blockquote&gt;
&lt;p&gt;
&lt;b&gt;zerotier&lt;/b&gt; 可谓是慕名许久，但之前一直没有太多内网穿透和异地组网的需求，此次准备在外网访问家里NAS部署的部分应用，所以也调研了一些相关的应用，最终选择了 &lt;b&gt;zerotier&lt;/b&gt; 来对我现有的机器进行组网
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;b&gt;FRP&lt;/b&gt;: 需要将服务器的端口映射出去，不太喜欢这种暴力的方式。我目前的服务基本上只会在 &lt;code&gt;0.0.0.0&lt;/code&gt; 监听80、443等常用端口，其它服务一律监听 &lt;code&gt;127.0.0.1&lt;/code&gt;，通过nginx访问内部的服务
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;b&gt;DDNS&lt;/b&gt;: 家里的NAS直接暴露在公网，这非常不安全，而且家用宽带无法使用80，443端口，只能使用高位端口
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;b&gt;ZEROTIER&lt;/b&gt;: 使用 &lt;b&gt;P2P&lt;/b&gt; 的方式对多台服务器进行组网，映射的端口只允许加入组网的设备访问，这在速度和安全性上确实是我所需要的
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;heading-1&quot;&gt;相关概念&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;b&gt;Planet&lt;/b&gt;: 行星服务器，也称根服务器。主要用于管理 &lt;b&gt;zerotier&lt;/b&gt; 客户端的地址信息
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;b&gt;Moon&lt;/b&gt;: 月亮服务器，也称中继服务器、跳转服务器。主要用于当两台设备无法直连时，可以通过Moon中转连接
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;b&gt;Leaf&lt;/b&gt;: 组网使用的设备，可以是一台服务器，一台NAS，甚至一台手机
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;heading-2&quot;&gt;部署教程&lt;/h2&gt;
&lt;p&gt;
   现在我有三台设备需要进行组网，一台A在国外， 一台B在国内(腾讯云)，还有一台C在家里(NAS)。我准备将私有Planet部署到机器A，同时机器A也会加入到内网里，A、B、C三台设备可以通过内网相互访问
&lt;/p&gt;

&lt;h3 id=&quot;heading-2.1&quot;&gt;UI界面&lt;/h3&gt;
&lt;p&gt;
    以 &lt;code&gt;jonnyan404/zerotier-planet&lt;/code&gt; 为例
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;
 创建目录
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;mkdir /opt/zerotier /opt/ztncui&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 部署服务
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;docker run &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;d &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;name ztncui &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;restart always \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;p &lt;span style=&quot;color:#ae81ff&quot;&gt;4000&lt;/span&gt;:&lt;span style=&quot;color:#ae81ff&quot;&gt;4000&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;p &lt;span style=&quot;color:#ae81ff&quot;&gt;9993&lt;/span&gt;:&lt;span style=&quot;color:#ae81ff&quot;&gt;9993&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;tcp &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;p &lt;span style=&quot;color:#ae81ff&quot;&gt;9993&lt;/span&gt;:&lt;span style=&quot;color:#ae81ff&quot;&gt;9993&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;udp \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;e MYADDR&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;{&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;服&lt;/span&gt;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;务&lt;/span&gt;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;器&lt;/span&gt;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;公&lt;/span&gt;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;网&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;IP&lt;/span&gt;} \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;e HTTP_PORT&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#ae81ff&quot;&gt;4000&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;5&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;e HTTP_ALL_INTERFACES&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;yes \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;6&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;e ZTNCUI_PASSWD&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;mrdoc&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;fun \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;7&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;v &lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;opt&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;zerotier:&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;lib&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;zerotier&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;one \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;8&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;v &lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;opt&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;ztncui:&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;opt&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;key&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;networks&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;ztncui&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;etc \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;9&lt;/span&gt;&lt;span&gt;keynetworks&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;ztncui&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
       然后就可以通过 &lt;code&gt;服务器公网IP:4000&lt;/code&gt; 访问UI管理界面，默认的用户名和密码: &lt;code&gt;admin,mrdoc.fun&lt;/code&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;heading-2.2&quot;&gt;Zerotier客户端&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;b&gt;Linux&lt;/b&gt;: 部署方式很简单，注意区分 &lt;b&gt;host网络&lt;/b&gt; 和 &lt;b&gt;bridge网络&lt;/b&gt;，这两个在安全性有所区别(具体在下面讲)
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;docker run &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;name zerotier &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;d \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;restart always \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;net host \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;cap&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;add NET_ADMIN \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;5&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;device &lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;dev&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;net&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;tun \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;6&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;v &lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;opt&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;zerotier:&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;lib&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;zerotier&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;one \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;7&lt;/span&gt;&lt;span&gt;zerotier&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;zerotier:latest&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
      如果使用私有Planet，记得替换 &lt;code&gt;/opt/zerotier/planet&lt;/code&gt; 文件
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;b&gt;Android&lt;/b&gt;: 推荐使用 &lt;a href=&quot;https://github.com/kaaass/ZerotierFix&quot;&gt;https://github.com/kaaass/ZerotierFix&lt;/a&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;heading-2.3&quot;&gt;私有Planet&lt;/h3&gt;
&lt;p&gt;
    默认的Planet信息是硬编码在zertier代码里，如果安装好客户端后会在 &lt;code&gt;zerotier-cli peers&lt;/code&gt; 看到官方的Planet服务器。
&lt;/p&gt;

&lt;p&gt;
    而部署私有的Planet的目的:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;
 官方的服务器基本都位于国外或者香港，服务连通性无法得到保证
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 安全性。试想一个陌生的设备加入到网络，而这个设备的许可只需要得到官方的认证即可。当然，官方是基本不可能发生这样的情况，但如果有一个完全控制的网络，何乐而不为呢
&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
    如何生成私有Planet文件?
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;git clone https://github.com/jonnyan404/zerotier-planet --depth=1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;cd zerotier-planet
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;docker cp mkmoonworld-x86_64 ztncui:/tmp
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;docker cp patch.sh ztncui:/tmp
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;5&lt;/span&gt;&lt;span&gt;docker exec -it ztncui bash /tmp/patch.sh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;6&lt;/span&gt;&lt;span&gt;docker restart ztncui&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
    这样就会在挂载目录 &lt;code&gt;/opt/zerotier&lt;/code&gt; 下生成一个新的 &lt;b&gt;planet&lt;/b&gt; 文件，记得下载并备份。&lt;b&gt;所有加入组网的客户端都需要替换该文件&lt;/b&gt;
&lt;/p&gt;

&lt;h3 id=&quot;heading-2.4&quot;&gt;私有Planet服务器加入组网&lt;/h3&gt;
&lt;p&gt;
    如果按照上述部署流程也可以正常使用 &lt;code&gt;zerotier&lt;/code&gt; 组网，&lt;b&gt;但是&lt;/b&gt;，如果想要把部署了私有Planet的设备也加入到内网，貌似没有一篇文章说到。 所以我专门研究了一下，想要把私有Planet的机器也加入到内网，大概是可以分为下面几种方式:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;
 (&lt;b&gt;不推荐&lt;/b&gt;) 修改ztncui内部zerotier的默认端口9993 &lt;br /&gt;
       在 &lt;code&gt;/opt/zerotier&lt;/code&gt; 目录下添加一个 &lt;code&gt;local.conf&lt;/code&gt;，并设置
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#f92672&quot;&gt;&amp;#34;settings&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;        &lt;span style=&quot;color:#f92672&quot;&gt;&amp;#34;primaryPort&amp;#34;&lt;/span&gt;: &lt;span style=&quot;color:#ae81ff&quot;&gt;9995&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;5&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
       然后修改 &lt;code&gt;patch.sh&lt;/code&gt; 文件里的 &lt;code&gt;9993&lt;/code&gt; 端口，以及 &lt;code&gt;/start_ztncui.sh&lt;/code&gt; 添加一行
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;echo &amp;#34;ZT_ADDR=localhost:$ZT_PORT&amp;#34; &amp;gt; /opt/key-networks/ztncui/.env&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 部署两个zerotier: 除了ztncui容器内部的一个zerotier，再在机器上部署一个客户端，并修改端口，避免端口冲突
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 (&lt;b&gt;推荐&lt;/b&gt;) ztncui镜像的UI和zerotier分开部署&lt;br /&gt;
       我研究后才发现 &lt;code&gt;ztncui&lt;/code&gt; 的相关镜像把事情弄的很复杂，都把 &lt;code&gt;ztncui&lt;/code&gt; 和 &lt;code&gt;zerotier&lt;/code&gt; 放到同一个镜像，专门去连接 &lt;code&gt;localhost:9993&lt;/code&gt; 。其实是可以把两个镜像分开的，&lt;b&gt;UI&lt;/b&gt; 只做 &lt;b&gt;UI&lt;/b&gt; ，使用 &lt;b&gt;API&lt;/b&gt; 去连接 &lt;b&gt;zerotier&lt;/b&gt; 官方的镜像
&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;heading-2.5&quot;&gt;UI和Zerotier分开部署&lt;/h3&gt;
&lt;p&gt;
    如果想要自己构建Docker镜像，可以参考 &lt;a href=&quot;https://github.com/honmaple/ztncui-aio&quot;&gt;honmaple/ztncui-aio&lt;/a&gt;
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;
 部署 &lt;b&gt;zerotier&lt;/b&gt; 的客户端(部署过的可以忽略)
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;docker run &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;d &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;name zerotier &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;restart always &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;net&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;host &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;cap&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;add NET_ADMIN &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;device &lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;dev&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;net&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;tun &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;v &lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;opt&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;zerotier:&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;lib&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;zerotier&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;one zerotier&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;zerotier:latest&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 部署 &lt;b&gt;UI&lt;/b&gt;
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 1&lt;/span&gt;&lt;span&gt;docker run &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;d &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;name ztncui &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;restart always \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 2&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;e MYADDR&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;{&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;服&lt;/span&gt;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;务&lt;/span&gt;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;器&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;IP&lt;/span&gt;} \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 3&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;e HTTP_PORT&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#ae81ff&quot;&gt;4000&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 4&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;e HTTP_ALL_INTERFACES&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;yes \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 5&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;e ZT_ADDR&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;{zerotier地址, &lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;比&lt;/span&gt;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;如&lt;/span&gt;Docker网关:&lt;span style=&quot;color:#ae81ff&quot;&gt;9993&lt;/span&gt;} \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 6&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;e ZT_TOKEN&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;{&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;可&lt;/span&gt;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;以&lt;/span&gt;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;为&lt;/span&gt;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;空&lt;/span&gt;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;，&lt;/span&gt;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;但&lt;/span&gt;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;需&lt;/span&gt;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;要&lt;/span&gt;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;挂&lt;/span&gt;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;载&lt;/span&gt;zerotier&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;one的配置路径} \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 7&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;v &lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;opt&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;ztncui:&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;opt&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;ztncui&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;etc \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 8&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;v &lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;opt&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;zerotier:&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;lib&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;zerotier&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;one \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt; 9&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;p &lt;span style=&quot;color:#ae81ff&quot;&gt;4000&lt;/span&gt;:&lt;span style=&quot;color:#ae81ff&quot;&gt;4000&lt;/span&gt; \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;10&lt;/span&gt;&lt;span&gt;honmaple&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;ztncui:latest&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
       &lt;b&gt;ZT_ADDR&lt;/b&gt;: 由于 &lt;b&gt;zerotier&lt;/b&gt; 和 &lt;b&gt;ztncui&lt;/b&gt; 没有部署在一个容器，所以需要从UI内部访问宿主机的 &lt;b&gt;&lt;b&gt;9993&lt;/b&gt;&lt;/b&gt; 端口，这里可以使用UI容器的网关访问，比如UI容器的IP是 &lt;b&gt;&lt;b&gt;172.17.0.12&lt;/b&gt;&lt;/b&gt;，则访问 &lt;b&gt;&lt;b&gt;172.17.0.1&lt;/b&gt;&lt;/b&gt;
&lt;/p&gt;

&lt;p&gt;
       另外，&lt;b&gt;zerotier&lt;/b&gt; 默认的API接口只允许 &lt;b&gt;&lt;b&gt;127.0.0.1&lt;/b&gt;&lt;/b&gt; 访问，所以需要在挂载目录 &lt;code&gt;/opt/zerotier&lt;/code&gt; 下新建一个 &lt;b&gt;&lt;b&gt;local.conf&lt;/b&gt;&lt;/b&gt;
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#f92672&quot;&gt;&amp;#34;settings&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;        &lt;span style=&quot;color:#f92672&quot;&gt;&amp;#34;allowManagementFrom&amp;#34;&lt;/span&gt;: [&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;127.0.0.1/24&amp;#34;&lt;/span&gt;, &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;::1&amp;#34;&lt;/span&gt;, &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;172.17.0.1/24&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;5&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 修改归属的用户和用户组
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;docker exec &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;it zerotier bash
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;cd &lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;lib&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;zerotier&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;one
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;chown zerotier&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;one:zerotier&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;one local&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;conf
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;exit&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 生成私有Planet文件
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;git clone https://github.com/honmaple/ztncui-aio --depth=1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;cd ztncui-aio
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;docker cp script/mkmoonworld-x86_64 zerotier:/tmp
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;docker cp script/patch.sh zerotier:/tmp
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;5&lt;/span&gt;&lt;span&gt;docker exec -it zerotier bash /tmp/patch.sh {服务器IP}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 重启
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;docker restart zerotier&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
       这样就能使私有Planet和zerotier客户端共存，让Planet服务器也能加入到内网环境了
&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;heading-3&quot;&gt;组网教程&lt;/h2&gt;
&lt;h3 id=&quot;heading-3.1&quot;&gt;创建网络&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;
 使用浏览器打开UI管理界面 &lt;code&gt;{服务器公网IP}:4000&lt;/code&gt;，&lt;code&gt;honmaple/ztncui&lt;/code&gt; 默认用户名密码是 &lt;code&gt;admin,password&lt;/code&gt;
       
  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2023/09/zerotier-01.jpg-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2023/09/zerotier-01.jpg-thumb&quot;
         alt=&quot;zerotier-01.jpg&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;
  &lt;link rel=&quot;stylesheet&quot; href=&quot;https://honmaple.me/libs/glightbox/glightbox.min.css&quot;&gt;
  &lt;script src=&quot;https://honmaple.me/libs/vanilla-lazyload/lazyload.min.js&quot; defer&gt;&lt;/script&gt;
  &lt;script src=&quot;https://honmaple.me/libs/glightbox/glightbox.min.js&quot; defer&gt;&lt;/script&gt;
    &lt;script src=&quot;https://honmaple.me/js/lazyload.js&quot; defer&gt;&lt;/script&gt;
    &lt;script src=&quot;https://honmaple.me/js/lightbox.js&quot; defer&gt;&lt;/script&gt;

&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 点击 &lt;code&gt;Add network&lt;/code&gt;，输入一个网络名称，比如 &lt;b&gt;testlab&lt;/b&gt;。然后选择 &lt;code&gt;Easy setup&lt;/code&gt;
       
  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2023/09/zerotier-02.jpg-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2023/09/zerotier-02.jpg-thumb&quot;
         alt=&quot;zerotier-02.jpg&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;

&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 添加一个内网网段，记得这个内网网段不能和需要加入组网的设备网段相同，比如我的设备C网段是 &lt;code&gt;192.168.31.0/24&lt;/code&gt; ，就不能添加该网段，另外Docker所使用的网段 &lt;code&gt;172.0.0.0/8&lt;/code&gt; 也需要避免添加，所以我这里选择 &lt;code&gt;10.8.230.0/24&lt;/code&gt;。&lt;b&gt;不同的设备内网网段不同，请根据实际添加&lt;/b&gt;
       
  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2023/09/zerotier-03.jpg-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2023/09/zerotier-03.jpg-thumb&quot;
         alt=&quot;zerotier-03.jpg&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;

&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;heading-3.2&quot;&gt;加入网络&lt;/h3&gt;
&lt;p&gt;
    创建好网络后就会得到一串网络ID，登录到设备，然后使用
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;docker exec zerotier zerotier-cli join {网络ID}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
    加入网络，正常情况下会得到
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;200 join OK&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
    刷新管理界面就会出现一个新的成员
    
  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2023/09/zerotier-04.jpg-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2023/09/zerotier-04.jpg-thumb&quot;
         alt=&quot;zerotier-04.jpg&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;

    然后勾选 &lt;b&gt;Authorizerd&lt;/b&gt; 允许加入，再次刷新，就能看到该设备分配了一个新的IP &lt;code&gt;10.8.230.170&lt;/code&gt;
    
  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2023/09/zerotier-05.jpg-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2023/09/zerotier-05.jpg-thumb&quot;
         alt=&quot;zerotier-05.jpg&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;

&lt;/p&gt;

&lt;p&gt;
    返回设备，可以看到设备多了一个新的IP
    
  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2023/09/zerotier-06.jpg-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2023/09/zerotier-06.jpg-thumb&quot;
         alt=&quot;zerotier-06.jpg&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;

&lt;/p&gt;

&lt;h3 id=&quot;heading-3.3&quot;&gt;跨网段访问&lt;/h3&gt;
&lt;p&gt;
    什么是跨网段访问? 比如现在我可以通过 &lt;b&gt;10.8.230.0/24&lt;/b&gt; 访问已经加入组网的设备，但我想要在&lt;b&gt;设备B&lt;/b&gt;上访问我家里的其它设备，但是，我家里设备的网段是 &lt;b&gt;192.168.31.0/24&lt;/b&gt;，正常是无法访问的，只能访问已经加入组网的Nas。这时需要配置静态路由，让设备B访问 &lt;b&gt;192.168.31.0/24&lt;/b&gt; 网段时走zerotier配置好的IP。
&lt;/p&gt;

&lt;p&gt;
    如果手动添加就是
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;ip route add 192.168.31.0/24 via 10.8.230.170 dev {zerotier建立的网卡}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
    当然，也可以直接使用zerotier管理界面添加，选择 &lt;code&gt;Routes&lt;/code&gt;
    
  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2023/09/zerotier-07.jpg-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2023/09/zerotier-07.jpg-thumb&quot;
         alt=&quot;zerotier-07.jpg&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;

&lt;/p&gt;

&lt;p&gt;
    &lt;b&gt;Target&lt;/b&gt; 输入想要访问的网段：&lt;code&gt;192.168.31.0/24&lt;/code&gt;，&lt;b&gt;Gateway&lt;/b&gt; 输入之前分配的IP：&lt;code&gt;10.8.230.170&lt;/code&gt;。
    
  &lt;a class=&quot;mx-auto block w-fit max-w-full no-underline&quot; href=&quot;https://s.libforest.com/images/2023/09/zerotier-08.jpg-show&quot; data-img-lightbox data-gallery=&quot;page-images&quot; data-type=&quot;image&quot;&gt;
    &lt;img data-src=&quot;https://s.libforest.com/images/2023/09/zerotier-08.jpg-thumb&quot;
         alt=&quot;zerotier-08.jpg&quot;
         decoding=&quot;async&quot;
         class=&quot;lazy mx-auto cursor-zoom-in rounded-md &quot;&gt;
  &lt;/a&gt;

&lt;/p&gt;

&lt;p&gt;
    创建好后可以在设备B上执行
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;ping 192.168.31.XX(除设备C之外的内网设备IP)&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
    查看网络是否连通
&lt;/p&gt;

&lt;h3 id=&quot;heading-3.4&quot;&gt;安全限制&lt;/h3&gt;
&lt;p&gt;
    正因为跨网段访问只需要添加一个静态路由，就能访问我家里的其它设备，这无疑是非常不安全的。如果私有Planet服务器遭到入侵，我家里的所有联网设备都会暴露出去，即使加入组网只是其中的一台。基于此原因，我专门调整了一下zerotier的部署方式，不再使用 &lt;b&gt;host网络&lt;/b&gt; 的方式部署，而是创建一个新的Docker网络 &lt;code&gt;zerotier&lt;/code&gt;
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;docker network create --driver=bridge --subnet=192.168.100.0/24 --gateway=192.168.100.1 zerotier&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
    注: &lt;code&gt;192.168.100.0/24&lt;/code&gt; 是一个全新的网段，不要使用172网段
&lt;/p&gt;

&lt;p&gt;
    然后删除之前部署的 &lt;b&gt;zerotier&lt;/b&gt; 客户端，并使用 &lt;b&gt;zerotier网络&lt;/b&gt; 重新部署
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;docker stop zerotier
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;docker rm zerotier
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;docker run &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;d &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;name zerotier &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;restart always &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;net zerotier &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;cap&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;add NET_ADMIN &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;device &lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;dev&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;net&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;tun &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;v &lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;opt&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;zerotier:&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;lib&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;zerotier&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;one zerotier&lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt;zerotier:latest&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
    细心的朋友应该会发现我这里没有将 &lt;b&gt;9993&lt;/b&gt; 端口映射给宿主机，这是由于我测试发现两台设备只需要其中一台开放 &lt;code&gt;9993&lt;/code&gt; 端口，两台设备之间就能直连。如果两台设备都不开放端口，则会通过开放了端口的其它设备进行跳转，查看 &lt;b&gt;peers&lt;/b&gt; 会看到一直是 &lt;b&gt;RELAY&lt;/b&gt; 状态
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;root@cf5f973bd294:/# zerotier-cli peers
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;200 peers
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;&amp;lt;ztaddr&amp;gt;   &amp;lt;ver&amp;gt;  &amp;lt;role&amp;gt; &amp;lt;lat&amp;gt; &amp;lt;link&amp;gt;   &amp;lt;lastTX&amp;gt; &amp;lt;lastRX&amp;gt; &amp;lt;path&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;xxxxxxxxx  1.12.1 LEAF      -1 RELAY&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
    这时想要从设备B访问我家里其它联网的设备已是不可能，除非突破Docker的限制。而正常情况下，我想要从设备B上访问的是部署在设备C的其它服务(以Docker服务为主)，所以，现在可以添加一个新的路由 &lt;b&gt;192.168.100.0/24&lt;/b&gt; 指向 &lt;b&gt;10.8.230.170&lt;/b&gt;，然后修改其它镜像使用的网络为 &lt;b&gt;zerotier&lt;/b&gt;
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;docker run -d --rm --name=test-nginx --net=zerotier nginx:stable-alpine
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;docker exec -it test-nginx ip a&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
    接着在设备B上执行
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;ping 192.168.100.3(test-nginx的IP)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;curl 192.168.100.3&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
    如果无法访问，需要在Docker所在宿主机上添加路由
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;ip route add 10.8.230.0/24 via 192.168.100.2(zerotier客户端的IP)&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
    另外，由于Docker的IP可能会发生改变，除创建容器时指定 &lt;code&gt;--ip&lt;/code&gt; 外，还可以将服务的端口映射出去，比如 &lt;b&gt;NasTools&lt;/b&gt; 使用端口为 3000，那么可以在创建容器时指定
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;-p 11300:3000&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
    然后在设备B上访问 &lt;code&gt;192.168.100.1:11300&lt;/code&gt;，即&lt;b&gt;网关地址+映射的端口&lt;/b&gt;，这样就能避免Docker重启后IP发生改变而导致服务异常的情况
&lt;/p&gt;

&lt;h2 id=&quot;heading-4&quot;&gt;FAQ&lt;/h2&gt;
&lt;h3 id=&quot;heading-4.1&quot;&gt;如何修改默认的9993端口?&lt;/h3&gt;
&lt;p&gt;
    在 &lt;b&gt;zerotier&lt;/b&gt; 挂载的目录下新建一个 &lt;code&gt;local.conf&lt;/code&gt; 文件，并设置
&lt;/p&gt;
&lt;pre style=&quot;color:#f8f8f2;background-color:#272822;-webkit-text-size-adjust:none;&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;1&lt;/span&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;2&lt;/span&gt;&lt;span&gt;    &lt;span style=&quot;color:#f92672&quot;&gt;&amp;#34;settings&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;3&lt;/span&gt;&lt;span&gt;        &lt;span style=&quot;color:#f92672&quot;&gt;&amp;#34;primaryPort&amp;#34;&lt;/span&gt;: &lt;span style=&quot;color:#ae81ff&quot;&gt;9995&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;4&lt;/span&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span style=&quot;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&quot;&gt;5&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h2 id=&quot;heading-5&quot;&gt;参考资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;a href=&quot;https://github.com/honmaple/ztncui-aio&quot;&gt;https://github.com/honmaple/ztncui-aio&lt;/a&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;a href=&quot;https://github.com/jonnyan404/zerotier-planet&quot;&gt;https://github.com/jonnyan404/zerotier-planet&lt;/a&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;a href=&quot;https://github.com/zerotier/ZeroTierOne/blob/dev/README.docker.md&quot;&gt;https://github.com/zerotier/ZeroTierOne/blob/dev/README.docker.md&lt;/a&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
 &lt;a href=&quot;https://docs.zerotier.com/zerotier/zerotier.conf/&quot;&gt;https://docs.zerotier.com/zerotier/zerotier.conf/&lt;/a&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
        <category term="Tech/Geek"></category>
    </entry>
</feed>
