diff options
author | 2023-12-15 21:25:00 +0800 | |
---|---|---|
committer | 2024-01-03 22:58:15 +0800 | |
commit | 4b70534bb4fce2ab978d0628660f543a8076ca93 (patch) | |
tree | 271dc54d1b7b51643095640fe69c659ba7693973 | |
parent | f401b0ce48e19f1e25af14b3a78b4d9ef8998e73 (diff) | |
download | myweb-4b70534bb4fce2ab978d0628660f543a8076ca93.tar.gz myweb-4b70534bb4fce2ab978d0628660f543a8076ca93.zip |
Add git server and python http server configuration
- how to build a git bare repo server using my server
- add sth to python http.server to show files in server
- in order to do this, split the aliyun_cloud.md into several parts
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | code/highlight.html | 350 | ||||
-rw-r--r-- | code/linux/aliyun_cloud.html | 568 | ||||
-rw-r--r-- | code/linux/aliyun_cloud.md | 628 | ||||
-rw-r--r-- | code/linux/gitserver.html | 364 | ||||
-rw-r--r-- | code/linux/gitserver.md | 368 | ||||
-rw-r--r-- | code/linux/httpmyserver.html | 277 | ||||
-rw-r--r-- | code/linux/httpmyserver.md | 291 | ||||
-rw-r--r-- | code/linux/vim.html | 833 | ||||
-rw-r--r-- | code/linux/vim.md | 413 | ||||
-rw-r--r-- | code/stdc++.html | 892 | ||||
-rw-r--r-- | common/CSS/MySet.css | 3 | ||||
-rw-r--r-- | common/CSS/huang.css | 2 | ||||
-rw-r--r-- | common/script4works.html | 28 | ||||
-rw-r--r-- | common/script4works.js | 28 | ||||
-rwxr-xr-x | md2html.sh | 28 | ||||
-rw-r--r-- | works/education.html | 2 | ||||
-rw-r--r-- | works/poetry.html | 87 |
18 files changed, 2281 insertions, 2884 deletions
@@ -1,6 +1,7 @@ | |||
1 | # To ignore all files used to push or run | 1 | # To ignore all files used to push or run |
2 | *.bat | 2 | *.bat |
3 | *.sh | 3 | push.sh |
4 | *.exe | 4 | *.exe |
5 | .*.sw* | ||
5 | /.vscode | 6 | /.vscode |
6 | */html2js | 7 | */html2js |
diff --git a/code/highlight.html b/code/highlight.html index a0d9b61..840a3fb 100644 --- a/code/highlight.html +++ b/code/highlight.html | |||
@@ -6,76 +6,48 @@ | |||
6 | <title>我的代码块</title> | 6 | <title>我的代码块</title> |
7 | <link rel="stylesheet" href="https://www.qin-juan-ge-zhu.top/common/CSS/pandoc.css"> | 7 | <link rel="stylesheet" href="https://www.qin-juan-ge-zhu.top/common/CSS/pandoc.css"> |
8 | <script type="text/javascript" src="https://www.qin-juan-ge-zhu.top/common/script4code.js"></script> | 8 | <script type="text/javascript" src="https://www.qin-juan-ge-zhu.top/common/script4code.js"></script> |
9 | <script src="https://www.qin-juan-ge-zhu.top/common/js/myhighlight.js"></script> | ||
10 | </head> | 9 | </head> |
11 | 10 | ||
12 | <body> | 11 | <body> |
13 | <p class="title">博客代码高亮与一键复制</p> | ||
14 | <div class="pandoc"> | 12 | <div class="pandoc"> |
15 | <span class="menu"> | 13 | <div class="main"> |
14 | <p class="title">博客代码高亮与一键复制</p> | ||
15 | <p>作为一名计算机学生,代码是生活里必不可少的组件。因而自年初开始学习前端、购买域名建站的时候,我就曾想过如何在网页里实现代码高亮。奈何才疏学浅,就此搁置。</p> | ||
16 | <p>上个月在搜索如何用代码自行实现 git 基本功能的时候,误打误撞进了大佬 Nikita 的<a href="https://www.leshenko.net/p/ugit/#">μgit | ||
17 | 教程</a>,惊为天人,不仅内容详细,排版也极为美观,尤其是代码的 git diff 显示,可以清晰地看到每一步做了哪些改变,仿佛大佬亲自莅临指导。于是在开启 μgit | ||
18 | 学习(<del>尚未有所推进,笑死</del>,算是个坑,<strong>以后补吧</strong>)的同时,与黄佬共同学习该教程所用到的代码高亮办法,发现是一个 js 插件 | ||
19 | highlight.min.js,探索过程中又找到了一个在此基础上以表格办法为代码添加行号的 js 插件 highlightjs-line-numbers.js,形成了一份草创的为 git 仓库提供 diff | ||
20 | 显示的<a | ||
21 | href="https://www.qin-juan-ge-zhu.top/code/others'code/highlight.html">网页</a>,按照目前的理解尚需一些其他工具,因此该网页几乎等同于完全不会,只能说“欲知后事如何,且听下回分解”了。(一段话两个坑?挖坑小能手实锤!) | ||
22 | </p> | ||
23 | <p>同时,一个多月来我为服务器 vim 做的配置 vimrc 变化较大。万一身边有人学呢?或者,年底服务期到期了这些设置总需要有个备份吧?故而近来想着重新写一份最新的。于是我碰到了之前无法解决的问题:之前 | ||
24 | Markdown | ||
25 | 导出为 html 所使用的工具是 typora,在导出方面几乎无出其右者,然而并不能识别和高亮 vimscript。即使对于其他可识别的代码,导出结果也是标签套标签、css 摞 | ||
26 | css,导出之后无论是修改代码还是更换高亮样式,蜀道之难难于上青天,除非重新导出。</p> | ||
27 | <p>这几件事便成了我为本站建立代码高亮的源动力。</p> | ||
28 | <p>过程的繁琐自不必说,让我们进入正题,<strong>用炫丽的色彩色彩点燃我们的码农世界吧</strong>!</p> | ||
29 | <p>需要注意的是,下文所有 html 使用的链接都是我使用的 url,我大部分替换为了<code>/path/to/……</code>,意在说明这里可以替换为自己实际的 url(官网链接、cdn | ||
30 | 链接、本地链接等),如有遗漏可自行修改。</p> | ||
31 | <h1 id="代码高亮">代码高亮</h1> | ||
32 | <p>现在很多网站的代码高亮插件都是<a href="https://highlightjs.org/">highlight.js</a>,其中文文档<a | ||
33 | href="http://highlight.cndoc.wiki/doc">在此</a>。该插件目前已支持近 200 种编程语言、有 75 套渲染样式,十分完备易用。利用 Vue、npm | ||
34 | 等高端技术的方法就不说了,<del>主要是我也不会</del>,就说说最简单的用法——直接在页面中加入 highlight.js 实现代码高亮。</p> | ||
35 | <p>使用方法极为简单:</p> | ||
16 | <ul> | 36 | <ul> |
17 | <li><a href="#代码高亮">代码高亮</a></li> | 37 | <li>在 html 文档的 head 中直接引入 highlight.min.js 和自己喜欢的 style 的链接 |
18 | <li><a href="#为高亮代码添加行号">为高亮代码添加行号</a></li> | ||
19 | <li><a href="#一键复制">一键复制</a> | ||
20 | <ul> | 38 | <ul> |
21 | <li><a href="#剪贴板有关">剪贴板有关</a></li> | 39 | <li>支持的 style 列表和代码语言在<a href="https://highlightjs.org/static/demo/">官方 |
22 | <li><a href="#修改pre">修改<pre></a></li> | 40 | demo</a>中,可以直接下载整套代码,也可以在 |
23 | <li><a href="#功能实现">功能实现</a></li> | 41 | F12 中只选择自己喜欢的 style 搞下来</li> |
24 | <li><a href="#教程所忘记的">教程所忘记的</a></li> | ||
25 | </ul> | 42 | </ul> |
26 | </li> | 43 | </li> |
27 | <li><a href="#抽成单独的文件">抽成单独的文件</a> | 44 | <li>将代码块用<code><pre><code>……</code></pre></code>包裹</li> |
28 | <ul> | 45 | <li>code 可以选择用 class 来标注语言,如<code><code class="language-c++">……</code></code>,也可以不标注,会自动识别语言 |
29 | <li><a href="#需要额外的css">需要额外的css</a></li> | ||
30 | <li><a href="#引入css">引入css</a></li> | ||
31 | <li><a href="#引入script">引入script</a></li> | ||
32 | <li><a href="#执行代码">执行代码</a></li> | ||
33 | </ul> | ||
34 | </li> | 46 | </li> |
35 | <li><a href="#综合">综合</a></li> | 47 | <li>代码第一行与<code><code></code>标签同行,最后一行可与<code></code></code>不同行,<strong>否则会在第一行之前出现一个空的第 0 |
36 | <li><a href="#还缺点什么吗">还缺点什么吗</a> | 48 | 行,代码块不对称</strong></li> |
37 | <ul> | ||
38 | <li><a href="#Markdown">Markdown</a></li> | ||
39 | <li><a href="#小脚本">小脚本</a></li> | ||
40 | </ul> | ||
41 | </li> | ||
42 | <li><a href="#碎碎念">碎碎念</a></li> | ||
43 | </ul> | 49 | </ul> |
44 | </span> | 50 | <pre><code><html> |
45 | <p>作为一名计算机学生,代码是生活里必不可少的组件。因而自年初开始学习前端、购买域名建站的时候,我就曾想过如何在网页里实现代码高亮。奈何才疏学浅,就此搁置。</p> | ||
46 | <p>上个月在搜索如何用代码自行实现 git 基本功能的时候,误打误撞进了大佬 Nikita 的<a href="https://www.leshenko.net/p/ugit/#">μgit | ||
47 | 教程</a>,惊为天人,不仅内容详细,排版也极为美观,尤其是代码的 git diff 显示,可以清晰地看到每一步做了哪些改变,仿佛大佬亲自莅临指导。于是在开启 μgit | ||
48 | 学习(<del>尚未有所推进,笑死</del>,算是个坑,<strong>以后补吧</strong>)的同时,与黄佬共同学习该教程所用到的代码高亮办法,发现是一个 js 插件 | ||
49 | highlight.min.js,探索过程中又找到了一个在此基础上以表格办法为代码添加行号的 js 插件 highlightjs-line-numbers.js,形成了一份草创的为 git 仓库提供 diff | ||
50 | 显示的<a | ||
51 | href="https://www.qin-juan-ge-zhu.top/code/others'code/highlight.html">网页</a>,按照目前的理解尚需一些其他工具,因此该网页几乎等同于完全不会,只能说“欲知后事如何,且听下回分解”了。(一段话两个坑?挖坑小能手实锤!) | ||
52 | </p> | ||
53 | <p>同时,一个多月来我为服务器 vim 做的配置 vimrc 变化较大。万一身边有人学呢?或者,年底服务期到期了这些设置总需要有个备份吧?故而近来想着重新写一份最新的。于是我碰到了之前无法解决的问题:之前 Markdown | ||
54 | 导出为 html 所使用的工具是 typora,在导出方面几乎无出其右者,然而并不能识别和高亮 vimscript。即使对于其他可识别的代码,导出结果也是标签套标签、css 摞 | ||
55 | css,导出之后无论是修改代码还是更换高亮样式,蜀道之难难于上青天,除非重新导出。</p> | ||
56 | <p>这几件事便成了我为本站建立代码高亮的源动力。</p> | ||
57 | <p>过程的繁琐自不必说,让我们进入正题,<strong>用炫丽的色彩色彩点燃我们的码农世界吧</strong>!</p> | ||
58 | <p>需要注意的是,下文所有 html 使用的链接都是我使用的 url,我大部分替换为了<code>/path/to/……</code>,意在说明这里可以替换为自己实际的 url(官网链接、cdn | ||
59 | 链接、本地链接等),如有遗漏可自行修改。</p> | ||
60 | <h1 id="代码高亮">代码高亮</h1> | ||
61 | <p>现在很多网站的代码高亮插件都是<a href="https://highlightjs.org/">highlight.js</a>,其中文文档<a | ||
62 | href="http://highlight.cndoc.wiki/doc">在此</a>。该插件目前已支持近 200 种编程语言、有 75 套渲染样式,十分完备易用。利用 Vue、npm | ||
63 | 等高端技术的方法就不说了,<del>主要是我也不会</del>,就说说最简单的用法——直接在页面中加入 highlight.js 实现代码高亮。</p> | ||
64 | <p>使用方法极为简单:</p> | ||
65 | <ul> | ||
66 | <li>在 html 文档的 head 中直接引入 highlight.min.js 和自己喜欢的 style 的链接 | ||
67 | <ul> | ||
68 | <li>支持的 style 列表和代码语言在<a href="https://highlightjs.org/static/demo/">官方 demo</a>中,可以直接下载整套代码,也可以在 | ||
69 | F12 中只选择自己喜欢的 style 搞下来</li> | ||
70 | </ul> | ||
71 | </li> | ||
72 | <li>将代码块用<code><pre><code>……</code></pre></code>包裹</li> | ||
73 | <li>code 可以选择用 class 来标注语言,如<code><code class="language-c++">……</code></code>,也可以不标注,会自动识别语言 | ||
74 | </li> | ||
75 | <li>代码第一行与<code><code></code>标签同行,最后一行可与<code></code></code>不同行,<strong>否则会在第一行之前出现一个空的第 0 | ||
76 | 行,代码块不对称</strong></li> | ||
77 | </ul> | ||
78 | <pre><code><html> | ||
79 | <head> | 51 | <head> |
80 | <!-- 选择最喜欢的style --> | 52 | <!-- 选择最喜欢的style --> |
81 | <link | 53 | <link |
@@ -104,14 +76,14 @@ int main() | |||
104 | </div> | 76 | </div> |
105 | </body> | 77 | </body> |
106 | </html></code></pre> | 78 | </html></code></pre> |
107 | <p>我们已经朝着代码块的最终目标迈出了一大步。</p> | 79 | <p>我们已经朝着代码块的最终目标迈出了一大步。</p> |
108 | <h1 id="为高亮代码添加行号">为高亮代码添加行号</h1> | 80 | <h1 id="为高亮代码添加行号">为高亮代码添加行号</h1> |
109 | <p>想想我们的代码编辑器,就会产生一个新诉求:为已经高亮的代码添加行号。没错,前辈大牛与我们的想法完全一致。</p> | 81 | <p>想想我们的代码编辑器,就会产生一个新诉求:为已经高亮的代码添加行号。没错,前辈大牛与我们的想法完全一致。</p> |
110 | <p>在 highlight.js 的基础上实现添加行号的有很多,这里采用的是其中一个,<a | 82 | <p>在 highlight.js 的基础上实现添加行号的有很多,这里采用的是其中一个,<a |
111 | href="https://github.com/wcoder/highlightjs-line-numbers.js/">highlightjs-line-numbers.js</a>。同样地,高端的食材往往只需要最简单的做法(努力为自己的菜找理由.jpg),这里采用直接引用 | 83 | href="https://github.com/wcoder/highlightjs-line-numbers.js/">highlightjs-line-numbers.js</a>。同样地,高端的食材往往只需要最简单的做法(努力为自己的菜找理由.jpg),这里采用直接引用 |
112 | js 的方式。</p> | 84 | js 的方式。</p> |
113 | <p>使用方法同样很简单,我们不得不佩服大佬:只需要在之前的基础上添加两行代码即可。如下:</p> | 85 | <p>使用方法同样很简单,我们不得不佩服大佬:只需要在之前的基础上添加两行代码即可。如下:</p> |
114 | <pre><code><html> | 86 | <pre><code><html> |
115 | <head> | 87 | <head> |
116 | <link | 88 | <link |
117 | rel="stylesheet" | 89 | rel="stylesheet" |
@@ -141,8 +113,8 @@ int main() | |||
141 | </div> | 113 | </div> |
142 | </body> | 114 | </body> |
143 | </html></code></pre> | 115 | </html></code></pre> |
144 | <p>在此基础上,为了使得行号进一步美观,官方甚至还给出了行号的 css,可供按需修改:</p> | 116 | <p>在此基础上,为了使得行号进一步美观,官方甚至还给出了行号的 css,可供按需修改:</p> |
145 | <pre><code>/* for block of numbers */ | 117 | <pre><code>/* for block of numbers */ |
146 | pre code td.hljs-ln-numbers { | 118 | pre code td.hljs-ln-numbers { |
147 | text-align: center; | 119 | text-align: center; |
148 | color: #9c9c9c; | 120 | color: #9c9c9c; |
@@ -158,18 +130,19 @@ pre code td.hljs-ln-code { | |||
158 | padding-left: 1rem; | 130 | padding-left: 1rem; |
159 | border: none; | 131 | border: none; |
160 | }</code></pre> | 132 | }</code></pre> |
161 | <h1 id="一键复制">一键复制</h1> | 133 | <h1 id="一键复制">一键复制</h1> |
162 | <p>代码块的功能越来越齐全,你可曾想过像万恶的 CSDN | 134 | <p>代码块的功能越来越齐全,你可曾想过像万恶的 CSDN |
163 | 搞“登录后复制”那样,来一个一键复制呢?这对于看到网站的人来说是很重要的,否则直接复制下来的代码很容易出现缩进不正确等各种情况,影响心情。<strong>说干就干!</strong></p> | 135 | 搞“登录后复制”那样,来一个一键复制呢?这对于看到网站的人来说是很重要的,否则直接复制下来的代码很容易出现缩进不正确等各种情况,影响心情。<strong>说干就干!</strong></p> |
164 | <p>可是就是这一步,难倒了我整整一天。支持 highlight.js 的一键复制不少,可是支持已经投入使用的 highlightjs-line-numbers.js | 136 | <p>可是就是这一步,难倒了我整整一天。支持 highlight.js 的一键复制不少,可是支持已经投入使用的 highlightjs-line-numbers.js |
165 | 的却不多;在此基础上,还要越简单越好,便于我这个菜鸡看懂和使用,所以像<a href="">这个</a>使用 Vue | 137 | 的却不多;在此基础上,还要越简单越好,便于我这个菜鸡看懂和使用,所以像<a href="">这个</a>使用 Vue |
166 | 还语焉不详的插件遗憾出局。到底还是做网站的心疼做网站的,最终在捣鼓了一下午和一晚上之后,深夜我终于找到了一篇<a | 138 | 还语焉不详的插件遗憾出局。到底还是做网站的心疼做网站的,最终在捣鼓了一下午和一晚上之后,深夜我终于找到了一篇<a |
167 | href="https://savalone.com/javascript/ueditor-highlightjs.html">文章</a>,与我的要求近乎完全一致,而且文章本身用的也是文章所说的代码处理办法,体验结果甚合吾意。 | 139 | href="https://savalone.com/javascript/ueditor-highlightjs.html">文章</a>,与我的要求近乎完全一致,而且文章本身用的也是文章所说的代码处理办法,体验结果甚合吾意。 |
168 | </p> | 140 | </p> |
169 | <h2 id="剪贴板有关">剪贴板有关</h2> | 141 | <h2 id="剪贴板有关">剪贴板有关</h2> |
170 | <p>一键复制与剪贴板有关。在这方面,<a href="https://github.com/zenorocha/clipboard.js">cliploard</a>是一个好用的 js。同样地,先看一下官方 Demo 吧: | 142 | <p>一键复制与剪贴板有关。在这方面,<a href="https://github.com/zenorocha/clipboard.js">cliploard</a>是一个好用的 js。同样地,先看一下官方 |
171 | </p> | 143 | Demo 吧: |
172 | <pre><code><script> | 144 | </p> |
145 | <pre><code><script> | ||
173 | <!-- 1. Define some markup --> | 146 | <!-- 1. Define some markup --> |
174 | <textarea id="bar">hello</textarea> | 147 | <textarea id="bar">hello</textarea> |
175 | <button class="btn" data-clipboard-action="cut" data-clipboard-target="#bar">Cut</button> | 148 | <button class="btn" data-clipboard-action="cut" data-clipboard-target="#bar">Cut</button> |
@@ -186,15 +159,16 @@ pre code td.hljs-ln-code { | |||
186 | console.log(e); | 159 | console.log(e); |
187 | }); | 160 | }); |
188 | </script></code></pre> | 161 | </script></code></pre> |
189 | <p>button 的 data-clipboard-action=“cut” 属性为“剪切”,data-clipboard-action=“copy” 属性为“复制”。然后可以看到 button 的 | 162 | <p>button 的 data-clipboard-action=“cut” 属性为“剪切”,data-clipboard-action=“copy” 属性为“复制”。然后可以看到 button 的 |
190 | data-clipboard-target 属性值 = 要进行复制的目标元素的 id。</p> | 163 | data-clipboard-target 属性值 = 要进行复制的目标元素的 id。</p> |
191 | <p>那么我们就要在每一个 pre 里面添加一个 data-clipboard-target 属性不同的 button 按钮,并且要为这个 pre 增加一个和 button 的 data-clipboard-target | 164 | <p>那么我们就要在每一个 pre 里面添加一个 data-clipboard-target 属性不同的 button 按钮,并且要为这个 pre 增加一个和 button 的 |
192 | 属性一样的 id,最后调用 demo 里的 js。<strong>前进!</strong></p> | 165 | data-clipboard-target |
193 | <h2 id="修改pre">修改<code><pre></code></h2> | 166 | 属性一样的 id,最后调用 demo 里的 js。<strong>前进!</strong></p> |
194 | <p>首先,引入 clipboard.js:</p> | 167 | <h2 id="修改pre">修改<code><pre></code></h2> |
195 | <pre><code><script src="url/clipboard.min.js"></script></code></pre> | 168 | <p>首先,引入 clipboard.js:</p> |
196 | <p>为每一个 pre 添加复制按钮:</p> | 169 | <pre><code><script src="url/clipboard.min.js"></script></code></pre> |
197 | <pre><code><script type="text/javascript"> | 170 | <p>为每一个 pre 添加复制按钮:</p> |
171 | <pre><code><script type="text/javascript"> | ||
198 | var allpre = document.getElementsByTagName("pre"); | 172 | var allpre = document.getElementsByTagName("pre"); |
199 | for (i = 0; i < allpre.length; i++) { | 173 | for (i = 0; i < allpre.length; i++) { |
200 | var onepre = document.getElementsByTagName("pre")[i]; | 174 | var onepre = document.getElementsByTagName("pre")[i]; |
@@ -207,22 +181,22 @@ pre code td.hljs-ln-code { | |||
207 | mycode; | 181 | mycode; |
208 | } | 182 | } |
209 | </script></code></pre> | 183 | </script></code></pre> |
210 | <p>为 pre 循环增加 id,并为 pre 内的 button 增加 data-clipboard-target 属性:</p> | 184 | <p>为 pre 循环增加 id,并为 pre 内的 button 增加 data-clipboard-target 属性:</p> |
211 | <pre><code><script> | 185 | <pre><code><script> |
212 | $("pre").each(function () { | 186 | $("pre").each(function () { |
213 | $(this).attr("id", "pre" + $(this).index()); | 187 | $(this).attr("id", "pre" + $(this).index()); |
214 | var btns = $(this).find("button"); | 188 | var btns = $(this).find("button"); |
215 | $(btns).attr("data-clipboard-target", "#pre" + $(this).index()); | 189 | $(btns).attr("data-clipboard-target", "#pre" + $(this).index()); |
216 | }); | 190 | }); |
217 | </script></code></pre> | 191 | </script></code></pre> |
218 | <h2 id="功能实现">功能实现</h2> | 192 | <h2 id="功能实现">功能实现</h2> |
219 | <p>为了简单起见,我们可以将之前的代码高亮与行号放在这里,也就是上边的各个 script 之后:</p> | 193 | <p>为了简单起见,我们可以将之前的代码高亮与行号放在这里,也就是上边的各个 script 之后:</p> |
220 | <pre><code><script> | 194 | <pre><code><script> |
221 | hljs.highlightAll(); | 195 | hljs.highlightAll(); |
222 | hljs.initLineNumbersOnLoad(); | 196 | hljs.initLineNumbersOnLoad(); |
223 | </script></code></pre> | 197 | </script></code></pre> |
224 | <p>而后直接复制 demo 目录内 target-textarea.html 的 js 代码:</p> | 198 | <p>而后直接复制 demo 目录内 target-textarea.html 的 js 代码:</p> |
225 | <pre><code><!--这个是官方 demo 的用法--> | 199 | <pre><code><!--这个是官方 demo 的用法--> |
226 | <script> | 200 | <script> |
227 | var clipboard = new ClipboardJS(".btn"); | 201 | var clipboard = new ClipboardJS(".btn"); |
228 | clipboard.on("success", function (e) { | 202 | clipboard.on("success", function (e) { |
@@ -232,8 +206,8 @@ pre code td.hljs-ln-code { | |||
232 | console.log(e); | 206 | console.log(e); |
233 | }); | 207 | }); |
234 | </script></code></pre> | 208 | </script></code></pre> |
235 | <p>原教程中提供的 css:</p> | 209 | <p>原教程中提供的 css:</p> |
236 | <pre><code>pre { | 210 | <pre><code>pre { |
237 | position: relative; | 211 | position: relative; |
238 | } | 212 | } |
239 | pre .btn { | 213 | pre .btn { |
@@ -251,10 +225,10 @@ pre .btn:hover { | |||
251 | pre:hover .btn { | 225 | pre:hover .btn { |
252 | display: block; | 226 | display: block; |
253 | }</code></pre> | 227 | }</code></pre> |
254 | <h2 id="教程所忘记的">教程所忘记的</h2> | 228 | <h2 id="教程所忘记的">教程所忘记的</h2> |
255 | <p>除此之外,由于一键复制的某些代码与前边关联,且需要足够的时间等待文档加载结束再执行,因而所有上述功能代码需要放置在文档末尾。</p> | 229 | <p>除此之外,由于一键复制的某些代码与前边关联,且需要足够的时间等待文档加载结束再执行,因而所有上述功能代码需要放置在文档末尾。</p> |
256 | <p>就好了?我做到这的时候也这么想。可惜事与愿违,如果我们仅仅是按照上边已经说的去写开头的那份 Hello World,我们会得到如下一篇文档。</p> | 230 | <p>就好了?我做到这的时候也这么想。可惜事与愿违,如果我们仅仅是按照上边已经说的去写开头的那份 Hello World,我们会得到如下一篇文档。</p> |
257 | <pre><code><html> | 231 | <pre><code><html> |
258 | <head> | 232 | <head> |
259 | <!-- style css引入 --> | 233 | <!-- style css引入 --> |
260 | <link | 234 | <link |
@@ -353,16 +327,16 @@ int main() | |||
353 | }); | 327 | }); |
354 | </script> | 328 | </script> |
355 | </html></code></pre> | 329 | </html></code></pre> |
356 | <p>直接打开浏览器看效果,会发现如下几个问题:</p> | 330 | <p>直接打开浏览器看效果,会发现如下几个问题:</p> |
357 | <ul> | 331 | <ul> |
358 | <li>“复制”与“已复制”同时出现,且后者被前者遮盖,点击“复制”时候也会出现但还是被遮盖;而我们需要的是一般情况“复制”,复制过了才“已复制”</li> | 332 | <li>“复制”与“已复制”同时出现,且后者被前者遮盖,点击“复制”时候也会出现但还是被遮盖;而我们需要的是一般情况“复制”,复制过了才“已复制”</li> |
359 | <li>点击“复制”的时候,复制到的东西把“复制”这两个字也复制进去了</li> | 333 | <li>点击“复制”的时候,复制到的东西把“复制”这两个字也复制进去了</li> |
360 | <li>复制的时候所有内容会被全选中,一般默认是蓝底白字,十分有碍观瞻,我们需要的是点击“复制”的时候代码展示没有变化(选不选中的,看不见就行了)</li> | 334 | <li>复制的时候所有内容会被全选中,一般默认是蓝底白字,十分有碍观瞻,我们需要的是点击“复制”的时候代码展示没有变化(选不选中的,看不见就行了)</li> |
361 | <li>“复制”与“已复制”字体大小、按钮大小均不一致</li> | 335 | <li>“复制”与“已复制”字体大小、按钮大小均不一致</li> |
362 | <li>还一个啥问题来着?忘了,最近脑子不好使,似乎想闹独立。</li> | 336 | <li>还一个啥问题来着?忘了,最近脑子不好使,似乎想闹独立。</li> |
363 | </ul> | 337 | </ul> |
364 | <p>总而言之,教程内容里差点东西。由于教程本身使用的也是这一套代码,F12 理所当然地能解决一切。最后我发现,作者漏了几段重要的 css:</p> | 338 | <p>总而言之,教程内容里差点东西。由于教程本身使用的也是这一套代码,F12 理所当然地能解决一切。最后我发现,作者漏了几段重要的 css:</p> |
365 | <pre><code>pre .btn-tip { | 339 | <pre><code>pre .btn-tip { |
366 | display: none; | 340 | display: none; |
367 | position: absolute; | 341 | position: absolute; |
368 | top: 0px; | 342 | top: 0px; |
@@ -405,26 +379,27 @@ int main() | |||
405 | code ::selection { | 379 | code ::selection { |
406 | background-color: rgba(0, 0, 0, 0); | 380 | background-color: rgba(0, 0, 0, 0); |
407 | }</code></pre> | 381 | }</code></pre> |
408 | <p>除了加了注释说明功能的地方之外,剩的是一些不甚打紧的参数,而且效果也比较满意,因此不需要修改,直接将上述 css 加入 style 标签内就好了。此时再打开这个 html,Hello World | 382 | <p>除了加了注释说明功能的地方之外,剩的是一些不甚打紧的参数,而且效果也比较满意,因此不需要修改,直接将上述 css 加入 style 标签内就好了。此时再打开这个 html,Hello World |
409 | 已经高亮,带有行号和一键复制,使用体验丝滑流畅。一切都是那么和谐,仿佛自来就是如此,什么都未发生过。</p> | 383 | 已经高亮,带有行号和一键复制,使用体验丝滑流畅。一切都是那么和谐,仿佛自来就是如此,什么都未发生过。</p> |
410 | <p>历尽千辛万苦,我们即将来到旅程的终点。</p> | 384 | <p>历尽千辛万苦,我们即将来到旅程的终点。</p> |
411 | <p><em><strong>吗?</strong></em></p> | 385 | <p><em><strong>吗?</strong></em></p> |
412 | <h1 id="抽成单独的文件">抽成单独的文件</h1> | 386 | <h1 id="抽成单独的文件">抽成单独的文件</h1> |
413 | <p>样例程序已经达到预期效果,但为了做网站,我们的目标远不止于此。我们需要的是<strong>将所需内容尽可能简单地引入已经写好的文档</strong>(我一般是用 pandoc/Typora 将 Markdown 导出为 | 387 | <p>样例程序已经达到预期效果,但为了做网站,我们的目标远不止于此。我们需要的是<strong>将所需内容尽可能简单地引入已经写好的文档</strong>(我一般是用 pandoc/Typora 将 Markdown |
414 | html),最好只是一个文件。没错,我们最后要做的,是将上边已经有的 script 标签、link 标签、style 标签和 js 代码写在同一份 js 文件里,只需要在 head 中引用该文件即可。</p> | 388 | 导出为 |
415 | <p>首先,记录一下现有的要求:</p> | 389 | html),最好只是一个文件。没错,我们最后要做的,是将上边已经有的 script 标签、link 标签、style 标签和 js 代码写在同一份 js 文件里,只需要在 head 中引用该文件即可。</p> |
416 | <ul> | 390 | <p>首先,记录一下现有的要求:</p> |
417 | <li>head 中的标签 | 391 | <ul> |
418 | <ul> | 392 | <li>head 中的标签 |
419 | <li>需要引入 style 样式,可以考虑加随机 style</li> | 393 | <ul> |
420 | <li>jquery 需要在其他的 script 之前引入,highlight.js 要在 highlightjs-line-number 之前引入,clipboard 最后引入</li> | 394 | <li>需要引入 style 样式,可以考虑加随机 style</li> |
421 | <li>所有要执行的 js 代码必须在文档整体完成之后再执行</li> | 395 | <li>jquery 需要在其他的 script 之前引入,highlight.js 要在 highlightjs-line-number 之前引入,clipboard 最后引入</li> |
422 | </ul> | 396 | <li>所有要执行的 js 代码必须在文档整体完成之后再执行</li> |
423 | </li> | 397 | </ul> |
424 | </ul> | 398 | </li> |
425 | <p>经过多次试验和黄四郎的悉心指导,得到了以下的方法。</p> | 399 | </ul> |
426 | <h2 id="需要的额外-css">需要的额外 css</h2> | 400 | <p>经过多次试验和黄四郎的悉心指导,得到了以下的方法。</p> |
427 | <pre><code>/* highlight.css */ | 401 | <h2 id="需要的额外-css">需要的额外 css</h2> |
402 | <pre><code>/* highlight.css */ | ||
428 | 403 | ||
429 | /* for block of numbers */ | 404 | /* for block of numbers */ |
430 | pre code td.hljs-ln-numbers { | 405 | pre code td.hljs-ln-numbers { |
@@ -509,20 +484,20 @@ pre .btn-tip { | |||
509 | code ::selection { | 484 | code ::selection { |
510 | background-color: rgba(0, 0, 0, 0); | 485 | background-color: rgba(0, 0, 0, 0); |
511 | }</code></pre> | 486 | }</code></pre> |
512 | <h2 id="引入-css">引入 css</h2> | 487 | <h2 id="引入-css">引入 css</h2> |
513 | <p>首先写一个为文档引入 css 的 js 函数:</p> | 488 | <p>首先写一个为文档引入 css 的 js 函数:</p> |
514 | <pre><code>function addLink(href, rel = "stylesheet") { | 489 | <pre><code>function addLink(href, rel = "stylesheet") { |
515 | // 默认为stylesheet | 490 | // 默认为stylesheet |
516 | const link = document.createElement("link"); | 491 | const link = document.createElement("link"); |
517 | link.rel = rel; | 492 | link.rel = rel; |
518 | link.href = href; | 493 | link.href = href; |
519 | document.head.appendChild(link); | 494 | document.head.appendChild(link); |
520 | }</code></pre> | 495 | }</code></pre> |
521 | <p>而后引入上述的额外 css:</p> | 496 | <p>而后引入上述的额外 css:</p> |
522 | <pre><code>// 加载高亮所需特殊css | 497 | <pre><code>// 加载高亮所需特殊css |
523 | addLink("/path/to/highlight.css");</code></pre> | 498 | addLink("/path/to/highlight.css");</code></pre> |
524 | <p>还需要选择高亮 style 样式。不知道你是否和我一样有选择困难症?每次写一篇文档都去选一个 style 着实很烦。不如随机抽取:</p> | 499 | <p>还需要选择高亮 style 样式。不知道你是否和我一样有选择困难症?每次写一篇文档都去选一个 style 着实很烦。不如随机抽取:</p> |
525 | <pre><code>// 此处负责随机选择一个代码高亮style的css并加载 | 500 | <pre><code>// 此处负责随机选择一个代码高亮style的css并加载 |
526 | // 数组内是现highlight.js所有插件名称,共计75个 | 501 | // 数组内是现highlight.js所有插件名称,共计75个 |
527 | const styles = [ | 502 | const styles = [ |
528 | "a11y-dark.min.css", | 503 | "a11y-dark.min.css", |
@@ -604,10 +579,10 @@ const styles = [ | |||
604 | 579 | ||
605 | const href = "/path/to/styles/" + styles[~~(Math.random() * styles.length)]; | 580 | const href = "/path/to/styles/" + styles[~~(Math.random() * styles.length)]; |
606 | addLink(href);</code></pre> | 581 | addLink(href);</code></pre> |
607 | <p>于是我们完成了 style 的高亮 style 随机选择。</p> | 582 | <p>于是我们完成了 style 的高亮 style 随机选择。</p> |
608 | <h2 id="引入-script">引入 script</h2> | 583 | <h2 id="引入-script">引入 script</h2> |
609 | <p>老规矩,先写一个引入 script 的函数:</p> | 584 | <p>老规矩,先写一个引入 script 的函数:</p> |
610 | <pre><code>// 加js的函数 | 585 | <pre><code>// 加js的函数 |
611 | function addScript(url, async = true) { | 586 | function addScript(url, async = true) { |
612 | //默认先到先得地加载 | 587 | //默认先到先得地加载 |
613 | const script = document.createElement("script"); | 588 | const script = document.createElement("script"); |
@@ -615,9 +590,9 @@ function addScript(url, async = true) { | |||
615 | script.async = async; | 590 | script.async = async; |
616 | document.head.appendChild(script); | 591 | document.head.appendChild(script); |
617 | }</code></pre> | 592 | }</code></pre> |
618 | <p>接下来按照上边说过的顺序(先 jQuery,再 highlight.min.js,而后 highlightjs-line-numbers.js,最后 | 593 | <p>接下来按照上边说过的顺序(先 jQuery,再 highlight.min.js,而后 highlightjs-line-numbers.js,最后 |
619 | clipboard.js)进行加载。为了防止浏览器并发地加载,<strong>必须规定<code>async=false</code></strong>。</p> | 594 | clipboard.js)进行加载。为了防止浏览器并发地加载,<strong>必须规定<code>async=false</code></strong>。</p> |
620 | <pre><code>// 此处是各个插件 | 595 | <pre><code>// 此处是各个插件 |
621 | // 首先放置最高的jQuery备用 | 596 | // 首先放置最高的jQuery备用 |
622 | // 而后是highlight.min.js高亮代码 | 597 | // 而后是highlight.min.js高亮代码 |
623 | // 再加行号 | 598 | // 再加行号 |
@@ -633,9 +608,9 @@ for (let i in url) { | |||
633 | // 要求必须按顺序加载 | 608 | // 要求必须按顺序加载 |
634 | addScript(url[i], false); | 609 | addScript(url[i], false); |
635 | }</code></pre> | 610 | }</code></pre> |
636 | <h2 id="执行代码">执行代码</h2> | 611 | <h2 id="执行代码">执行代码</h2> |
637 | <p>最后、也是最重要的部分,当然是要在文档末尾才执行的代码啦~所以我们要在原功能代码的基础上套一层<code>onload()</code>,如下:</p> | 612 | <p>最后、也是最重要的部分,当然是要在文档末尾才执行的代码啦~所以我们要在原功能代码的基础上套一层<code>onload()</code>,如下:</p> |
638 | <pre><code>// 以下代码负责使用上述模块,因而必须在html文档整体完成之后加载 | 613 | <pre><code>// 以下代码负责使用上述模块,因而必须在html文档整体完成之后加载 |
639 | onload = () => { | 614 | onload = () => { |
640 | // 导出的源码由<pre><code>……</code></pre>包裹,符合highlight.min.js要求 | 615 | // 导出的源码由<pre><code>……</code></pre>包裹,符合highlight.min.js要求 |
641 | // 需要在code之前加入复制按钮,要求点击之后显示已复制 | 616 | // 需要在code之前加入复制按钮,要求点击之后显示已复制 |
@@ -673,9 +648,9 @@ onload = () => { | |||
673 | console.log(e); | 648 | console.log(e); |
674 | }); | 649 | }); |
675 | };</code></pre> | 650 | };</code></pre> |
676 | <h1 id="综合">综合</h1> | 651 | <h1 id="综合">综合</h1> |
677 | <p>总而言之,现在我们得到了两份文件:</p> | 652 | <p>总而言之,现在我们得到了两份文件:</p> |
678 | <pre><code>/* highlight.css */ | 653 | <pre><code>/* highlight.css */ |
679 | 654 | ||
680 | /* for block of numbers */ | 655 | /* for block of numbers */ |
681 | pre code td.hljs-ln-numbers { | 656 | pre code td.hljs-ln-numbers { |
@@ -760,8 +735,8 @@ pre .btn-tip { | |||
760 | code ::selection { | 735 | code ::selection { |
761 | background-color: rgba(0, 0, 0, 0); | 736 | background-color: rgba(0, 0, 0, 0); |
762 | }</code></pre> | 737 | }</code></pre> |
763 | <p>还有一份 js:</p> | 738 | <p>还有一份 js:</p> |
764 | <pre><code>// myhighlight.js | 739 | <pre><code>// myhighlight.js |
765 | // 代码高亮、加行号、加一键复制功能 | 740 | // 代码高亮、加行号、加一键复制功能 |
766 | 741 | ||
767 | // 加js的函数 | 742 | // 加js的函数 |
@@ -923,8 +898,8 @@ onload = () => { | |||
923 | console.log(e); | 898 | console.log(e); |
924 | }); | 899 | }); |
925 | };</code></pre> | 900 | };</code></pre> |
926 | <p>使用方法也很简单,只需要引入上边这个 myhighlight.js 即可。比如之前写好的 Hello World 页面:</p> | 901 | <p>使用方法也很简单,只需要引入上边这个 myhighlight.js 即可。比如之前写好的 Hello World 页面:</p> |
927 | <pre><code><html> | 902 | <pre><code><html> |
928 | <head> | 903 | <head> |
929 | <title>Hello World展示</title> | 904 | <title>Hello World展示</title> |
930 | <!-- 前边需要什么css/js还可以自己添 --> | 905 | <!-- 前边需要什么css/js还可以自己添 --> |
@@ -947,23 +922,23 @@ int main() | |||
947 | </div> | 922 | </div> |
948 | </body> | 923 | </body> |
949 | </html></code></pre> | 924 | </html></code></pre> |
950 | <p><strong>代码多跑路,<kbd>Ctrl+c/v</kbd>少跑腿,国安民乐,岂不美哉?</strong></p> | 925 | <p><strong>代码多跑路,<kbd>Ctrl+c/v</kbd>少跑腿,国安民乐,岂不美哉?</strong></p> |
951 | <h1 id="还缺点什么吗">还缺点什么吗?</h1> | 926 | <h1 id="还缺点什么吗">还缺点什么吗?</h1> |
952 | <p>“还缺?这不已经好了吗?”没错,代码部分好了,但对我们而言差点东西。</p> | 927 | <p>“还缺?这不已经好了吗?”没错,代码部分好了,但对我们而言差点东西。</p> |
953 | <h2 id="markdown">Markdown</h2> | 928 | <h2 id="markdown">Markdown</h2> |
954 | <p>根据上边已经有的代码高亮,现在完成手搓 html 写网页已经很轻松加愉快了,常用的无非就是那几个标签罢了。为了更简单一些,难道不能写 Markdown 吗?当然可以!</p> | 929 | <p>根据上边已经有的代码高亮,现在完成手搓 html 写网页已经很轻松加愉快了,常用的无非就是那几个标签罢了。为了更简单一些,难道不能写 Markdown 吗?当然可以!</p> |
955 | <p>有两个特别好的小工具,一个叫<a href="https://typora.io/">Typora</a>,另一个叫<a href="https://pandoc.org/">pandoc</a>。前者是专门的 | 930 | <p>有两个特别好的小工具,一个叫<a href="https://typora.io/">Typora</a>,另一个叫<a href="https://pandoc.org/">pandoc</a>。前者是专门的 |
956 | Markdown 编辑器,可以做到实时预览、所见即所得,主题样式也可以自由选择和安装;后者则是一个做文档转换的命令行小工具。二者都可以实现 Markdown 转 html。笔者目前是在 Linux | 931 | Markdown 编辑器,可以做到实时预览、所见即所得,主题样式也可以自由选择和安装;后者则是一个做文档转换的命令行小工具。二者都可以实现 Markdown 转 html。笔者目前是在 Linux |
957 | 里写这篇文章,因而现在用的是 pandoc。</p> | 932 | 里写这篇文章,因而现在用的是 pandoc。</p> |
958 | <p>有几个点需要注意:</p> | 933 | <p>有几个点需要注意:</p> |
959 | <ul> | 934 | <ul> |
960 | <li>Typora 是买断制收费,刚下载会有 15 天试用期,如需购买则目前是$14.99(合¥ 89.00),一个账号最多可以同时在三个口使用(也就是一个号最多能供三个人用,可以合买)</li> | 935 | <li>Typora 是买断制收费,刚下载会有 15 天试用期,如需购买则目前是$14.99(合¥ 89.00),一个账号最多可以同时在三个口使用(也就是一个号最多能供三个人用,可以合买)</li> |
961 | <li>Typora 一部分导出功能需要 pandoc 支持</li> | 936 | <li>Typora 一部分导出功能需要 pandoc 支持</li> |
962 | <li>pandoc 在各种文件类型(包括 Markdown 在内)导出为 pdf 时需要 LaTeX 支持,因而如果没有 LaTeX 那就不要导出为 pdf。</li> | 937 | <li>pandoc 在各种文件类型(包括 Markdown 在内)导出为 pdf 时需要 LaTeX 支持,因而如果没有 LaTeX 那就不要导出为 pdf。</li> |
963 | <li>使用上述两种工具导出 Markdown 时,一般的代码会自带高亮,但是此种高亮是由 css 和标签一层一层摞起来的,不便于更改代码本身和代码样式,更不可能实现上述的一键复制。因而笔者建议,在编写 | 938 | <li>使用上述两种工具导出 Markdown 时,一般的代码会自带高亮,但是此种高亮是由 css 和标签一层一层摞起来的,不便于更改代码本身和代码样式,更不可能实现上述的一键复制。因而笔者建议,在编写 |
964 | Markdown 时候可以标明代码块用的语言,导出之前全部删掉。如:</li> | 939 | Markdown 时候可以标明代码块用的语言,导出之前全部删掉。如:</li> |
965 | </ul> | 940 | </ul> |
966 | <pre><code><!-- 下边用三个`作代码块示例好像不识别,改用···,请注意 --> | 941 | <pre><code><!-- 下边用三个`作代码块示例好像不识别,改用···,请注意 --> |
967 | 942 | ||
968 | <!-- 写的时候 --> | 943 | <!-- 写的时候 --> |
969 | 944 | ||
@@ -976,9 +951,9 @@ int main() | |||
976 | ··· | 951 | ··· |
977 | #include <iostream> | 952 | #include <iostream> |
978 | ···</code></pre> | 953 | ···</code></pre> |
979 | <h2 id="小脚本">小脚本</h2> | 954 | <h2 id="小脚本">小脚本</h2> |
980 | <p>pandoc 导出十分方便,要改造为我们所需的 html 还需要一些批量处理。这里我写了两个脚本,按需取用。</p> | 955 | <p>pandoc 导出十分方便,要改造为我们所需的 html 还需要一些批量处理。这里我写了两个脚本,按需取用。</p> |
981 | <pre><code># vime.sh | 956 | <pre><code># vime.sh |
982 | # 本文件用来在命令行里执行vim的文件操作 | 957 | # 本文件用来在命令行里执行vim的文件操作 |
983 | #!/bin/bash | 958 | #!/bin/bash |
984 | 959 | ||
@@ -989,8 +964,8 @@ echo $2 | |||
989 | read -n 1 | 964 | read -n 1 |
990 | # 执行 | 965 | # 执行 |
991 | find -name "$1" -exec sed -i "$2" {} \;</code></pre> | 966 | find -name "$1" -exec sed -i "$2" {} \;</code></pre> |
992 | <p>另一个脚本:</p> | 967 | <p>另一个脚本:</p> |
993 | <pre><code># pan4html.sh | 968 | <pre><code># pan4html.sh |
994 | #!/bin/bash | 969 | #!/bin/bash |
995 | 970 | ||
996 | # 这一行原想删除导出文件的style标签,好像没起作用 | 971 | # 这一行原想删除导出文件的style标签,好像没起作用 |
@@ -1008,13 +983,14 @@ vime $1 "s/<\/body>/<\/div><\/body>/g" | |||
1008 | # 从而实现表格居中、表内文字左对齐 | 983 | # 从而实现表格居中、表内文字左对齐 |
1009 | vime $1 "s/<table>/<div class=\"table-div\"><table>/g" | 984 | vime $1 "s/<table>/<div class=\"table-div\"><table>/g" |
1010 | vime $1 "s/<\/table>/<\/table><\/div>/g"</code></pre> | 985 | vime $1 "s/<\/table>/<\/table><\/div>/g"</code></pre> |
1011 | <h1 id="碎碎念">碎碎念</h1> | 986 | <h1 id="碎碎念">碎碎念</h1> |
1012 | <p>看起来文章内容很长,实际核心内容很短。核心内容很短,但探索的经历很长。</p> | 987 | <p>看起来文章内容很长,实际核心内容很短。核心内容很短,但探索的经历很长。</p> |
1013 | <p>开头已经说过,之所以需要做代码高亮、行号、一键复制功能,是因为 pandoc 和 Typora 这两个我常用的 Markdown 导出工具均不支持 vimscript | 988 | <p>开头已经说过,之所以需要做代码高亮、行号、一键复制功能,是因为 pandoc 和 Typora 这两个我常用的 Markdown 导出工具均不支持 vimscript |
1014 | 高亮。二者实际上在导出方面做的非常好,绝大多数语言都支持高亮,审美也相当不错,但是由于这一点问题,居然使我弄出了一键复制,也还是很令我自己吃惊的。</p> | 989 | 高亮。二者实际上在导出方面做的非常好,绝大多数语言都支持高亮,审美也相当不错,但是由于这一点问题,居然使我弄出了一键复制,也还是很令我自己吃惊的。</p> |
1015 | <p>现在代码块的功能可云大备,也许以后大多数文章都会改用这一套代码高亮吧。大概是不会再改了。</p> | 990 | <p>现在代码块的功能可云大备,也许以后大多数文章都会改用这一套代码高亮吧。大概是不会再改了。</p> |
1016 | <p class="time">2023.7.8</p> | 991 | <p class="time">2023.7.8</p> |
1017 | <script src="https://www.qin-juan-ge-zhu.top/common/js/comment.js"></script> | 992 | <script src="https://www.qin-juan-ge-zhu.top/common/js/comment.js"></script> |
993 | </div> | ||
1018 | </div> | 994 | </div> |
1019 | </body> | 995 | </body> |
1020 | 996 | ||
diff --git a/code/linux/aliyun_cloud.html b/code/linux/aliyun_cloud.html index 4851312..dd1e429 100644 --- a/code/linux/aliyun_cloud.html +++ b/code/linux/aliyun_cloud.html | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | <head> | 4 | <head> |
5 | <meta charset="utf-8" /> | 5 | <meta charset="utf-8" /> |
6 | <meta name="generator" content="pandoc" /> | ||
6 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> | 7 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> |
7 | <title>我的免费云服</title> | 8 | <title>我的免费云服</title> |
8 | <link rel="stylesheet" href="https://www.qin-juan-ge-zhu.top/common/CSS/pandoc.css"> | 9 | <link rel="stylesheet" href="https://www.qin-juan-ge-zhu.top/common/CSS/pandoc.css"> |
@@ -30,16 +31,15 @@ | |||
30 | <p>实验学习过程中会发给一个临时账号,自动创建一个临时的实例(服务器)供实验之用,时长 1h。讲真,阿里云的实验学习做的非常好,实验文档就在实验界面旁边,非常方便。B | 31 | <p>实验学习过程中会发给一个临时账号,自动创建一个临时的实例(服务器)供实验之用,时长 1h。讲真,阿里云的实验学习做的非常好,实验文档就在实验界面旁边,非常方便。B |
31 | 站/油管/知乎等诸多平台都有这个实验的详细教程可以参考。</p> | 32 | 站/油管/知乎等诸多平台都有这个实验的详细教程可以参考。</p> |
32 | <p>另外,由于是一个临时账号,我个人建议另找一个浏览器做实验,方便和自己现在用的帐户/ECS 实例区别开来。</p> | 33 | <p>另外,由于是一个临时账号,我个人建议另找一个浏览器做实验,方便和自己现在用的帐户/ECS 实例区别开来。</p> |
33 | <h1 id="服器配置">服器配置</h1> | 34 | <h2 id="件配置">件配置</h2> |
34 | <p>服务器硬件配置应该都是固定的吧?CPU 双核,内存 2G,硬盘 40G,带宽 1MBps。我个人觉得这个配置还是挺不错的,毕竟是白嫖,要求也不能太高了不是?</p> | 35 | <p>服务器硬件配置应该都是固定的吧?CPU 双核,内存 2G,硬盘 40G,带宽 1MBps。我个人觉得这个配置还是挺不错的,毕竟是白嫖,要求也不能太高了不是?</p> |
35 | <p>操作系统方面,由于个人比较喜欢纯命令行操作,所以选择了 Ubuntu22.04 LTS,我的虚拟机也是这个版本,相对而言会比其他发行版更熟悉一些。</p> | 36 | <p>操作系统方面,由于个人比较喜欢纯命令行操作,所以选择了 Ubuntu22.04 LTS,我的虚拟机也是这个版本,相对而言会比其他发行版更熟悉一些。</p> |
36 | <h2 id="服务器初始化">服务器初始化</h2> | 37 | <h1 id="服务器初始化">服务器初始化</h1> |
37 | <p>在跟着创建实例的要求一步步做好之后,我们就拥有了一台属于自己的服务器了,并已经有了根用户 root。接下来,我们需要做一些初始化的工作。</p> | 38 | <p>在跟着创建实例的要求一步步做好之后,我们就拥有了一台属于自己的服务器了,并已经有了根用户 root。接下来,我们需要做一些初始化的工作。</p> |
38 | <h3 id="创建新用户">创建新用户</h3> | 39 | <h2 id="创建新用户">创建新用户</h2> |
39 | <p>众所周知,<strong>为了安全起见,我们需要一个非 root 但具有 sudo | 40 | <p>众所周知,<strong>为了安全起见,我们需要一个非 root 但具有 sudo |
40 | 权限的用户来进行日常操作</strong>。这里我创建了一个名为<kbd>player</kbd>的用户并设置了密码,然后将其加入 | 41 | 权限的用户来进行日常操作</strong>。这里我创建了一个名为<kbd>player</kbd>的用户并设置了密码,然后将其加入 sudo 组。</p> |
41 | sudo 组。</p> | 42 | <pre><code># 创建新用户,-m参数创建用户,-d参数手动指定用户的主目录 |
42 | <pre><code class="language-bash"># 创建新用户,-m参数创建用户,-d参数手动指定用户的主目录 | ||
43 | sudo useradd -m player -d /home/player | 43 | sudo useradd -m player -d /home/player |
44 | # 如需指定默认shell,可以加上-s参数。 | 44 | # 如需指定默认shell,可以加上-s参数。 |
45 | # 这里需要注意,一般意义上bash是sh的超集,因此sh能干的bash一般都能干,所以这里一般需要指定为bash。 | 45 | # 这里需要注意,一般意义上bash是sh的超集,因此sh能干的bash一般都能干,所以这里一般需要指定为bash。 |
@@ -54,26 +54,11 @@ sudo apt install vim | |||
54 | 54 | ||
55 | cd /etc | 55 | cd /etc |
56 | sudo vim sudoers | 56 | sudo vim sudoers |
57 | # 找到root ALL=(ALL:ALL) ALL,按o新开一行,然后写一份一样的,把root改成player | 57 | # 找到root ALL=(ALL:ALL) ALL, |
58 | # 按ESC,输入:wq保存退出</code></pre> | 58 | # 新开一行然后写一份一样的,把root改成player,保存退出</code></pre> |
59 | <p>这时我们会发现一个很操蛋的事情,“为啥命令提示符之前不显示当前用户名和当前路径嘞?这岂不是每次看路径都需要<kbd>pwd</kbd>吗?烦不烦啊!”别急,问题很好修改。</p> | ||
60 | <pre><code class="language-bash">cd /home/player | ||
61 | vim .bashrc | ||
62 | # 找到PS1=,将其修改为PS1="\u@\h:\w\$" | ||
63 | # 按ESC,输入:wq保存退出</code></pre> | ||
64 | <p>修改退出之后似乎一切都没有变化。我们需要重启一下服务器。</p> | ||
65 | <pre><code>sudo reboot</code></pre> | ||
66 | <p>重新连接之后,也许还是没有变化,我就是这样的。后来在处理其它问题的时候,我发现了根本原因所在:我 TM 创建用户的时候忘了加<kbd>-s</kbd>参数,导致新用户的默认 shell | ||
67 | 是<kbd>sh</kbd>而不是<kbd>bash</kbd>。所以,我们需要修改一下新用户的默认 shell。</p> | ||
68 | <pre><code class="language-bash"># 查看当前用户的默认shell | ||
69 | echo $SHELL | ||
70 | |||
71 | # 修改默认shell | ||
72 | sudo chsh -s /bin/bash player</code></pre> | ||
73 | <p>这时再重启服务器,就会发现,一切都正常了,一切是那么美好。</p> | ||
74 | <h2 id="安装软件">安装软件</h2> | 59 | <h2 id="安装软件">安装软件</h2> |
75 | <p>经历了上边的配置,现在我们拥有了一台可以正常使用的服务器。服务器是为了什么?开发!开发!开发!所以,我们需要安装一些开发所需的软件。</p> | 60 | <p>经历了上边的配置,现在我们拥有了一台可以正常使用的服务器。服务器是为了什么?开发!开发!开发!所以,我们需要安装一些开发所需的软件。</p> |
76 | <pre><code class="language-bash"># 如需添加软件源,可以先执行下边的命令 | 61 | <pre><code># 如需添加软件源,可以先执行下边的命令 |
77 | # 备份软件源 | 62 | # 备份软件源 |
78 | sudo cp /etc/apt/sources.list /etc/apt/sources.list.old | 63 | sudo cp /etc/apt/sources.list /etc/apt/sources.list.old |
79 | # 修改软件源 | 64 | # 修改软件源 |
@@ -98,18 +83,169 @@ sudo apt install gcc | |||
98 | sudo apt install make cmake | 83 | sudo apt install make cmake |
99 | 84 | ||
100 | # 剩下需要安装的软件,可以自行搜索</code></pre> | 85 | # 剩下需要安装的软件,可以自行搜索</code></pre> |
101 | <h2 id="配置-ssh">配置 ssh</h2> | 86 | <h2 id="简单美化一下命令行">简单美化一下命令行</h2> |
87 | <p>配到这里,我们会发现一个很操蛋的事情,“为啥命令提示符之前不显示当前用户名和当前路径嘞?这岂不是每次看路径都需要<kbd>pwd</kbd>吗?烦不烦啊!”别急,问题很好修改。</p> | ||
88 | <pre><code>cd ~ | ||
89 | vim .bashrc | ||
90 | # 找到PS1=,将其修改为PS1="\u@\h:\w\$" | ||
91 | |||
92 | # 加载.bashrc | ||
93 | source .bashrc</code></pre> | ||
94 | <p>改好之后也许还是没有变化,我就是这样的。后来在处理其它问题的时候,我发现了根本原因所在:我 TM 创建用户的时候忘了加<kbd>-s</kbd>参数,导致新用户的默认 shell | ||
95 | 是<kbd>sh</kbd>而不是<kbd>bash</kbd>。所以,我们需要修改一下新用户的默认 shell。</p> | ||
96 | <pre><code># 查看当前用户的默认shell | ||
97 | echo $SHELL | ||
98 | |||
99 | # 修改默认shell | ||
100 | sudo chsh -s /bin/bash player</code></pre> | ||
101 | <p>这时再重新加载,就会发现,一切都正常了,一切是那么美好。</p> | ||
102 | <p>除此之外,我们也许想要调整命令行显示的用户名、路径之类内容的颜色,会想让命令行像 git bash 一样当我们进入 git 仓库的时候显示当前在什么分支。针对这两项需求,我修改了一下我的.bashrc | ||
103 | 文件,现在其内容如下:</p> | ||
104 | <pre><code># ~/.bashrc: executed by bash(1) for non-login shells. | ||
105 | # see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) | ||
106 | # for examples | ||
107 | |||
108 | # If not running interactively, don't do anything | ||
109 | case $- in | ||
110 | *i*) ;; | ||
111 | *) return;; | ||
112 | esac | ||
113 | |||
114 | # don't put duplicate lines or lines starting with space in the history. | ||
115 | # See bash(1) for more options | ||
116 | HISTCONTROL=ignoreboth | ||
117 | |||
118 | # append to the history file, don't overwrite it | ||
119 | shopt -s histappend | ||
120 | |||
121 | # for setting history length see HISTSIZE and HISTFILESIZE in bash(1) | ||
122 | HISTSIZE=1000 | ||
123 | HISTFILESIZE=2000 | ||
124 | |||
125 | # check the window size after each command and, if necessary, | ||
126 | # update the values of LINES and COLUMNS. | ||
127 | shopt -s checkwinsize | ||
128 | |||
129 | # If set, the pattern "**" used in a pathname expansion context will | ||
130 | # match all files and zero or more directories and subdirectories. | ||
131 | #shopt -s globstar | ||
132 | |||
133 | # make less more friendly for non-text input files, see lesspipe(1) | ||
134 | [ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" | ||
135 | |||
136 | # set variable identifying the chroot you work in (used in the prompt below) | ||
137 | if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then | ||
138 | debian_chroot=$(cat /etc/debian_chroot) | ||
139 | fi | ||
140 | |||
141 | # set a fancy prompt (non-color, unless we know we "want" color) | ||
142 | case "$TERM" in | ||
143 | xterm-color|*-256color) color_prompt=yes;; | ||
144 | esac | ||
145 | |||
146 | # uncomment for a colored prompt, if the terminal has the capability; turned | ||
147 | # off by default to not distract the user: the focus in a terminal window | ||
148 | # should be on the output of commands, not on the prompt | ||
149 | #force_color_prompt=yes | ||
150 | |||
151 | if [ -n "$force_color_prompt" ]; then | ||
152 | if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then | ||
153 | # We have color support; assume it's compliant with Ecma-48 | ||
154 | # (ISO/IEC-6429). (Lack of such support is extremely rare, and such | ||
155 | # a case would tend to support setf rather than setaf.) | ||
156 | color_prompt=yes | ||
157 | else | ||
158 | color_prompt= | ||
159 | fi | ||
160 | fi | ||
161 | |||
162 | # 简单修改一下颜色 | ||
163 | if [ "$color_prompt" = yes ]; then | ||
164 | PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\[\033[00m\]' | ||
165 | else | ||
166 | PS1='${debian_chroot:+($debian_chroot)}\u@\h:' | ||
167 | fi | ||
168 | |||
169 | # 如果是git仓库,在命令行提示符之前用不同的颜色显示当前分支 | ||
170 | PS1="$PS1"'\[\033[33m\]' # change to yellow | ||
171 | PS1="$PS1"'\w' # pwd | ||
172 | PS1="$PS1"'\[\033[36m\]' # change color to cyan | ||
173 | PS1="$PS1"'`__git_ps1`' # git branch | ||
174 | PS1="$PS1"'\[\033[0m\]' # change color | ||
175 | #PS1="$PS1"'\n' # new line | ||
176 | PS1="$PS1"'\$ ' # prompt: always $ | ||
177 | unset color_prompt force_color_prompt | ||
178 | |||
179 | # If this is an xterm set the title to user@host:dir | ||
180 | case "$TERM" in | ||
181 | xterm*|rxvt*) | ||
182 | PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1" | ||
183 | ;; | ||
184 | *) | ||
185 | ;; | ||
186 | esac | ||
187 | |||
188 | # enable color support of ls and also add handy aliases | ||
189 | if [ -x /usr/bin/dircolors ]; then | ||
190 | test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" | ||
191 | alias ls='ls --color=auto' | ||
192 | #alias dir='dir --color=auto' | ||
193 | #alias vdir='vdir --color=auto' | ||
194 | |||
195 | alias grep='grep --color=auto' | ||
196 | alias fgrep='fgrep --color=auto' | ||
197 | alias egrep='egrep --color=auto' | ||
198 | fi | ||
199 | |||
200 | # colored GCC warnings and errors | ||
201 | #export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' | ||
202 | |||
203 | # some more ls aliases | ||
204 | alias ll='ls -alF' | ||
205 | alias la='ls -A' | ||
206 | alias l='ls -CF' | ||
207 | |||
208 | # Add an "alert" alias for long running commands. Use like so: | ||
209 | # sleep 10; alert | ||
210 | alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"' | ||
211 | |||
212 | # Alias definitions. | ||
213 | # You may want to put all your additions into a separate file like | ||
214 | # ~/.bash_aliases, instead of adding them here directly. | ||
215 | # See /usr/share/doc/bash-doc/examples in the bash-doc package. | ||
216 | |||
217 | if [ -f ~/.bash_aliases ]; then | ||
218 | . ~/.bash_aliases | ||
219 | fi | ||
220 | |||
221 | # enable programmable completion features (you don't need to enable | ||
222 | # this, if it's already enabled in /etc/bash.bashrc and /etc/profile | ||
223 | # sources /etc/bash.bashrc). | ||
224 | if ! shopt -oq posix; then | ||
225 | if [ -f /usr/share/bash-completion/bash_completion ]; then | ||
226 | . /usr/share/bash-completion/bash_completion | ||
227 | elif [ -f /etc/bash_completion ]; then | ||
228 | . /etc/bash_completion | ||
229 | fi | ||
230 | fi | ||
231 | echo This\ is\ .bashrc. | ||
232 | |||
233 | alias pip='python -m pip' | ||
234 | # 设置bash使用vim模式,允许使用0、dw之类常用vim快捷键,方便命令编辑 | ||
235 | set -o vi | ||
236 | # 有时候我们需要一些魔法 | ||
237 | export http_proxy=http://127.0.0.1:7890 | ||
238 | export https_proxy=http://127.0.0.1:7890</code></pre> | ||
239 | <h1 id="配置-ssh">配置 ssh</h1> | ||
102 | <p>用着用着,就会发现:我为啥一直在浏览器里搞命令行?要是能直接在本地的命令行里搞就好了。当然,阿里云能满足我们。</p> | 240 | <p>用着用着,就会发现:我为啥一直在浏览器里搞命令行?要是能直接在本地的命令行里搞就好了。当然,阿里云能满足我们。</p> |
103 | <h3 id="ssh-简介">ssh 简介</h3> | 241 | <h2 id="ssh-简介">ssh 简介</h2> |
104 | <p>什么是 ssh?ssh 是 Secure Shell 的缩写,中文名为安全外壳协议。ssh 是一种加密的网络协议,可以在不安全的网络中为网络服务提供安全的传输环境。ssh | 242 | <p>什么是 ssh?ssh 是 Secure Shell 的缩写,中文名为安全外壳协议。ssh 是一种加密的网络协议,可以在不安全的网络中为网络服务提供安全的传输环境。ssh |
105 | 是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用 ssh 协议可以有效防止远程管理过程中的信息泄露问题。通过 ssh 可以对所有传输的数据进行加密,也能够防止 DNS 欺骗和 IP | 243 | 是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用 ssh 协议可以有效防止远程管理过程中的信息泄露问题。通过 ssh 可以对所有传输的数据进行加密,也能够防止 DNS 欺骗和 IP |
106 | 欺骗。ssh | 244 | 欺骗。ssh 还支持在两个远程主机之间进行数据的传输。</p> |
107 | 还支持在两个远程主机之间进行数据的传输。</p> | ||
108 | <p>说了也记不住,直接开干!</p> | 245 | <p>说了也记不住,直接开干!</p> |
109 | <h3 id="配置安全组规则">配置安全组规则</h3> | 246 | <h2 id="配置安全组规则">配置安全组规则</h2> |
110 | <p>在阿里云控制台左上角点击,选择<code>云服务器ECS</code>,会进入云服务器实例控制界面。在左侧菜单栏寻找<code>安全组</code> ,添加安全组规则。按要求添加新的安全组规则,开放 TCP | 247 | <p>在阿里云控制台左上角点击,选择<code>云服务器ECS</code>,会进入云服务器实例控制界面。在左侧菜单栏寻找<code>安全组</code> ,添加安全组规则。按要求添加新的安全组规则,开放 TCP |
111 | 协议对应的 | 248 | 协议对应的 22 端口。(其实可以都开了,但是毕竟不安全,建议后续按需开放。)</p> |
112 | 22 端口。(其实可以都开了,但是毕竟不安全,建议后续按需开放。)</p> | ||
113 | <p>接着,在菜单栏中点击<code>密钥对</code>,创建新的密钥对。<strong>完成之后会自动下载一个.pem 文件,我们需要将该文件保存好,丢失之后无法找回,这是 ssh 连接的密钥。</strong> | 249 | <p>接着,在菜单栏中点击<code>密钥对</code>,创建新的密钥对。<strong>完成之后会自动下载一个.pem 文件,我们需要将该文件保存好,丢失之后无法找回,这是 ssh 连接的密钥。</strong> |
114 | </p> | 250 | </p> |
115 | <p>为了方便用别名连接,我们需要一个配置文件:</p> | 251 | <p>为了方便用别名连接,我们需要一个配置文件:</p> |
@@ -117,7 +253,7 @@ sudo apt install make cmake | |||
117 | <li>将上述.pem 文件移动到家目录<code>C:\用户\当前用户名</code>的<kbd>.ssh</kbd>文件夹下</li> | 253 | <li>将上述.pem 文件移动到家目录<code>C:\用户\当前用户名</code>的<kbd>.ssh</kbd>文件夹下</li> |
118 | <li>在<kbd>.ssh</kbd>文件夹下创建文件<kbd>config</kbd>,内容如下:</li> | 254 | <li>在<kbd>.ssh</kbd>文件夹下创建文件<kbd>config</kbd>,内容如下:</li> |
119 | </ul> | 255 | </ul> |
120 | <pre><code class="language-plaintext"># 给服务器起的别名,这里是aliyun | 256 | <pre><code># 给服务器起的别名,这里是aliyun |
121 | Host aliyun | 257 | Host aliyun |
122 | # IP地址,这里以127.0.0.1代替,但真实操作需要换成服务器的公网ip,在控制台就能看到 | 258 | # IP地址,这里以127.0.0.1代替,但真实操作需要换成服务器的公网ip,在控制台就能看到 |
123 | IP 127.0.0.1 | 259 | IP 127.0.0.1 |
@@ -132,208 +268,21 @@ User player | |||
132 | ssh aliyun</code></pre> | 268 | ssh aliyun</code></pre> |
133 | <h1 id="拥抱-vim">拥抱 vim</h1> | 269 | <h1 id="拥抱-vim">拥抱 vim</h1> |
134 | <p>既然我们选择了在命令行里使用,编辑文件当然是比较常用 vim 了。当然 neovim 与其他命令行编辑器也很好,但我不熟悉,请参照网上其他教程进行配置。</p> | 270 | <p>既然我们选择了在命令行里使用,编辑文件当然是比较常用 vim 了。当然 neovim 与其他命令行编辑器也很好,但我不熟悉,请参照网上其他教程进行配置。</p> |
135 | <p>我的 vim 学习与配置<a href="https://www.qin-juan-he-zhu.top/code/linux/vim.html">链接</a>中有如下一些基本配置:</p> | 271 | <p>我的 vim 学习与配置<a href="https://www.qin-juan-ge-zhu.top/code/linux/vim.html">链接</a>中有如下一些基本配置:</p> |
136 | <ul> | 272 | <ul> |
137 | <li>同时开启绝对行号与相对行号,则当前行显示真实行号,其他行显示相对于当前行为上/下第几行,方便跳转。</li> | ||
138 | <li>代码中常常需要的<code>()[]{}</code>自动匹配</li> | ||
139 | <li>自动缩进和智能缩进,但似乎没啥鸟用</li> | ||
140 | <li>vim 自带的代码高亮,感觉还是相当不错的</li> | 273 | <li>vim 自带的代码高亮,感觉还是相当不错的</li> |
274 | <li>代码中常常需要的<code>()[]{}</code>自动匹配</li> | ||
275 | <li>同时开启绝对行号与相对行号,则当前行显示真实行号,其他行显示相对于当前行为上/下第几行,方便跳转。</li> | ||
276 | <li>代码按语法缩进,并且每次保存或退出时自动格式化</li> | ||
141 | <li>当前行/当前列各给一个颜色,因为有的平台光标显示很不明显,正常插入模式一般也不好确定光标位置,这样方便知道光标在哪。</li> | 277 | <li>当前行/当前列各给一个颜色,因为有的平台光标显示很不明显,正常插入模式一般也不好确定光标位置,这样方便知道光标在哪。</li> |
142 | <li>自动折行,即当前行太长了会被折回来显示,但还是同一行,方便一次性看完整。</li> | 278 | <li>自动折行,即当前行太长了会被折回来显示,但还是同一行,方便一次性看完整。</li> |
143 | <li>一些快捷键,如<kbd>ta</kbd>到行末(替代够不到的<kbd>$</kbd>),<kbd>end</kbd>来到文件末(替代难记的<kbd>G</kbd>),还有<kbd>up/ne</kbd>上/下移动 | 279 | <li>一些快捷键,如<kbd>L</kbd>到行末(替代够不到的<kbd>$</kbd>),还有<kbd>K/J</kbd>上/下移动 10 行等。</li> |
144 | 20 行等。</li> | 280 | <li>基本的状态栏设置,包括文件名、git 分支、文件编码、文件类型、总行数等信息,方便查看。</li> |
145 | <li>自动识别文件类型,并对<code>*.html, *.c, *.cpp, *.python</code>等文件在保存<kbd>:w<Enter> | 281 | <li>自动识别文件类型,并对<code>*.html, *.c, *.cpp, *.python</code>等文件在保存<kbd>:w<Enter></kbd>时自动格式化</li> |
146 | </kbd>时自动格式化,在正常或选择模式下<kbd>Ctrl+p</kbd>一键注释(别骂了别骂了,<kbd>Ctrl+/</kbd>我属实是设置不出来)</li> | 282 | <li>插件和其他重重设置</li> |
147 | </ul> | 283 | </ul> |
148 | <h2 id="插件管理">插件管理</h2> | ||
149 | <p>这里使用了几个插件,插件管理目前用的是评价一般的<code>Vundle</code>。个人评价,下载插件啥的属实是慢,每次都报错报到怀疑人生,害得我都得手动安装然后在里边添加,但是别的目前还不会使。气死偶勒! | 284 | <p>这里使用了几个插件,插件管理目前用的是评价一般的<code>Vundle</code>。个人评价,下载插件啥的属实是慢,每次都报错报到怀疑人生,害得我都得手动安装然后在里边添加,但是别的目前还不会使。气死偶勒! |
150 | </p> | 285 | </p> |
151 | <p>这里需要注意的是,上文提到我喜欢把有用的东西放在<code>~/useful</code>下,但是如果直接这样写路径,其他用户如 root | ||
152 | 等使用时候就会报错,人家的主目录第下没这个东西!所以,在写路径的位置,切记要写绝对路径!!!</p> | ||
153 | <h1 id="游戏">游戏</h1> | ||
154 | <blockquote> | ||
155 | <p>All work no play makes Jack a doll boy.</p> | ||
156 | </blockquote> | ||
157 | <p>经过了上边的配置,写代码的控制基本完善了,但是服务器怎么能只拿来干活呢?没有游戏怎么行?我们要快乐!</p> | ||
158 | <p>目前我的服务器上装了三个游戏</p> | ||
159 | <ul> | ||
160 | <li>俄罗斯方块,装的是<code>tint</code></li> | ||
161 | <li>扫雷,装的是<code>miebash</code></li> | ||
162 | <li>贪吃蛇,找不到力(允悲</li> | ||
163 | </ul> | ||
164 | <p>安装方法网上都有,就不多说了。玩得愉快!</p> | ||
165 | <h1 id="git-远程存储">git 远程存储</h1> | ||
166 | <p>君不闻,《西游记》有云:</p> | ||
167 | <blockquote> | ||
168 | <p>争名夺利几时休,早起迟眠不自由。</p> | ||
169 | <p>骑着驴骡思骏马,官居宰相望王侯。</p> | ||
170 | </blockquote> | ||
171 | <p>完成了代码环境的配置,我就在想,要是有一个自己的远程 git 存储库该多好?</p> | ||
172 | <p>说干就干,我找到了 gitlab 安装教程,信心满满,谁知“先帝创业未半而中道崩殂”。</p> | ||
173 | <h2 id="gitlab">gitlab?</h2> | ||
174 | <p>我按照网上的教程,更新了清华镜像源,下载安装 gitlab。孰料一次一次在安装过程卡死,而且情况十分严重,CPU 占用率长期维持在 50%以上,内存更是飙升到 | ||
175 | 90%,现在不仅安装进行不下去了,甚至一切操作都不认识,包括<kbd>Ctrl+C</kbd>想要杀死当前进程的请求也会石沉大海。没办法,只得强制重启。</p> | ||
176 | <p>如是反复若干次,最终死心,将 gitlab 彻底从云服务器卸载,“革职为民,永不叙用”。</p> | ||
177 | <p>经过上网查找,原因果然出现在配置上。<strong>gitlab 推荐的最小内存是 4G,但是目前我们只有 | ||
178 | 2G,内存爆满也就理所当然了。</strong>没办法,期限之内不能更改配置,就算能更改,我都穷到薅资本主义羊毛了,还能有钱升级配置?笑死。</p> | ||
179 | <h2 id="就这">就这?</h2> | ||
180 | <p>就因为这个问题,我们就不干了?这是不行滴,小同志。</p> | ||
181 | <p>不久之后,黄四郎同志发来了一篇博客:<a href="https://www.ruanyifeng.com/blog/2022/10/git-server.html">最简单的 git 服务器</a></p> | ||
182 | <p>看起来似乎不错,但是失之简略。幸好,我在 git 官方教程<a href="https://git-scm.com/book/zh/v2">Pro | ||
183 | Git</a>上找到了另一部分,两个拼一拼、试一试,最终成功了。 | ||
184 | </p> | ||
185 | <p>注意,本地和远程都需要安装 git,相信能看这里的读者应该已经是安装过了,这里不再赘述。</p> | ||
186 | <h3 id="前置">前置</h3> | ||
187 | <p>在创建存储库之前,我想我们应该做些什么。</p> | ||
188 | <p>对了,创建新用户吧!按照上述写的步骤创建一个新用户并为之设置密码,可以不用加入 sudo 组,因为我们不需要这个用户来操作服务器,只需要用来存储代码就行了。</p> | ||
189 | <h3 id="本地存储库">本地存储库</h3> | ||
190 | <p>本地我们需要一个存储库,如果已有的则可以忽略本部分。</p> | ||
191 | <pre><code class="language-bash"># 创建本地存储库,这里叫test吧 | ||
192 | mkdir test | ||
193 | cd test | ||
194 | git init</code></pre> | ||
195 | <p>但是本方法要求本地存储库必须已经有 commit(s)。好办,就写一个常用的<code>.gitignore</code>好了。</p> | ||
196 | <pre><code class="language-plaintext">*.sh | ||
197 | *.bat | ||
198 | *.exe | ||
199 | *.dll | ||
200 | *.so | ||
201 | *.[oa] | ||
202 | *.idea</code></pre> | ||
203 | <p>而后,为了方便提交操作,可以再创建一个<code>push.sh</code>脚本:</p> | ||
204 | <pre><code class="language-bash">#!/bin/bash | ||
205 | git add . | ||
206 | git commit | ||
207 | git push</code></pre> | ||
208 | <p>注意,创建<code>push.sh</code>一定要在<code>.gitignore</code>之后,否则不会被忽略的。</p> | ||
209 | <h3 id="远程仓库">远程仓库</h3> | ||
210 | <p>就一句话:</p> | ||
211 | <pre><code class="language-bash"># 创建远程仓库,这里也叫test吧 | ||
212 | ssh git@127.0.0.1 git init --bare test.git</code></pre> | ||
213 | <p>注意,本处指明的 git 为远程用户名,127.0.0.1 代表云服务器的公网 ip,test.git 为远程仓库名。使用的时候都需要换成自己的。</p> | ||
214 | <h3 id="本地与远程连接">本地与远程连接</h3> | ||
215 | <p>本地和远程都有了,下一步就是建立联系了。</p> | ||
216 | <pre><code class="language-bash"># 本地添加远程 | ||
217 | git remote add origin git@127.0.0.1:test.git | ||
218 | |||
219 | # 此时尚不能直接推送,因为并未指定上游对应分支,需要指定 | ||
220 | git push --set-upstream origin master | ||
221 | |||
222 | # 之后就可以直接推送了 | ||
223 | sh push.sh</code></pre> | ||
224 | <h3 id="自动化">自动化</h3> | ||
225 | <p>怎么样,操作看起来又臭又长吧?我也这么觉得。所以我写了两份代码,供同时自动创建本地仓库和远程对应仓库并建立所有对应关系之用。</p> | ||
226 | <pre><code class="language-c">/* | ||
227 | * gitadd.c | ||
228 | */ | ||
229 | #include <stdio.h> | ||
230 | #include <stdlib.h> | ||
231 | #include <string.h> | ||
232 | #include <direct.h> | ||
233 | |||
234 | int main() | ||
235 | { | ||
236 | char local_name[100],remote_name[100],tmp[100]; | ||
237 | printf("您好!\n请输入本地仓库名:"); | ||
238 | gets(local_name); | ||
239 | printf("请输入远程仓库名:"); | ||
240 | gets(remote_name); | ||
241 | |||
242 | //远程仓库创建 | ||
243 | strcpy(tmp,"ssh aliyun-git git init --bare "); | ||
244 | strcat(remote_name,".git"); | ||
245 | strcat(tmp,remote_name); | ||
246 | system(tmp); | ||
247 | |||
248 | //本地仓库创建 | ||
249 | mkdir(local_name); | ||
250 | chdir(local_name); | ||
251 | system("git init"); | ||
252 | |||
253 | //本地仓库初始化 | ||
254 | FILE* file; | ||
255 | //编写.gitignore | ||
256 | file=fopen(".gitignore","w"); | ||
257 | fprintf(file,"*.sh\n"); | ||
258 | fprintf(file,"*.bat\n"); | ||
259 | fprintf(file,"*.exe\n"); | ||
260 | fprintf(file,"*.[oa]\n"); | ||
261 | fprintf(file,"*.pyc\n"); | ||
262 | fprintf(file,"__pycache__\n"); | ||
263 | fprintf(file,"*.vscode\n"); | ||
264 | fprintf(file,"*.swp\n"); | ||
265 | fclose(file); | ||
266 | //编写push.sh | ||
267 | file=fopen("push.sh","w"); | ||
268 | fprintf(file,"git add .\n"); | ||
269 | fprintf(file,"git commit\n"); | ||
270 | fprintf(file,"git push"); | ||
271 | fclose(file); | ||
272 | |||
273 | //提交初始化commit | ||
274 | system("git add ."); | ||
275 | system("git commit -m \"Initial commit\""); | ||
276 | strcpy(tmp,"git remote add origin aliyun-git:"); | ||
277 | strcat(tmp,remote_name); | ||
278 | system(tmp); | ||
279 | system("git push --set-upstream origin master"); | ||
280 | system("git push"); | ||
281 | |||
282 | printf("完成!"); | ||
283 | return 0; | ||
284 | }</code></pre> | ||
285 | <pre><code class="language-python"># gitadd.py | ||
286 | import os | ||
287 | |||
288 | if __name__ == '__main__': | ||
289 | print("你好!") | ||
290 | print("请输入本地仓库名:") | ||
291 | local_name = input() | ||
292 | print("请输入远程仓库名:") | ||
293 | remote_name = input() | ||
294 | os.system("ssh aliyun-git git init --bare "+remote_name+".git") | ||
295 | |||
296 | # 创建本地仓库 | ||
297 | os.system("mkdir "+local_name) | ||
298 | os.chdir(local_name) | ||
299 | print("本地仓库已建立!") | ||
300 | print("当前路径为"+os.getcwd()) | ||
301 | |||
302 | # 初始化git仓库 | ||
303 | os.system("git init") | ||
304 | |||
305 | # 以utf8编码编写.gitignore文件 | ||
306 | with open(".gitignore", "w", encoding="utf8") as f: | ||
307 | f.write("*.pyc\n") | ||
308 | f.write("__pycache__/\n") | ||
309 | f.write("*.exe\n") | ||
310 | f.write("*.[oa]\n") | ||
311 | f.write("*.swp\n") | ||
312 | f.write("*.sh\n") | ||
313 | f.write("*.bat\n") | ||
314 | |||
315 | # 编写push.sh文件 | ||
316 | with open("push.sh", "w", encoding="utf8") as f: | ||
317 | f.write("git add .\n") | ||
318 | f.write("git commit\n") | ||
319 | f.write("git push\n") | ||
320 | |||
321 | print("本地仓库初始化完成!") | ||
322 | |||
323 | # 连接远程仓库 | ||
324 | os.system("git add .") | ||
325 | os.system("git commit -m \"Initial commit\"") | ||
326 | os.system("git remote add origin aliyun-git:"+remote_name+".git") | ||
327 | os.system("git push --set-upstream origin master") | ||
328 | os.system("git push") | ||
329 | |||
330 | print("完成!")</code></pre> | ||
331 | <p><strong>Attention please:</strong> | ||
332 | 本地仓库名和远程仓库名不要加后缀,程序会自动添加。另外,如果要修改,在转换本地当前工作目录的时候,<strong>一定要使用语言自带的调整当前工作目录的函数,不要调用系统命令</strong>,否则会出现编译器/解释器自动将程序作为多线程执行,导致一个线程进去了然后线程当场去世,后续的操作在另一个线程,工作目录根本没发生变化,也就是把原来所在的位置给 | ||
333 | git 初始化了,出现奇奇怪怪的错误。</p> | ||
334 | <h3 id="其他">其他</h3> | ||
335 | <p>需要明白的是,上述方法在远端创立的<strong>只是一个裸仓库</strong>(即只是我们本地仓库的<code>.git</code>文件夹),不包含工作目录,所以不能直接在远端进行操作,需要在本地进行操作,然后推送到远端。但是<code>git clone</code>的时候,本地得到的是一个完整的仓库,而其他使用也与普通仓库无异。 | ||
336 | </p> | ||
337 | <h1 id="来看看在线-vscode-吧">来看看在线 VSCode 吧!</h1> | 286 | <h1 id="来看看在线-vscode-吧">来看看在线 VSCode 吧!</h1> |
338 | <p>本来,一切就这样完美收官、从胜利走向更大的胜利了。坏就坏在我按照五个月前的计划添置了一个 | 287 | <p>本来,一切就这样完美收官、从胜利走向更大的胜利了。坏就坏在我按照五个月前的计划添置了一个 |
339 | iPad。在最初的设想里它就不单单是当平板做笔记看书用的,而是要充当电脑的编程功能,来在必要的时刻随拿随走,替代我这十几斤重、续航还短的游戏本的。</p> | 288 | iPad。在最初的设想里它就不单单是当平板做笔记看书用的,而是要充当电脑的编程功能,来在必要的时刻随拿随走,替代我这十几斤重、续航还短的游戏本的。</p> |
@@ -347,9 +296,9 @@ if __name__ == '__main__': | |||
347 | <p>但是我这里 curl 不知何故一直不能用,wget 也不好使,只能在 gayhub 仓库的<a | 296 | <p>但是我这里 curl 不知何故一直不能用,wget 也不好使,只能在 gayhub 仓库的<a |
348 | href="https://github.com/coder/code-server/releases">Releases</a>里找到最新版适合的安装包手动安装了。我是 | 297 | href="https://github.com/coder/code-server/releases">Releases</a>里找到最新版适合的安装包手动安装了。我是 |
349 | Ubuntu22.04LTS,系统架构 amd64,所以下载了对应的.deb 安装包。</p> | 298 | Ubuntu22.04LTS,系统架构 amd64,所以下载了对应的.deb 安装包。</p> |
350 | <pre><code class="language-bash"># 本地命令行中运行 | 299 | <pre><code># 本地命令行中运行 |
351 | scp code-server-4.13.0-linux-amd64.deb aliyun:code-server-4.13.0-linux-amd64.deb</code></pre> | 300 | scp code-server-4.13.0-linux-amd64.deb aliyun:code-server-4.13.0-linux-amd64.deb</code></pre> |
352 | <pre><code class="language-bash"># 云服务器命令行中运行 | 301 | <pre><code># 云服务器命令行中运行 |
353 | 302 | ||
354 | # 安装 | 303 | # 安装 |
355 | sudo dpkg -i code-server-4.13.0-linux-amd64.deb</code></pre> | 304 | sudo dpkg -i code-server-4.13.0-linux-amd64.deb</code></pre> |
@@ -358,14 +307,11 @@ sudo dpkg -i code-server-4.13.0-linux-amd64.deb</code></pre> | |||
358 | <p>安装完成后,就可以直接运行了。</p> | 307 | <p>安装完成后,就可以直接运行了。</p> |
359 | <pre><code>code-server</code></pre> | 308 | <pre><code>code-server</code></pre> |
360 | <p>就可以直接运行了,但是这样只能在本地浏览器运行,而我们需要的是远程运行。算了,直接上脚本!</p> | 309 | <p>就可以直接运行了,但是这样只能在本地浏览器运行,而我们需要的是远程运行。算了,直接上脚本!</p> |
361 | <pre><code class="language-shell">#!/bin/sh | 310 | <pre><code>#!/bin/sh |
362 | code-server --host "0.0.0.0"> /home/player/useful/codeserver-out.txt 2>&1 & | 311 | code-server --host "0.0.0.0"> /home/player/useful/codeserver-out.txt 2>&1 &</code></pre> |
363 | echo 启动完成!程序已在后台运行。 | ||
364 | echo 如需杀死进程,请以jobs查看后台程序编号并kill %num | ||
365 | echo 或ps查看进程号并kill之。</code></pre> | ||
366 | <p>其中第一条指令是设置允许外界访问,并指定了由后台运行、所有输出写进<code>/home/player/useful/codeserver.txt</code>文件中。后续均为输出信息。</p> | 312 | <p>其中第一条指令是设置允许外界访问,并指定了由后台运行、所有输出写进<code>/home/player/useful/codeserver.txt</code>文件中。后续均为输出信息。</p> |
367 | <p>初次这样设置,直接打开会有密码,密码的存储文件在<code>~/.config/code-server/config.yaml</code>中,可以直接修改,也可以使用命令行修改。比如我当前的设置为:</p> | 313 | <p>初次这样设置,直接打开会有密码,密码的存储文件在<code>~/.config/code-server/config.yaml</code>中,可以直接修改,也可以使用命令行修改。比如我当前的设置为:</p> |
368 | <pre><code class="language-yaml">bind-addr: 127.0.0.1:8080 | 314 | <pre><code>bind-addr: 127.0.0.1:8080 |
369 | auth: password | 315 | auth: password |
370 | password: player | 316 | password: player |
371 | cert: false</code></pre> | 317 | cert: false</code></pre> |
@@ -374,10 +320,7 @@ cert: false</code></pre> | |||
374 | <h2 id="杀死">杀死</h2> | 320 | <h2 id="杀死">杀死</h2> |
375 | <p>设置好之后会需要重新启动程序,我一般选择杀死然后重新运行启动脚本。</p> | 321 | <p>设置好之后会需要重新启动程序,我一般选择杀死然后重新运行启动脚本。</p> |
376 | <p>杀死的方法:</p> | 322 | <p>杀死的方法:</p> |
377 | <pre><code class="language-bash"># 运行指令 | 323 | <pre><code>$ ps -ef | grep code-server |
378 | ps -ef | grep code-server | ||
379 | |||
380 | # 输出结果如下 | ||
381 | player 2621 1 0 May29 ? 00:00:00 /usr/lib/code-server/lib/node /usr/lib/code-server --host 0.0.0.0 | 324 | player 2621 1 0 May29 ? 00:00:00 /usr/lib/code-server/lib/node /usr/lib/code-server --host 0.0.0.0 |
382 | player 2646 2621 0 May29 ? 00:03:31 /usr/lib/code-server/lib/node /usr/lib/code-server/out/node/entry | 325 | player 2646 2621 0 May29 ? 00:03:31 /usr/lib/code-server/lib/node /usr/lib/code-server/out/node/entry |
383 | player 3079 2646 0 May29 ? 00:00:57 /usr/lib/code-server/lib/node /usr/lib/code-server/lib/vscode/out/bootstrap-fork --type=ptyHost --logsPath /home/player/.local/share/code-server/logs/20230529T211752 | 326 | player 3079 2646 0 May29 ? 00:00:57 /usr/lib/code-server/lib/node /usr/lib/code-server/lib/vscode/out/bootstrap-fork --type=ptyHost --logsPath /home/player/.local/share/code-server/logs/20230529T211752 |
@@ -390,8 +333,8 @@ player 465057 464494 0 13:42 ? 00:00:35 /usr/lib/code-server/lib/nod | |||
390 | player 579173 574648 0 16:44 pts/1 00:00:00 grep --color=auto code-server | 333 | player 579173 574648 0 16:44 pts/1 00:00:00 grep --color=auto code-server |
391 | 334 | ||
392 | # 只需要杀死根进程也就是第一个进程就好,下边的数据需要改成当前对应进程号 | 335 | # 只需要杀死根进程也就是第一个进程就好,下边的数据需要改成当前对应进程号 |
393 | kill -9 2621</code></pre> | 336 | $ kill -9 2621</code></pre> |
394 | <p>重新启动之后,就可以用<code><服务器公网ip>:<指定端口></code>访问在线 VSCode 了,初次访问会比较慢,耐心等待吧。</p> | 337 | <p>重新启动之后,就可以用<code>ip:post</code>访问在线 VSCode 了,初次访问会比较慢,耐心等待吧。</p> |
395 | <h2 id="同步设置">同步设置</h2> | 338 | <h2 id="同步设置">同步设置</h2> |
396 | <p>在线 VSCode 设置好了,但是为了进一步抹平在线端与本地端的差异,最好做一下同步设置处理。网上大多数教程给的都是利用插件<a | 339 | <p>在线 VSCode 设置好了,但是为了进一步抹平在线端与本地端的差异,最好做一下同步设置处理。网上大多数教程给的都是利用插件<a |
397 | href="https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync">Settings | 340 | href="https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync">Settings |
@@ -425,50 +368,56 @@ kill -9 2621</code></pre> | |||
425 | github 上,一旦把一级域名解析到服务器,就要出问题。</p> | 368 | github 上,一旦把一级域名解析到服务器,就要出问题。</p> |
426 | <p>除此之外,记得到阿里云 ecs 那里,在安全组规则中,开放 http/https 对应的 80/443 端口!两个都要开!</p> | 369 | <p>除此之外,记得到阿里云 ecs 那里,在安全组规则中,开放 http/https 对应的 80/443 端口!两个都要开!</p> |
427 | <h2 id="icp-备案">ICP 备案</h2> | 370 | <h2 id="icp-备案">ICP 备案</h2> |
428 | <p>众所周知,我国是工人阶级领导的、以工农联盟为基础的、人民民主专政的社会主义国家,一切事关宣传、舆论的东西都要在党的领导下,都要经过审查备案,包括建网站和域名 https 使用。</p> | 371 | <p>众所周知,我国是“工人阶级领导的、以工农联盟为基础的、人民民主专政的社会主义”国家,一切事关宣传、舆论的东西都要在党的领导下,都要经过审查备案,包括建网站和域名 https 使用。ICP |
429 | <p>ICP 备案的原则是:用谁的服务器,在谁那里备案。即以我而言,我在腾讯云买的域名、做的 DNS 解析,但用的是阿里云的服务器,就要在阿里云做 ICP 备案。</p> | 372 | 备案的原则是:<strong>用谁的服务器,在谁那里备案</strong>。以我为例,我在腾讯云买的域名、做的 DNS 解析,但用的是阿里云的服务器,就要在阿里云做 ICP 备案。</p> |
430 | <p>备案流程按按着走就行,只是有几点需要特别注意:</p> | 373 | <p>备案流程按按着走就行,只是有几点需要特别注意:</p> |
431 | <ul> | 374 | <ul> |
432 | <li>备案的省份需要与户籍所在省一致</li> | 375 | <li>备案的省份需要与户籍所在省一致</li> |
433 | <li>备案网站名称不要太普通,容易和别人重复,会被客服小姐姐电话要求订正</li> | 376 | <li>备案网站名称不要太普通,容易和别人重复,会被客服小姐姐电话要求订正</li> |
434 | <li>网站名称不要出现“阁、楼、店”等一些容易误会为企业商业主体网站的名称,否则也会被退回。</li> | 377 | <li>网站名称不要出现“阁、楼、店”等一些容易误会为企业商业主体网站的名称,否则也会被退回。</li> |
435 | <li>网站用途描述要详细,尽量 30 字以上,绝对不要出现“博客”等词,审查非常非常严格,而且极大可能直接被 ban。即使你真要博客,不能暗度陈仓吗?</li> | 378 | <li>网站用途描述要详细,尽量 30 字以上 |
379 | <ul> | ||
380 | <li>用途描述绝对不要出现“博客”等词,审查非常非常严格,而且极大可能直接被 ban。即使你真要博客,不能暗度陈仓吗?</li> | ||
381 | <li>就算你要开评论区也不要说提及。<strong>朋友,你也不想你的博客隔三差五被警察同志拿着放大镜看吧?</strong></li> | ||
382 | </ul> | ||
383 | </li> | ||
436 | </ul> | 384 | </ul> |
437 | <p>提交备案之后。如有问题客服会打电话通知,并退回修改;阿里云初审需要大概不到 1 天,工信部短信确认需要 1 天,然后发送到备案省(即户籍所在省)的管局,时长最多 20 天,建议提前搞。我用了 6 天。</p> | 385 | <p>提交备案之后。如有问题客服会打电话通知,并退回修改;阿里云初审需要大概不到 1 天,工信部短信确认需要 1 天,然后发送到备案省(即户籍所在省)的管局,时长最多 20 天,建议提前搞。我用了 6 天。</p> |
438 | <h2 id="nginx-代理">Nginx 代理</h2> | 386 | <h2 id="nginx-代理">Nginx 代理</h2> |
439 | <p>都做好之后,访问<code>code.player.com</code>,发现啥也没有,浏览器说对面没反应。是的,因为 A 记录只解析到了 ip,并没有解析到指定端口,而 http 默认端口 80,https | 387 | <p>都做好之后,访问<code>code.player.com</code>,发现啥也没有,浏览器说对面没反应。是的,因为 A 记录只解析到了 ip,并没有解析到指定端口,而 http 默认端口 80,https |
440 | 默认端口 | 388 | 默认端口 443,都和上边 code-server 指定的端口 8080 不一样。</p> |
441 | 443,都和上边 code-server 指定的端口 8080 不一样。</p> | ||
442 | <p>没错,我们需要一个代理,根据访问的网址来对应到指定端口。</p> | 389 | <p>没错,我们需要一个代理,根据访问的网址来对应到指定端口。</p> |
443 | <h3 id="安装-1">安装</h3> | 390 | <h3 id="安装运行与常用操作">安装、运行与常用操作</h3> |
444 | <pre><code>sudo apt install nginx</code></pre> | 391 | <pre><code>sudo apt install nginx |
445 | <h3 id="运行-1">运行</h3> | 392 | # 安装完成后如果服务器重启,nginx会自动启动,手动启动命令如下 |
446 | <pre><code>nginx</code></pre> | 393 | sudo nginx |
394 | |||
395 | # 停止服务 | ||
396 | sudo nginx -s stop | ||
397 | |||
398 | # 重新加载配置文件(适用于修改了配置文件但不需要重启的场景) | ||
399 | sudo nginx -s reload</code></pre> | ||
447 | <h3 id="ssl-证书">SSL 证书</h3> | 400 | <h3 id="ssl-证书">SSL 证书</h3> |
448 | <p>想要使用 https 方式,还需要一个 SSL 证书,每个域名一个证。腾讯云比较坑,必须花钱。这里我用的是 Certbot 免费发放的证书。</p> | 401 | <p>想要使用 https 方式,还需要一个 SSL 证书,每个域名一个证。腾讯云比较坑,必须花钱。这里我用的是 Certbot 免费发放的证书。</p> |
449 | <p>首先,下载 Certbot:</p> | 402 | <p>首先,下载 Certbot:</p> |
450 | <pre><code>sudo apt install certbot</code></pre> | 403 | <pre><code>sudo apt install certbot</code></pre> |
451 | <p>在申请证书之前,需要停止 nginx 的工作,如果正在运行,按照上边说的方法杀死即可:</p> | 404 | <p>在申请证书之前,需要停止 nginx 的工作,如果正在运行,按照上边说的方法杀死,而后就可以申请证书辣!</p> |
452 | <pre><code class="language-bash">ps -ef | grep nginx | 405 | <pre><code># 申请证书 |
406 | sudo certbot certonly --standalone --email example@qq.com -d code.player.com | ||
453 | 407 | ||
454 | # 杀死显示的第一个进程 | 408 | # 除了使用参数方式外,也可以使用交互的方式 |
455 | kill -9 <进程号> | 409 | sudo certbot certonly</code></pre> |
456 | |||
457 | # 重启nginx | ||
458 | nginx</code></pre> | ||
459 | <p>而后就可以申请证书辣!</p> | ||
460 | <pre><code class="language-bash"># 申请证书 | ||
461 | sudo certbot certonly --standalone --email example@qq.com -d code.player.com</code></pre> | ||
462 | <p>申请完成后会展示证书的存储路径,记下来,后边会用到。比如:</p> | 410 | <p>申请完成后会展示证书的存储路径,记下来,后边会用到。比如:</p> |
463 | <p>SSL 证书 /etc/letsencrypt/live/code.play.com/fullchain.pem;</p> | 411 | <p>SSL 证书 /etc/letsencrypt/live/code.player.com/fullchain.pem;</p> |
464 | <p>SSL 证书秘钥 /etc/letsencrypt/live/code.play.com/privkey.pem;</p> | 412 | <p>SSL 证书秘钥 /etc/letsencrypt/live/code.player.com/privkey.pem;</p> |
465 | <h3 id="修改添加配置">修改、添加配置</h3> | 413 | <h3 id="修改添加配置">修改、添加配置</h3> |
466 | <p>Nginx | 414 | <p>Nginx |
467 | 默认下载目录在<code>/etc/nginx</code>,该目录下有个<code>.conf</code>文件,但不建议直接改,建议在<code>/etc/nginx/conf.d</code>文件夹下为每个需要转发的域名添加单独的设置文件,这样方便管理和修改。运行过程中 | 415 | 默认下载目录在<code>/etc/nginx</code>,该目录下有个<code>.conf</code>文件,但不建议直接改,建议在<code>/etc/nginx/conf.d</code>文件夹下为每个需要转发的域名添加单独的设置文件,这样方便管理和修改。运行过程中 |
468 | Nginx 会自动将该目录下所有配置文件全部加载的,不需要手动设置。</p> | 416 | Nginx 会自动将该目录下所有配置文件全部加载的,不需要手动设置。</p> |
469 | <p>在<code>/etc/nginx/conf.d</code>中,新建文件<code>vscode.conf</code>,内容如下:</p> | 417 | <p>在<code>/etc/nginx/conf.d</code>中,新建文件<code>vscode.conf</code>,内容如下:</p> |
470 | <pre><code class="language-plaintext">server | 418 | <pre><code>server |
471 | { | 419 | { |
420 | # 这段是一个常用的http重定向到https的方法,用了都说好 | ||
472 | listen 80; | 421 | listen 80; |
473 | server_name code.player.com; | 422 | server_name code.player.com; |
474 | return 301 https://$host$request_uri; | 423 | return 301 https://$host$request_uri; |
@@ -478,21 +427,102 @@ server | |||
478 | server_name code.player.com; | 427 | server_name code.player.com; |
479 | listen 443 ssl; | 428 | listen 443 ssl; |
480 | 429 | ||
430 | # 证书路径 | ||
481 | ssl_certificate /etc/letsencrypt/live/code.player.com/fullchain.pem; | 431 | ssl_certificate /etc/letsencrypt/live/code.player.com/fullchain.pem; |
482 | ssl_certificate_key /etc/letsencrypt/live/code.player.com/privkey.pem; | 432 | ssl_certificate_key /etc/letsencrypt/live/code.player.com/privkey.pem; |
483 | 433 | ||
434 | # 这是对于code-server做出的设置 | ||
484 | location / { | 435 | location / { |
485 | proxy_pass http://127.0.0.1:8080;# 这里的端口号要和code-server指定的端口号一致,我是8080 | 436 | proxy_pass http://127.0.0.1:8080; # 这里的端口号要和code-server指定的端口号一致,我是8080 |
486 | proxy_set_header Host $host; | 437 | proxy_set_header Host $host; |
487 | proxy_set_header Upgrade $http_upgrade; | 438 | proxy_set_header Upgrade $http_upgrade; |
488 | proxy_set_header Connection upgrade; | 439 | proxy_set_header Connection upgrade; |
489 | proxy_set_header Accept-Encoding gzip; | 440 | proxy_set_header Accept-Encoding gzip; |
490 | } | 441 | } |
442 | |||
443 | # 如果文件对应的是webroot服务(也就是一个文件夹下存放着指定网址的网页) | ||
444 | # 需要将上边的配置修改为 | ||
445 | # location / { | ||
446 | # root /var/myweb/; # 这里是文件夹路径 | ||
447 | # index index.html; # 这里是每个文件夹下默认打开的文件 | ||
448 | # } | ||
491 | }</code></pre> | 449 | }</code></pre> |
492 | <p>亲测有效。</p> | ||
493 | <p>编写完文件之后,需要重新加载配置文件(不必重启 Nginx):</p> | 450 | <p>编写完文件之后,需要重新加载配置文件(不必重启 Nginx):</p> |
494 | <pre><code class="language-bash">nginx -s reload</code></pre> | 451 | <pre><code>sudo nginx -s reload</code></pre> |
495 | <p>但在使用过程中,一定记得把域名换成自己的域名、证书路径换成自己的证书路径、端口换成自己在 code-server 中指定的端口!</p> | 452 | <p>再次提醒:一定记得把域名换成自己的域名、证书路径换成自己的证书路径、端口换成自己在提供服务的应用(如 code-server)中指定的端口!</p> |
453 | <h1 id="服务器上的文件浏览">服务器上的文件浏览</h1> | ||
454 | <p>我们已经学会了设置 nginx 的 webroot,但也有很多情况我们需要能在各种设备上直接地看到服务器上有哪些文件,既能方便文件传输,也能覆盖对大多数只需要看不需要改的场景。</p> | ||
455 | <p>python3 为我们提供了一个简单的 http 文件浏览服务,默认安装目录为<code>/usr/lib/python3.x/http/server.py</code>,一般情况下我们可以直接运行它:</p> | ||
456 | <pre><code>python3 -m http.server</code></pre> | ||
457 | <p>但是 python 提供的这份文件存在一些问题:</p> | ||
458 | <ul> | ||
459 | <li>响应头没有规定文件编码,让浏览器自己看着办,容易出现乱码</li> | ||
460 | <li>里边选择性忽略了一些文件、文件夹</li> | ||
461 | </ul> | ||
462 | <p>于是我在给定的基础上做了一些小修改,修改版的文件在<a href="https://www.qin-juan-ge-zhu.top/code/linux/httpmyserver.html">这里</a>。 | ||
463 | </p> | ||
464 | <h1 id="git-远程存储">git 远程存储</h1> | ||
465 | <p>君不闻《西游记》有云:</p> | ||
466 | <blockquote> | ||
467 | <p>争名夺利几时休,早起迟眠不自由。</p> | ||
468 | <p>骑着驴骡思骏马,官居宰相望王侯。</p> | ||
469 | </blockquote> | ||
470 | <p>完成了代码环境的配置,我就在想,要是有一个自己的远程 git 托管环境该多好?那就干!</p> | ||
471 | <p>我的详细配置方法写在<a href="https://www.qin-juan-ge-zhu.top/code/linux/gitserver.html">这里</a>里了。</p> | ||
472 | <h1 id="游戏">游戏</h1> | ||
473 | <blockquote> | ||
474 | <p>All work no play makes Jack a doll boy.</p> | ||
475 | </blockquote> | ||
476 | <p>经过了上边的配置,写代码的控制基本完善了,但是服务器怎么能只拿来干活呢?没有游戏怎么行?我们要快乐!</p> | ||
477 | <p>目前我装了三个游戏:</p> | ||
478 | <ul> | ||
479 | <li>俄罗斯方块,装的是<code>tint</code></li> | ||
480 | <li>扫雷,装的是<code>minebash</code></li> | ||
481 | <li>贪吃蛇,找不到力(允悲</li> | ||
482 | </ul> | ||
483 | <p>安装方法网上都有,就不多说了。玩得愉快!</p> | ||
484 | <h1 id="开机运行脚本">开机运行脚本</h1> | ||
485 | <p>经过了以上的设置,我的服务器已经有了许多服务,特别是每个计算机人电脑里必然需要养的一只宠物——小蓝猫 | ||
486 | clash。但是每次重启系统之后,这许多服务都需要自己手动拉起的话未免太过麻烦了,所以我们需要一个在系统加载完成后就能自动以 root 身份执行的脚本。经过查询,我找到了处理办法。</p> | ||
487 | <p>在 Linux 系统下,开机启动一般使用的是<code>/etc/rc.local</code>文件(但也有很多发行版不再使用这种操作方式)。ubuntu20.04 系统已经默认安装了 | ||
488 | rc-local.service 服务,但是不知什么原因系统把这个服务给“隐蔽”了,所以如果不做一番操作是无法使用的。</p> | ||
489 | <pre><code># 以下所有命令需要root身份执行 | ||
490 | |||
491 | cp /usr/lib/systemd/system/rc-local.service /etc/systemd/system/ | ||
492 | # 修改rc-local.service文件,在文件末尾添加以下内容(注意删去前边的注释符): | ||
493 | # [Install] | ||
494 | # WantedBy=multi-user.target | ||
495 | |||
496 | # 创建rc.local文件,带上shebang行 | ||
497 | echo '#!/bin/bash' > /etc/rc.local | ||
498 | # 修改rc.local文件权限 | ||
499 | chmod +x /etc/rc.local | ||
500 | |||
501 | # 上述步骤完成后,注意不要急于写rc.local脚本,我们需要先启动rc-local.service服务 | ||
502 | systemctl start rc-local.service | ||
503 | systemctl enable rc-local.service | ||
504 | # 上述两条命令运行正常时,系统需要重启 | ||
505 | reboot | ||
506 | |||
507 | # 重启完成后,检查rc-local.service服务是否正常运行 | ||
508 | systemctl status rc-local.service | ||
509 | |||
510 | # 一切正常,就可以编写rc.local脚本的内容了 | ||
511 | # 需要注意的是,该脚本以root身份运行,所以不需要sudo | ||
512 | # 如果部分命令需要以其他用户身份运行,可以使用su命令,如: | ||
513 | # su -l <username> -c <要运行的命令> | ||
514 | # 如果要运行的是脚本(不建议,没必要),注意对应参数 | ||
515 | # 文件的最后,可以用exec &> /var/log/rc-local.log将脚本的输出重定向到日志文件中</code></pre> | ||
516 | <p>除此之外,我们可能还需要为所有用户默认开启魔法。这个功能在开机脚本和<code>/etc/profile</code>中都无法实现,应当放在<code>/etc/environment</code>中。在其中添加以下内容: | ||
517 | </p> | ||
518 | <pre><code>PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin" | ||
519 | http_proxy=http://127.0.0.1:7890 | ||
520 | https_proxy=http://127.0.0.1:7890 | ||
521 | no_proxy=127.0.0.1,localhost | ||
522 | HTTP_PROXY=http://127.0.0.1:7890 | ||
523 | HTTPS_PROXY=http://127.0.0.1:7890 | ||
524 | NO_PROXY=127.0.0.1,localhost</code></pre> | ||
525 | <p>该文件中的所有设置对于所有用户均有效,着实省去了每次开机、切换用户都要手动挂代理的麻烦。</p> | ||
496 | <h1 id="碎碎念">碎碎念</h1> | 526 | <h1 id="碎碎念">碎碎念</h1> |
497 | <blockquote> | 527 | <blockquote> |
498 | <p>王子猷(徽之)居山阴,夜大雪,眠觉,开室命酌酒,四望皎然。因起彷徨。咏左思《招隐诗》,忽忆戴安道(逵)。时戴在剡,即便夜乘小船就之。经宿方至,造门不前而返。人问其故,王曰:“吾本乘兴而行,兴尽而返,何必见戴!” | 528 | <p>王子猷(徽之)居山阴,夜大雪,眠觉,开室命酌酒,四望皎然。因起彷徨。咏左思《招隐诗》,忽忆戴安道(逵)。时戴在剡,即便夜乘小船就之。经宿方至,造门不前而返。人问其故,王曰:“吾本乘兴而行,兴尽而返,何必见戴!” |
@@ -501,8 +531,8 @@ server | |||
501 | </blockquote> | 531 | </blockquote> |
502 | <p>一时兴起跟着黄四郎同志搞了前端,又一时兴起薅资本主义羊毛搞服务器,甚至现在写这篇文档也是一时兴起。可能我就是这样一个人吧,想到哪里做到哪里,全是为了快乐。</p> | 532 | <p>一时兴起跟着黄四郎同志搞了前端,又一时兴起薅资本主义羊毛搞服务器,甚至现在写这篇文档也是一时兴起。可能我就是这样一个人吧,想到哪里做到哪里,全是为了快乐。</p> |
503 | <p>这篇文档是对一个月以来搞云服务器的配置的一个小小总结,本来以为没多少东西,结果写了整整一下午到现在,一个 Markdown 文档,手写居然达到了 900 多行、将近 40KB,令我也大吃一惊。</p> | 533 | <p>这篇文档是对一个月以来搞云服务器的配置的一个小小总结,本来以为没多少东西,结果写了整整一下午到现在,一个 Markdown 文档,手写居然达到了 900 多行、将近 40KB,令我也大吃一惊。</p> |
504 | <p>也许我之后还会继续鼓捣我的服务器,那时候就继续写下去吧。现在也许该考虑考虑期末考试了(笑。</p> | 534 | <p>也许我之后还会继续鼓捣我的服务器,那时候就继续写下去吧。现在该考虑考虑期末考试了(笑。</p> |
505 | <p class="time">2023.5.30傍晚</p> | 535 | <p class="time">2023.5.30傍晚<br>2024.1.3</p> |
506 | <script src="https://www.qin-juan-ge-zhu.top/common/js/comment.js"></script> | 536 | <script src="https://www.qin-juan-ge-zhu.top/common/js/comment.js"></script> |
507 | </div> | 537 | </div> |
508 | </div> | 538 | </div> |
diff --git a/code/linux/aliyun_cloud.md b/code/linux/aliyun_cloud.md index 5bd4857..d059571 100644 --- a/code/linux/aliyun_cloud.md +++ b/code/linux/aliyun_cloud.md | |||
@@ -18,17 +18,17 @@ | |||
18 | 18 | ||
19 | 另外,由于是一个临时账号,我个人建议另找一个浏览器做实验,方便和自己现在用的帐户/ECS 实例区别开来。 | 19 | 另外,由于是一个临时账号,我个人建议另找一个浏览器做实验,方便和自己现在用的帐户/ECS 实例区别开来。 |
20 | 20 | ||
21 | # 服器配置 | 21 | ## 件配置 |
22 | 22 | ||
23 | 服务器硬件配置应该都是固定的吧?CPU 双核,内存 2G,硬盘 40G,带宽 1MBps。我个人觉得这个配置还是挺不错的,毕竟是白嫖,要求也不能太高了不是? | 23 | 服务器硬件配置应该都是固定的吧?CPU 双核,内存 2G,硬盘 40G,带宽 1MBps。我个人觉得这个配置还是挺不错的,毕竟是白嫖,要求也不能太高了不是? |
24 | 24 | ||
25 | 操作系统方面,由于个人比较喜欢纯命令行操作,所以选择了 Ubuntu22.04 LTS,我的虚拟机也是这个版本,相对而言会比其他发行版更熟悉一些。 | 25 | 操作系统方面,由于个人比较喜欢纯命令行操作,所以选择了 Ubuntu22.04 LTS,我的虚拟机也是这个版本,相对而言会比其他发行版更熟悉一些。 |
26 | 26 | ||
27 | ## 服务器初始化 | 27 | # 服务器初始化 |
28 | 28 | ||
29 | 在跟着创建实例的要求一步步做好之后,我们就拥有了一台属于自己的服务器了,并已经有了根用户 root。接下来,我们需要做一些初始化的工作。 | 29 | 在跟着创建实例的要求一步步做好之后,我们就拥有了一台属于自己的服务器了,并已经有了根用户 root。接下来,我们需要做一些初始化的工作。 |
30 | 30 | ||
31 | ### 创建新用户 | 31 | ## 创建新用户 |
32 | 32 | ||
33 | 众所周知,**为了安全起见,我们需要一个非 root 但具有 sudo 权限的用户来进行日常操作**。这里我创建了一个名为<kbd>player</kbd>的用户并设置了密码,然后将其加入 sudo 组。 | 33 | 众所周知,**为了安全起见,我们需要一个非 root 但具有 sudo 权限的用户来进行日常操作**。这里我创建了一个名为<kbd>player</kbd>的用户并设置了密码,然后将其加入 sudo 组。 |
34 | 34 | ||
@@ -48,37 +48,10 @@ sudo apt install vim | |||
48 | 48 | ||
49 | cd /etc | 49 | cd /etc |
50 | sudo vim sudoers | 50 | sudo vim sudoers |
51 | # 找到root ALL=(ALL:ALL) ALL,按o新开一行,然后写一份一样的,把root改成player | 51 | # 找到root ALL=(ALL:ALL) ALL, |
52 | # ESC,输入:wq保存退出 | 52 | # 开一然后写一份一样的,把root改成player,保存退出 |
53 | ``` | 53 | ``` |
54 | 54 | ||
55 | 这时我们会发现一个很操蛋的事情,“为啥命令提示符之前不显示当前用户名和当前路径嘞?这岂不是每次看路径都需要<kbd>pwd</kbd>吗?烦不烦啊!”别急,问题很好修改。 | ||
56 | |||
57 | ```bash | ||
58 | cd /home/player | ||
59 | vim .bashrc | ||
60 | # 找到PS1=,将其修改为PS1="\u@\h:\w\$" | ||
61 | # 按ESC,输入:wq保存退出 | ||
62 | ``` | ||
63 | |||
64 | 修改退出之后似乎一切都没有变化。我们需要重启一下服务器。 | ||
65 | |||
66 | ```bash | ||
67 | sudo reboot | ||
68 | ``` | ||
69 | |||
70 | 重新连接之后,也许还是没有变化,我就是这样的。后来在处理其它问题的时候,我发现了根本原因所在:我 TM 创建用户的时候忘了加<kbd>-s</kbd>参数,导致新用户的默认 shell 是<kbd>sh</kbd>而不是<kbd>bash</kbd>。所以,我们需要修改一下新用户的默认 shell。 | ||
71 | |||
72 | ```bash | ||
73 | # 查看当前用户的默认shell | ||
74 | echo $SHELL | ||
75 | |||
76 | # 修改默认shell | ||
77 | sudo chsh -s /bin/bash player | ||
78 | ``` | ||
79 | |||
80 | 这时再重启服务器,就会发现,一切都正常了,一切是那么美好。 | ||
81 | |||
82 | ## 安装软件 | 55 | ## 安装软件 |
83 | 56 | ||
84 | 经历了上边的配置,现在我们拥有了一台可以正常使用的服务器。服务器是为了什么?开发!开发!开发!所以,我们需要安装一些开发所需的软件。 | 57 | 经历了上边的配置,现在我们拥有了一台可以正常使用的服务器。服务器是为了什么?开发!开发!开发!所以,我们需要安装一些开发所需的软件。 |
@@ -111,17 +84,182 @@ sudo apt install make cmake | |||
111 | # 剩下需要安装的软件,可以自行搜索 | 84 | # 剩下需要安装的软件,可以自行搜索 |
112 | ``` | 85 | ``` |
113 | 86 | ||
114 | ## 配置 ssh | 87 | ## 简单美化一下命令行 |
88 | |||
89 | 配到这里,我们会发现一个很操蛋的事情,“为啥命令提示符之前不显示当前用户名和当前路径嘞?这岂不是每次看路径都需要<kbd>pwd</kbd>吗?烦不烦啊!”别急,问题很好修改。 | ||
90 | |||
91 | ```bash | ||
92 | cd ~ | ||
93 | vim .bashrc | ||
94 | # 找到PS1=,将其修改为PS1="\u@\h:\w\$" | ||
95 | |||
96 | # 加载.bashrc | ||
97 | source .bashrc | ||
98 | ``` | ||
99 | |||
100 | 改好之后也许还是没有变化,我就是这样的。后来在处理其它问题的时候,我发现了根本原因所在:我 TM 创建用户的时候忘了加<kbd>-s</kbd>参数,导致新用户的默认 shell 是<kbd>sh</kbd>而不是<kbd>bash</kbd>。所以,我们需要修改一下新用户的默认 shell。 | ||
101 | |||
102 | ```bash | ||
103 | # 查看当前用户的默认shell | ||
104 | echo $SHELL | ||
105 | |||
106 | # 修改默认shell | ||
107 | sudo chsh -s /bin/bash player | ||
108 | ``` | ||
109 | |||
110 | 这时再重新加载,就会发现,一切都正常了,一切是那么美好。 | ||
111 | |||
112 | 除此之外,我们也许想要调整命令行显示的用户名、路径之类内容的颜色,会想让命令行像 git bash 一样当我们进入 git 仓库的时候显示当前在什么分支。针对这两项需求,我修改了一下我的.bashrc 文件,现在其内容如下: | ||
113 | |||
114 | ```bash | ||
115 | # ~/.bashrc: executed by bash(1) for non-login shells. | ||
116 | # see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) | ||
117 | # for examples | ||
118 | |||
119 | # If not running interactively, don't do anything | ||
120 | case $- in | ||
121 | *i*) ;; | ||
122 | *) return;; | ||
123 | esac | ||
124 | |||
125 | # don't put duplicate lines or lines starting with space in the history. | ||
126 | # See bash(1) for more options | ||
127 | HISTCONTROL=ignoreboth | ||
128 | |||
129 | # append to the history file, don't overwrite it | ||
130 | shopt -s histappend | ||
131 | |||
132 | # for setting history length see HISTSIZE and HISTFILESIZE in bash(1) | ||
133 | HISTSIZE=1000 | ||
134 | HISTFILESIZE=2000 | ||
135 | |||
136 | # check the window size after each command and, if necessary, | ||
137 | # update the values of LINES and COLUMNS. | ||
138 | shopt -s checkwinsize | ||
139 | |||
140 | # If set, the pattern "**" used in a pathname expansion context will | ||
141 | # match all files and zero or more directories and subdirectories. | ||
142 | #shopt -s globstar | ||
143 | |||
144 | # make less more friendly for non-text input files, see lesspipe(1) | ||
145 | [ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" | ||
146 | |||
147 | # set variable identifying the chroot you work in (used in the prompt below) | ||
148 | if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then | ||
149 | debian_chroot=$(cat /etc/debian_chroot) | ||
150 | fi | ||
151 | |||
152 | # set a fancy prompt (non-color, unless we know we "want" color) | ||
153 | case "$TERM" in | ||
154 | xterm-color|*-256color) color_prompt=yes;; | ||
155 | esac | ||
156 | |||
157 | # uncomment for a colored prompt, if the terminal has the capability; turned | ||
158 | # off by default to not distract the user: the focus in a terminal window | ||
159 | # should be on the output of commands, not on the prompt | ||
160 | #force_color_prompt=yes | ||
161 | |||
162 | if [ -n "$force_color_prompt" ]; then | ||
163 | if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then | ||
164 | # We have color support; assume it's compliant with Ecma-48 | ||
165 | # (ISO/IEC-6429). (Lack of such support is extremely rare, and such | ||
166 | # a case would tend to support setf rather than setaf.) | ||
167 | color_prompt=yes | ||
168 | else | ||
169 | color_prompt= | ||
170 | fi | ||
171 | fi | ||
172 | |||
173 | # 简单修改一下颜色 | ||
174 | if [ "$color_prompt" = yes ]; then | ||
175 | PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\[\033[00m\]' | ||
176 | else | ||
177 | PS1='${debian_chroot:+($debian_chroot)}\u@\h:' | ||
178 | fi | ||
179 | |||
180 | # 如果是git仓库,在命令行提示符之前用不同的颜色显示当前分支 | ||
181 | PS1="$PS1"'\[\033[33m\]' # change to yellow | ||
182 | PS1="$PS1"'\w' # pwd | ||
183 | PS1="$PS1"'\[\033[36m\]' # change color to cyan | ||
184 | PS1="$PS1"'`__git_ps1`' # git branch | ||
185 | PS1="$PS1"'\[\033[0m\]' # change color | ||
186 | #PS1="$PS1"'\n' # new line | ||
187 | PS1="$PS1"'\$ ' # prompt: always $ | ||
188 | unset color_prompt force_color_prompt | ||
189 | |||
190 | # If this is an xterm set the title to user@host:dir | ||
191 | case "$TERM" in | ||
192 | xterm*|rxvt*) | ||
193 | PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1" | ||
194 | ;; | ||
195 | *) | ||
196 | ;; | ||
197 | esac | ||
198 | |||
199 | # enable color support of ls and also add handy aliases | ||
200 | if [ -x /usr/bin/dircolors ]; then | ||
201 | test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" | ||
202 | alias ls='ls --color=auto' | ||
203 | #alias dir='dir --color=auto' | ||
204 | #alias vdir='vdir --color=auto' | ||
205 | |||
206 | alias grep='grep --color=auto' | ||
207 | alias fgrep='fgrep --color=auto' | ||
208 | alias egrep='egrep --color=auto' | ||
209 | fi | ||
210 | |||
211 | # colored GCC warnings and errors | ||
212 | #export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' | ||
213 | |||
214 | # some more ls aliases | ||
215 | alias ll='ls -alF' | ||
216 | alias la='ls -A' | ||
217 | alias l='ls -CF' | ||
218 | |||
219 | # Add an "alert" alias for long running commands. Use like so: | ||
220 | # sleep 10; alert | ||
221 | alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"' | ||
222 | |||
223 | # Alias definitions. | ||
224 | # You may want to put all your additions into a separate file like | ||
225 | # ~/.bash_aliases, instead of adding them here directly. | ||
226 | # See /usr/share/doc/bash-doc/examples in the bash-doc package. | ||
227 | |||
228 | if [ -f ~/.bash_aliases ]; then | ||
229 | . ~/.bash_aliases | ||
230 | fi | ||
231 | |||
232 | # enable programmable completion features (you don't need to enable | ||
233 | # this, if it's already enabled in /etc/bash.bashrc and /etc/profile | ||
234 | # sources /etc/bash.bashrc). | ||
235 | if ! shopt -oq posix; then | ||
236 | if [ -f /usr/share/bash-completion/bash_completion ]; then | ||
237 | . /usr/share/bash-completion/bash_completion | ||
238 | elif [ -f /etc/bash_completion ]; then | ||
239 | . /etc/bash_completion | ||
240 | fi | ||
241 | fi | ||
242 | echo This\ is\ .bashrc. | ||
243 | |||
244 | alias pip='python -m pip' | ||
245 | # 设置bash使用vim模式,允许使用0、dw之类常用vim快捷键,方便命令编辑 | ||
246 | set -o vi | ||
247 | # 有时候我们需要一些魔法 | ||
248 | export http_proxy=http://127.0.0.1:7890 | ||
249 | export https_proxy=http://127.0.0.1:7890 | ||
250 | ``` | ||
251 | |||
252 | # 配置 ssh | ||
115 | 253 | ||
116 | 用着用着,就会发现:我为啥一直在浏览器里搞命令行?要是能直接在本地的命令行里搞就好了。当然,阿里云能满足我们。 | 254 | 用着用着,就会发现:我为啥一直在浏览器里搞命令行?要是能直接在本地的命令行里搞就好了。当然,阿里云能满足我们。 |
117 | 255 | ||
118 | ### ssh 简介 | 256 | ## ssh 简介 |
119 | 257 | ||
120 | 什么是 ssh?ssh 是 Secure Shell 的缩写,中文名为安全外壳协议。ssh 是一种加密的网络协议,可以在不安全的网络中为网络服务提供安全的传输环境。ssh 是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用 ssh 协议可以有效防止远程管理过程中的信息泄露问题。通过 ssh 可以对所有传输的数据进行加密,也能够防止 DNS 欺骗和 IP 欺骗。ssh 还支持在两个远程主机之间进行数据的传输。 | 258 | 什么是 ssh?ssh 是 Secure Shell 的缩写,中文名为安全外壳协议。ssh 是一种加密的网络协议,可以在不安全的网络中为网络服务提供安全的传输环境。ssh 是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用 ssh 协议可以有效防止远程管理过程中的信息泄露问题。通过 ssh 可以对所有传输的数据进行加密,也能够防止 DNS 欺骗和 IP 欺骗。ssh 还支持在两个远程主机之间进行数据的传输。 |
121 | 259 | ||
122 | 说了也记不住,直接开干! | 260 | 说了也记不住,直接开干! |
123 | 261 | ||
124 | ### 配置安全组规则 | 262 | ## 配置安全组规则 |
125 | 263 | ||
126 | 在阿里云控制台左上角点击,选择`云服务器ECS`,会进入云服务器实例控制界面。在左侧菜单栏寻找`安全组` ,添加安全组规则。按要求添加新的安全组规则,开放 TCP 协议对应的 22 端口。(其实可以都开了,但是毕竟不安全,建议后续按需开放。) | 264 | 在阿里云控制台左上角点击,选择`云服务器ECS`,会进入云服务器实例控制界面。在左侧菜单栏寻找`安全组` ,添加安全组规则。按要求添加新的安全组规则,开放 TCP 协议对应的 22 端口。(其实可以都开了,但是毕竟不安全,建议后续按需开放。) |
127 | 265 | ||
@@ -132,7 +270,7 @@ sudo apt install make cmake | |||
132 | - 将上述.pem 文件移动到家目录`C:\用户\当前用户名`的<kbd>.ssh</kbd>文件夹下 | 270 | - 将上述.pem 文件移动到家目录`C:\用户\当前用户名`的<kbd>.ssh</kbd>文件夹下 |
133 | - 在<kbd>.ssh</kbd>文件夹下创建文件<kbd>config</kbd>,内容如下: | 271 | - 在<kbd>.ssh</kbd>文件夹下创建文件<kbd>config</kbd>,内容如下: |
134 | 272 | ||
135 | ```txt | 273 | ```plaintext |
136 | # 给服务器起的别名,这里是aliyun | 274 | # 给服务器起的别名,这里是aliyun |
137 | Host aliyun | 275 | Host aliyun |
138 | # IP地址,这里以127.0.0.1代替,但真实操作需要换成服务器的公网ip,在控制台就能看到 | 276 | # IP地址,这里以127.0.0.1代替,但真实操作需要换成服务器的公网ip,在控制台就能看到 |
@@ -156,255 +294,21 @@ ssh aliyun | |||
156 | 294 | ||
157 | 既然我们选择了在命令行里使用,编辑文件当然是比较常用 vim 了。当然 neovim 与其他命令行编辑器也很好,但我不熟悉,请参照网上其他教程进行配置。 | 295 | 既然我们选择了在命令行里使用,编辑文件当然是比较常用 vim 了。当然 neovim 与其他命令行编辑器也很好,但我不熟悉,请参照网上其他教程进行配置。 |
158 | 296 | ||
159 | 我的 vim 学习与配置[链接](https://www.qin-juan-he-zhu.top/code/linux/vim.html)中有如下一些基本配置: | 297 | 我的 vim 学习与配置[链接](https://www.qin-juan-ge-zhu.top/code/linux/vim.html)中有如下一些基本配置: |
160 | 298 | ||
161 | - 同时开启绝对行号与相对行号,则当前行显示真实行号,其他行显示相对于当前行为上/下第几行,方便跳转。 | ||
162 | - 代码中常常需要的`()[]{}`自动匹配 | ||
163 | - 自动缩进和智能缩进,但似乎没啥鸟用 | ||
164 | - vim 自带的代码高亮,感觉还是相当不错的 | 299 | - vim 自带的代码高亮,感觉还是相当不错的 |
300 | - 代码中常常需要的`()[]{}`自动匹配 | ||
301 | - 同时开启绝对行号与相对行号,则当前行显示真实行号,其他行显示相对于当前行为上/下第几行,方便跳转。 | ||
302 | - 代码按语法缩进,并且每次保存或退出时自动格式化 | ||
165 | - 当前行/当前列各给一个颜色,因为有的平台光标显示很不明显,正常插入模式一般也不好确定光标位置,这样方便知道光标在哪。 | 303 | - 当前行/当前列各给一个颜色,因为有的平台光标显示很不明显,正常插入模式一般也不好确定光标位置,这样方便知道光标在哪。 |
166 | - 自动折行,即当前行太长了会被折回来显示,但还是同一行,方便一次性看完整。 | 304 | - 自动折行,即当前行太长了会被折回来显示,但还是同一行,方便一次性看完整。 |
167 | - 一些快捷键,如<kbd>ta</kbd>到行末(替代够不到的<kbd>$</kbd>),<kbd>end</kbd>来到文件末(替代难记的<kbd>G</kbd>),还有<kbd>up/ne</kbd>上/下移动 20 行等。 | 305 | - 一些快捷键,如<kbd>L</kbd>到行末(替代够不到的<kbd>$</kbd>),还有<kbd>K/J</kbd>上/下移动 10 行等。 |
168 | - 自动识别文件类型,并对`*.html, *.c, *.cpp, *.python`等文件在保存<kbd>:w<Enter></kbd>时自动格式化,在正常或选择模式下<kbd>Ctrl+p</kbd>一键注释(别骂了别骂了,<kbd>Ctrl+/</kbd>我属实是设置不出来) | 306 | - 基本的状态栏设置,包括文件名、git 分支、文件编码、文件类型、总行数等信息,方便查看。 |
169 | 307 | - 自动识别文件类型,并对`*.html, *.c, *.cpp, *.python`等文件在保存<kbd>:w<Enter></kbd>时自动格式化 | |
170 | ## 插件 | 308 | - 插件和其他重重 |
171 | 309 | ||
172 | 这里使用了几个插件,插件管理目前用的是评价一般的`Vundle`。个人评价,下载插件啥的属实是慢,每次都报错报到怀疑人生,害得我都得手动安装然后在里边添加,但是别的目前还不会使。气死偶勒! | 310 | 这里使用了几个插件,插件管理目前用的是评价一般的`Vundle`。个人评价,下载插件啥的属实是慢,每次都报错报到怀疑人生,害得我都得手动安装然后在里边添加,但是别的目前还不会使。气死偶勒! |
173 | 311 | ||
174 | 这里需要注意的是,上文提到我喜欢把有用的东西放在`~/useful`下,但是如果直接这样写路径,其他用户如 root 等使用时候就会报错,人家的主目录第下没这个东西!所以,在写路径的位置,切记要写绝对路径!!! | ||
175 | |||
176 | # 游戏 | ||
177 | |||
178 | > All work no play makes Jack a doll boy. | ||
179 | |||
180 | 经过了上边的配置,写代码的控制基本完善了,但是服务器怎么能只拿来干活呢?没有游戏怎么行?我们要快乐! | ||
181 | |||
182 | 目前我的服务器上装了三个游戏 | ||
183 | |||
184 | - 俄罗斯方块,装的是`tint` | ||
185 | - 扫雷,装的是`miebash` | ||
186 | - 贪吃蛇,找不到力(允悲 | ||
187 | |||
188 | 安装方法网上都有,就不多说了。玩得愉快! | ||
189 | |||
190 | # git 远程存储 | ||
191 | |||
192 | 君不闻,《西游记》有云: | ||
193 | |||
194 | > 争名夺利几时休,早起迟眠不自由。 | ||
195 | > | ||
196 | > 骑着驴骡思骏马,官居宰相望王侯。 | ||
197 | |||
198 | 完成了代码环境的配置,我就在想,要是有一个自己的远程 git 存储库该多好? | ||
199 | |||
200 | 说干就干,我找到了 gitlab 安装教程,信心满满,谁知"先帝创业未半而中道崩殂"。 | ||
201 | |||
202 | ## gitlab? | ||
203 | |||
204 | 我按照网上的教程,更新了清华镜像源,下载安装 gitlab。孰料一次一次在安装过程卡死,而且情况十分严重,CPU | ||
205 | 占用率长期维持在 50%以上,内存更是飙升到 90%,现在不仅安装进行不下去了,甚至一切操作都不认识,包括<kbd>Ctrl+C</kbd>想要杀死当前进程的请求也会石沉大海。没办法,只得强制重启。 | ||
206 | |||
207 | 如是反复若干次,最终死心,将 gitlab 彻底从云服务器卸载,"革职为民,永不叙用"。 | ||
208 | |||
209 | 经过上网查找,原因果然出现在配置上。**gitlab 推荐的最小内存是 4G,但是目前我们只有 2G,内存爆满也就理所当然了。**没办法,期限之内不能更改配置,就算能更改,我都穷到薅资本主义羊毛了,还能有钱升级配置?笑死。 | ||
210 | |||
211 | ## 就这? | ||
212 | |||
213 | 就因为这个问题,我们就不干了?这是不行滴,小同志。 | ||
214 | |||
215 | 不久之后,黄四郎同志发来了一篇博客:[最简单的 git 服务器](https://www.ruanyifeng.com/blog/2022/10/git-server.html) | ||
216 | |||
217 | 看起来似乎不错,但是失之简略。幸好,我在 git 官方教程[Pro Git](https://git-scm.com/book/zh/v2)上找到了另一部分,两个拼一拼、试一试,最终成功了。 | ||
218 | |||
219 | 注意,本地和远程都需要安装 git,相信能看这里的读者应该已经是安装过了,这里不再赘述。 | ||
220 | |||
221 | ### 前置 | ||
222 | |||
223 | 在创建存储库之前,我想我们应该做些什么。 | ||
224 | |||
225 | 对了,创建新用户吧!按照上述写的步骤创建一个新用户并为之设置密码,可以不用加入 sudo 组,因为我们不需要这个用户来操作服务器,只需要用来存储代码就行了。 | ||
226 | |||
227 | ### 本地存储库 | ||
228 | |||
229 | 本地我们需要一个存储库,如果已有的则可以忽略本部分。 | ||
230 | |||
231 | ```bash | ||
232 | # 创建本地存储库,这里叫test吧 | ||
233 | mkdir test | ||
234 | cd test | ||
235 | git init | ||
236 | ``` | ||
237 | |||
238 | 但是本方法要求本地存储库必须已经有 commit(s)。好办,就写一个常用的`.gitignore`好了。 | ||
239 | |||
240 | ```vim | ||
241 | *.sh | ||
242 | *.bat | ||
243 | *.exe | ||
244 | *.dll | ||
245 | *.so | ||
246 | *.[oa] | ||
247 | *.idea | ||
248 | ``` | ||
249 | |||
250 | 而后,为了方便提交操作,可以再创建一个`push.sh`脚本: | ||
251 | |||
252 | ```bash | ||
253 | #!/bin/bash | ||
254 | git add . | ||
255 | git commit | ||
256 | git push | ||
257 | ``` | ||
258 | |||
259 | 注意,创建`push.sh`一定要在`.gitignore`之后,否则不会被忽略的。 | ||
260 | |||
261 | ### 远程仓库 | ||
262 | |||
263 | 就一句话: | ||
264 | |||
265 | ```bash | ||
266 | # 创建远程仓库,这里也叫test吧 | ||
267 | ssh git@127.0.0.1 git init --bare test.git | ||
268 | ``` | ||
269 | |||
270 | 注意,本处指明的 git 为远程用户名,127.0.0.1 代表云服务器的公网 ip,test.git 为远程仓库名。使用的时候都需要换成自己的。 | ||
271 | |||
272 | ### 本地与远程连接 | ||
273 | |||
274 | 本地和远程都有了,下一步就是建立联系了。 | ||
275 | |||
276 | ```bash | ||
277 | # 本地添加远程 | ||
278 | git remote add origin git@127.0.0.1:test.git | ||
279 | |||
280 | # 此时尚不能直接推送,因为并未指定上游对应分支,需要指定 | ||
281 | git push --set-upstream origin master | ||
282 | |||
283 | # 之后就可以直接推送了 | ||
284 | sh push.sh | ||
285 | ``` | ||
286 | |||
287 | ### 自动化 | ||
288 | |||
289 | 怎么样,操作看起来又臭又长吧?我也这么觉得。所以我写了两份代码,供同时自动创建本地仓库和远程对应仓库并建立所有对应关系之用。 | ||
290 | |||
291 | ```c | ||
292 | /* | ||
293 | * gitadd.c | ||
294 | */ | ||
295 | #include <stdio.h> | ||
296 | #include <stdlib.h> | ||
297 | #include <string.h> | ||
298 | #include <direct.h> | ||
299 | |||
300 | int main() | ||
301 | { | ||
302 | char local_name[100],remote_name[100],tmp[100]; | ||
303 | printf("您好!\n请输入本地仓库名:"); | ||
304 | gets(local_name); | ||
305 | printf("请输入远程仓库名:"); | ||
306 | gets(remote_name); | ||
307 | |||
308 | //远程仓库创建 | ||
309 | strcpy(tmp,"ssh aliyun-git git init --bare "); | ||
310 | strcat(remote_name,".git"); | ||
311 | strcat(tmp,remote_name); | ||
312 | system(tmp); | ||
313 | |||
314 | //本地仓库创建 | ||
315 | mkdir(local_name); | ||
316 | chdir(local_name); | ||
317 | system("git init"); | ||
318 | |||
319 | //本地仓库初始化 | ||
320 | FILE* file; | ||
321 | //编写.gitignore | ||
322 | file=fopen(".gitignore","w"); | ||
323 | fprintf(file,"*.sh\n"); | ||
324 | fprintf(file,"*.bat\n"); | ||
325 | fprintf(file,"*.exe\n"); | ||
326 | fprintf(file,"*.[oa]\n"); | ||
327 | fprintf(file,"*.pyc\n"); | ||
328 | fprintf(file,"__pycache__\n"); | ||
329 | fprintf(file,"*.vscode\n"); | ||
330 | fprintf(file,"*.swp\n"); | ||
331 | fclose(file); | ||
332 | //编写push.sh | ||
333 | file=fopen("push.sh","w"); | ||
334 | fprintf(file,"git add .\n"); | ||
335 | fprintf(file,"git commit\n"); | ||
336 | fprintf(file,"git push"); | ||
337 | fclose(file); | ||
338 | |||
339 | //提交初始化commit | ||
340 | system("git add ."); | ||
341 | system("git commit -m \"Initial commit\""); | ||
342 | strcpy(tmp,"git remote add origin aliyun-git:"); | ||
343 | strcat(tmp,remote_name); | ||
344 | system(tmp); | ||
345 | system("git push --set-upstream origin master"); | ||
346 | system("git push"); | ||
347 | |||
348 | printf("完成!"); | ||
349 | return 0; | ||
350 | } | ||
351 | ``` | ||
352 | |||
353 | ```python | ||
354 | # gitadd.py | ||
355 | import os | ||
356 | |||
357 | if __name__ == '__main__': | ||
358 | print("你好!") | ||
359 | print("请输入本地仓库名:") | ||
360 | local_name = input() | ||
361 | print("请输入远程仓库名:") | ||
362 | remote_name = input() | ||
363 | os.system("ssh aliyun-git git init --bare "+remote_name+".git") | ||
364 | |||
365 | # 创建本地仓库 | ||
366 | os.system("mkdir "+local_name) | ||
367 | os.chdir(local_name) | ||
368 | print("本地仓库已建立!") | ||
369 | print("当前路径为"+os.getcwd()) | ||
370 | |||
371 | # 初始化git仓库 | ||
372 | os.system("git init") | ||
373 | |||
374 | # 以utf8编码编写.gitignore文件 | ||
375 | with open(".gitignore", "w", encoding="utf8") as f: | ||
376 | f.write("*.pyc\n") | ||
377 | f.write("__pycache__/\n") | ||
378 | f.write("*.exe\n") | ||
379 | f.write("*.[oa]\n") | ||
380 | f.write("*.swp\n") | ||
381 | f.write("*.sh\n") | ||
382 | f.write("*.bat\n") | ||
383 | |||
384 | # 编写push.sh文件 | ||
385 | with open("push.sh", "w", encoding="utf8") as f: | ||
386 | f.write("git add .\n") | ||
387 | f.write("git commit\n") | ||
388 | f.write("git push\n") | ||
389 | |||
390 | print("本地仓库初始化完成!") | ||
391 | |||
392 | # 连接远程仓库 | ||
393 | os.system("git add .") | ||
394 | os.system("git commit -m \"Initial commit\"") | ||
395 | os.system("git remote add origin aliyun-git:"+remote_name+".git") | ||
396 | os.system("git push --set-upstream origin master") | ||
397 | os.system("git push") | ||
398 | |||
399 | print("完成!") | ||
400 | ``` | ||
401 | |||
402 | **Attention please:** 本地仓库名和远程仓库名不要加后缀,程序会自动添加。另外,如果要修改,在转换本地当前工作目录的时候,**一定要使用语言自带的调整当前工作目录的函数,不要调用系统命令**,否则会出现编译器/解释器自动将程序作为多线程执行,导致一个线程进去了然后线程当场去世,后续的操作在另一个线程,工作目录根本没发生变化,也就是把原来所在的位置给 git 初始化了,出现奇奇怪怪的错误。 | ||
403 | |||
404 | ### 其他 | ||
405 | |||
406 | 需要明白的是,上述方法在远端创立的**只是一个裸仓库**(即只是我们本地仓库的`.git`文件夹),不包含工作目录,所以不能直接在远端进行操作,需要在本地进行操作,然后推送到远端。但是`git clone`的时候,本地得到的是一个完整的仓库,而其他使用也与普通仓库无异。 | ||
407 | |||
408 | # 来看看在线 VSCode 吧! | 312 | # 来看看在线 VSCode 吧! |
409 | 313 | ||
410 | 本来,一切就这样完美收官、从胜利走向更大的胜利了。坏就坏在我按照五个月前的计划添置了一个 iPad。在最初的设想里它就不单单是当平板做笔记看书用的,而是要充当电脑的编程功能,来在必要的时刻随拿随走,替代我这十几斤重、续航还短的游戏本的。 | 314 | 本来,一切就这样完美收官、从胜利走向更大的胜利了。坏就坏在我按照五个月前的计划添置了一个 iPad。在最初的设想里它就不单单是当平板做笔记看书用的,而是要充当电脑的编程功能,来在必要的时刻随拿随走,替代我这十几斤重、续航还短的游戏本的。 |
@@ -450,9 +354,6 @@ code-server | |||
450 | ```bash | 354 | ```bash |
451 | #!/bin/sh | 355 | #!/bin/sh |
452 | code-server --host "0.0.0.0"> /home/player/useful/codeserver-out.txt 2>&1 & | 356 | code-server --host "0.0.0.0"> /home/player/useful/codeserver-out.txt 2>&1 & |
453 | echo 启动完成!程序已在后台运行。 | ||
454 | echo 如需杀死进程,请以jobs查看后台程序编号并kill %num | ||
455 | echo 或ps查看进程号并kill之。 | ||
456 | ``` | 357 | ``` |
457 | 358 | ||
458 | 其中第一条指令是设置允许外界访问,并指定了由后台运行、所有输出写进`/home/player/useful/codeserver.txt`文件中。后续均为输出信息。 | 359 | 其中第一条指令是设置允许外界访问,并指定了由后台运行、所有输出写进`/home/player/useful/codeserver.txt`文件中。后续均为输出信息。 |
@@ -474,11 +375,8 @@ cert: false | |||
474 | 375 | ||
475 | 杀死的方法: | 376 | 杀死的方法: |
476 | 377 | ||
477 | ```bash | 378 | ```plaintext |
478 | # 运行指令 | 379 | $ ps -ef | grep code-server |
479 | ps -ef | grep code-server | ||
480 | |||
481 | # 输出结果如下 | ||
482 | player 2621 1 0 May29 ? 00:00:00 /usr/lib/code-server/lib/node /usr/lib/code-server --host 0.0.0.0 | 380 | player 2621 1 0 May29 ? 00:00:00 /usr/lib/code-server/lib/node /usr/lib/code-server --host 0.0.0.0 |
483 | player 2646 2621 0 May29 ? 00:03:31 /usr/lib/code-server/lib/node /usr/lib/code-server/out/node/entry | 381 | player 2646 2621 0 May29 ? 00:03:31 /usr/lib/code-server/lib/node /usr/lib/code-server/out/node/entry |
484 | player 3079 2646 0 May29 ? 00:00:57 /usr/lib/code-server/lib/node /usr/lib/code-server/lib/vscode/out/bootstrap-fork --type=ptyHost --logsPath /home/player/.local/share/code-server/logs/20230529T211752 | 382 | player 3079 2646 0 May29 ? 00:00:57 /usr/lib/code-server/lib/node /usr/lib/code-server/lib/vscode/out/bootstrap-fork --type=ptyHost --logsPath /home/player/.local/share/code-server/logs/20230529T211752 |
@@ -491,10 +389,10 @@ player 465057 464494 0 13:42 ? 00:00:35 /usr/lib/code-server/lib/nod | |||
491 | player 579173 574648 0 16:44 pts/1 00:00:00 grep --color=auto code-server | 389 | player 579173 574648 0 16:44 pts/1 00:00:00 grep --color=auto code-server |
492 | 390 | ||
493 | # 只需要杀死根进程也就是第一个进程就好,下边的数据需要改成当前对应进程号 | 391 | # 只需要杀死根进程也就是第一个进程就好,下边的数据需要改成当前对应进程号 |
494 | kill -9 2621 | 392 | $ kill -9 2621 |
495 | ``` | 393 | ``` |
496 | 394 | ||
497 | 重新启动之后,就可以用`<服务器公网ip>:<指定端口>`访问在线 VSCode 了,初次访问会比较慢,耐心等待吧。 | 395 | 重新启动之后,就可以用`ip:post`访问在线 VSCode 了,初次访问会比较慢,耐心等待吧。 |
498 | 396 | ||
499 | ## 同步设置 | 397 | ## 同步设置 |
500 | 398 | ||
@@ -535,16 +433,16 @@ kill -9 2621 | |||
535 | 433 | ||
536 | ## ICP 备案 | 434 | ## ICP 备案 |
537 | 435 | ||
538 | 众所周知,我国是工人阶级领导的、以工农联盟为基础的、人民民主专政的社会主义国家,一切事关宣传、舆论的东西都要在党的领导下,都要经过审查备案,包括建网站和域名 https 使用。 | 436 | 众所周知,我国是“工人阶级领导的、以工农联盟为基础的、人民民主专政的社会主义”国家,一切事关宣传、舆论的东西都要在党的领导下,都要经过审查备案,包括建网站和域名 https 使用。ICP 备案的原则是:**用谁的服务器,在谁那里备案**。以我为例,我在腾讯云买的域名、做的 DNS 解析,但用的是阿里云的服务器,就要在阿里云做 ICP 备案。 |
539 | |||
540 | ICP 备案的原则是:用谁的服务器,在谁那里备案。即以我而言,我在腾讯云买的域名、做的 DNS 解析,但用的是阿里云的服务器,就要在阿里云做 ICP 备案。 | ||
541 | 437 | ||
542 | 备案流程按按着走就行,只是有几点需要特别注意: | 438 | 备案流程按按着走就行,只是有几点需要特别注意: |
543 | 439 | ||
544 | - 备案的省份需要与户籍所在省一致 | 440 | - 备案的省份需要与户籍所在省一致 |
545 | - 备案网站名称不要太普通,容易和别人重复,会被客服小姐姐电话要求订正 | 441 | - 备案网站名称不要太普通,容易和别人重复,会被客服小姐姐电话要求订正 |
546 | - 网站名称不要出现“阁、楼、店”等一些容易误会为企业商业主体网站的名称,否则也会被退回。 | 442 | - 网站名称不要出现“阁、楼、店”等一些容易误会为企业商业主体网站的名称,否则也会被退回。 |
547 | - 网站用途描述要详细,尽量 30 字以上,绝对不要出现“博客”等词,审查非常非常严格,而且极大可能直接被 ban。即使你真要博客,不能暗度陈仓吗? | 443 | - 网站用途描述要详细,尽量 30 字以上 |
444 | - 用途描述绝对不要出现“博客”等词,审查非常非常严格,而且极大可能直接被 ban。即使你真要博客,不能暗度陈仓吗? | ||
445 | - 就算你要开评论区也不要说提及。**朋友,你也不想你的博客隔三差五被警察同志拿着放大镜看吧?** | ||
548 | 446 | ||
549 | 提交备案之后。如有问题客服会打电话通知,并退回修改;阿里云初审需要大概不到 1 天,工信部短信确认需要 1 天,然后发送到备案省(即户籍所在省)的管局,时长最多 20 天,建议提前搞。我用了 6 天。 | 447 | 提交备案之后。如有问题客服会打电话通知,并退回修改;阿里云初审需要大概不到 1 天,工信部短信确认需要 1 天,然后发送到备案省(即户籍所在省)的管局,时长最多 20 天,建议提前搞。我用了 6 天。 |
550 | 448 | ||
@@ -554,16 +452,18 @@ ICP 备案的原则是:用谁的服务器,在谁那里备案。即以我而 | |||
554 | 452 | ||
555 | 没错,我们需要一个代理,根据访问的网址来对应到指定端口。 | 453 | 没错,我们需要一个代理,根据访问的网址来对应到指定端口。 |
556 | 454 | ||
557 | ### 安装 | 455 | ### 安装、运行与常用操作 |
558 | 456 | ||
559 | ```bash | 457 | ```bash |
560 | sudo apt install nginx | 458 | sudo apt install nginx |
561 | ``` | 459 | # 安装完成后如果服务器重启,nginx会自动启动,手动启动命令如下 |
460 | sudo nginx | ||
562 | 461 | ||
563 | ### 运行 | 462 | # 停止服务 |
463 | sudo nginx -s stop | ||
564 | 464 | ||
565 | ```bash | 465 | # 重新加载配置文件(适用于修改了配置文件但不需要重启的场景) |
566 | nginx | 466 | sudo nginx -s reload |
567 | ``` | 467 | ``` |
568 | 468 | ||
569 | ### SSL 证书 | 469 | ### SSL 证书 |
@@ -576,30 +476,21 @@ nginx | |||
576 | sudo apt install certbot | 476 | sudo apt install certbot |
577 | ``` | 477 | ``` |
578 | 478 | ||
579 | 在申请证书之前,需要停止 nginx 的工作,如果正在运行,按照上边说的方法杀死即可: | 479 | 在申请证书之前,需要停止 nginx 的工作,如果正在运行,按照上边说的方法杀死,而后就可以申请证书辣! |
580 | |||
581 | ```bash | ||
582 | ps -ef | grep nginx | ||
583 | |||
584 | # 杀死显示的第一个进程 | ||
585 | kill -9 <进程号> | ||
586 | |||
587 | # 重启nginx | ||
588 | nginx | ||
589 | ``` | ||
590 | |||
591 | 而后就可以申请证书辣! | ||
592 | 480 | ||
593 | ```bash | 481 | ```bash |
594 | # 申请证书 | 482 | # 申请证书 |
595 | sudo certbot certonly --standalone --email example@qq.com -d code.player.com | 483 | sudo certbot certonly --standalone --email example@qq.com -d code.player.com |
484 | |||
485 | # 除了使用参数方式外,也可以使用交互的方式 | ||
486 | sudo certbot certonly | ||
596 | ``` | 487 | ``` |
597 | 488 | ||
598 | 申请完成后会展示证书的存储路径,记下来,后边会用到。比如: | 489 | 申请完成后会展示证书的存储路径,记下来,后边会用到。比如: |
599 | 490 | ||
600 | SSL 证书 /etc/letsencrypt/live/code.play.com/fullchain.pem; | 491 | SSL 证书 /etc/letsencrypt/live/code.player.com/fullchain.pem; |
601 | 492 | ||
602 | SSL 证书秘钥 /etc/letsencrypt/live/code.play.com/privkey.pem; | 493 | SSL 证书秘钥 /etc/letsencrypt/live/code.player.com/privkey.pem; |
603 | 494 | ||
604 | ### 修改、添加配置 | 495 | ### 修改、添加配置 |
605 | 496 | ||
@@ -610,6 +501,7 @@ Nginx 默认下载目录在`/etc/nginx`,该目录下有个`.conf`文件,但 | |||
610 | ```conf | 501 | ```conf |
611 | server | 502 | server |
612 | { | 503 | { |
504 | # 这段是一个常用的http重定向到https的方法,用了都说好 | ||
613 | listen 80; | 505 | listen 80; |
614 | server_name code.player.com; | 506 | server_name code.player.com; |
615 | return 301 https://$host$request_uri; | 507 | return 301 https://$host$request_uri; |
@@ -619,28 +511,128 @@ server | |||
619 | server_name code.player.com; | 511 | server_name code.player.com; |
620 | listen 443 ssl; | 512 | listen 443 ssl; |
621 | 513 | ||
514 | # 证书路径 | ||
622 | ssl_certificate /etc/letsencrypt/live/code.player.com/fullchain.pem; | 515 | ssl_certificate /etc/letsencrypt/live/code.player.com/fullchain.pem; |
623 | ssl_certificate_key /etc/letsencrypt/live/code.player.com/privkey.pem; | 516 | ssl_certificate_key /etc/letsencrypt/live/code.player.com/privkey.pem; |
624 | 517 | ||
518 | # 这是对于code-server做出的设置 | ||
625 | location / { | 519 | location / { |
626 | proxy_pass http://127.0.0.1:8080;# 这里的端口号要和code-server指定的端口号一致,我是8080 | 520 | proxy_pass http://127.0.0.1:8080; # 这里的端口号要和code-server指定的端口号一致,我是8080 |
627 | proxy_set_header Host $host; | 521 | proxy_set_header Host $host; |
628 | proxy_set_header Upgrade $http_upgrade; | 522 | proxy_set_header Upgrade $http_upgrade; |
629 | proxy_set_header Connection upgrade; | 523 | proxy_set_header Connection upgrade; |
630 | proxy_set_header Accept-Encoding gzip; | 524 | proxy_set_header Accept-Encoding gzip; |
631 | } | 525 | } |
526 | |||
527 | # 如果文件对应的是webroot服务(也就是一个文件夹下存放着指定网址的网页) | ||
528 | # 需要将上边的配置修改为 | ||
529 | # location / { | ||
530 | # root /var/myweb/; # 这里是文件夹路径 | ||
531 | # index index.html; # 这里是每个文件夹下默认打开的文件 | ||
532 | # } | ||
632 | } | 533 | } |
633 | ``` | 534 | ``` |
634 | 535 | ||
635 | 亲测有效。 | ||
636 | |||
637 | 编写完文件之后,需要重新加载配置文件(不必重启 Nginx): | 536 | 编写完文件之后,需要重新加载配置文件(不必重启 Nginx): |
638 | 537 | ||
639 | ```bash | 538 | ```bash |
640 | nginx -s reload | 539 | sudo nginx -s reload |
540 | ``` | ||
541 | |||
542 | 再次提醒:一定记得把域名换成自己的域名、证书路径换成自己的证书路径、端口换成自己在提供服务的应用(如 code-server)中指定的端口! | ||
543 | |||
544 | # 服务器上的文件浏览 | ||
545 | |||
546 | 我们已经学会了设置 nginx 的 webroot,但也有很多情况我们需要能在各种设备上直接地看到服务器上有哪些文件,既能方便文件传输,也能覆盖对大多数只需要看不需要改的场景。 | ||
547 | |||
548 | python3 为我们提供了一个简单的 http 文件浏览服务,默认安装目录为`/usr/lib/python3.x/http/server.py`,一般情况下我们可以直接运行它: | ||
549 | |||
550 | ```bash | ||
551 | python3 -m http.server | ||
552 | ``` | ||
553 | |||
554 | 但是 python 提供的这份文件存在一些问题: | ||
555 | |||
556 | - 响应头没有规定文件编码,让浏览器自己看着办,容易出现乱码 | ||
557 | - 里边选择性忽略了一些文件、文件夹 | ||
558 | |||
559 | 于是我在给定的基础上做了一些小修改,修改版的文件在[这里](https://www.qin-juan-ge-zhu.top/code/linux/httpmyserver.html)。 | ||
560 | |||
561 | # git 远程存储 | ||
562 | |||
563 | 君不闻《西游记》有云: | ||
564 | |||
565 | > 争名夺利几时休,早起迟眠不自由。 | ||
566 | > | ||
567 | > 骑着驴骡思骏马,官居宰相望王侯。 | ||
568 | |||
569 | 完成了代码环境的配置,我就在想,要是有一个自己的远程 git 托管环境该多好?那就干! | ||
570 | |||
571 | 我的详细配置方法写在[这里](https://www.qin-juan-ge-zhu.top/code/linux/gitserver.html)里了。 | ||
572 | |||
573 | # 游戏 | ||
574 | |||
575 | > All work no play makes Jack a doll boy. | ||
576 | |||
577 | 经过了上边的配置,写代码的控制基本完善了,但是服务器怎么能只拿来干活呢?没有游戏怎么行?我们要快乐! | ||
578 | |||
579 | 目前我装了三个游戏: | ||
580 | |||
581 | - 俄罗斯方块,装的是`tint` | ||
582 | - 扫雷,装的是`minebash` | ||
583 | - 贪吃蛇,找不到力(允悲 | ||
584 | |||
585 | 安装方法网上都有,就不多说了。玩得愉快! | ||
586 | |||
587 | # 开机运行脚本 | ||
588 | |||
589 | 经过了以上的设置,我的服务器已经有了许多服务,特别是每个计算机人电脑里必然需要养的一只宠物——小蓝猫 clash。但是每次重启系统之后,这许多服务都需要自己手动拉起的话未免太过麻烦了,所以我们需要一个在系统加载完成后就能自动以 root 身份执行的脚本。经过查询,我找到了处理办法。 | ||
590 | |||
591 | 在 Linux 系统下,开机启动一般使用的是`/etc/rc.local`文件(但也有很多发行版不再使用这种操作方式)。ubuntu20.04 系统已经默认安装了 rc-local.service 服务,但是不知什么原因系统把这个服务给“隐蔽”了,所以如果不做一番操作是无法使用的。 | ||
592 | |||
593 | ```bash | ||
594 | # 以下所有命令需要root身份执行 | ||
595 | |||
596 | cp /usr/lib/systemd/system/rc-local.service /etc/systemd/system/ | ||
597 | # 修改rc-local.service文件,在文件末尾添加以下内容(注意删去前边的注释符): | ||
598 | # [Install] | ||
599 | # WantedBy=multi-user.target | ||
600 | |||
601 | # 创建rc.local文件,带上shebang行 | ||
602 | echo '#!/bin/bash' > /etc/rc.local | ||
603 | # 修改rc.local文件权限 | ||
604 | chmod +x /etc/rc.local | ||
605 | |||
606 | # 上述步骤完成后,注意不要急于写rc.local脚本,我们需要先启动rc-local.service服务 | ||
607 | systemctl start rc-local.service | ||
608 | systemctl enable rc-local.service | ||
609 | # 上述两条命令运行正常时,系统需要重启 | ||
610 | reboot | ||
611 | |||
612 | # 重启完成后,检查rc-local.service服务是否正常运行 | ||
613 | systemctl status rc-local.service | ||
614 | |||
615 | # 一切正常,就可以编写rc.local脚本的内容了 | ||
616 | # 需要注意的是,该脚本以root身份运行,所以不需要sudo | ||
617 | # 如果部分命令需要以其他用户身份运行,可以使用su命令,如: | ||
618 | # su -l <username> -c <要运行的命令> | ||
619 | # 如果要运行的是脚本(不建议,没必要),注意对应参数 | ||
620 | # 文件的最后,可以用exec &> /var/log/rc-local.log将脚本的输出重定向到日志文件中 | ||
621 | ``` | ||
622 | |||
623 | 除此之外,我们可能还需要为所有用户默认开启魔法。这个功能在开机脚本和`/etc/profile`中都无法实现,应当放在`/etc/environment`中。在其中添加以下内容: | ||
624 | |||
625 | ```plaintext | ||
626 | PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin" | ||
627 | http_proxy=http://127.0.0.1:7890 | ||
628 | https_proxy=http://127.0.0.1:7890 | ||
629 | no_proxy=127.0.0.1,localhost | ||
630 | HTTP_PROXY=http://127.0.0.1:7890 | ||
631 | HTTPS_PROXY=http://127.0.0.1:7890 | ||
632 | NO_PROXY=127.0.0.1,localhost | ||
641 | ``` | 633 | ``` |
642 | 634 | ||
643 | 但在使用过程中,一定记得把域名换成自己的域名、证书路径换成自己的证书路径、端口换成自己在 code-server 中指定的端口! | 635 | 该文件中的所有设置对于所有用户均有效,着实省去了每次开机、切换用户都要手动挂代理的麻烦。 |
644 | 636 | ||
645 | # 碎碎念 | 637 | # 碎碎念 |
646 | 638 | ||
@@ -652,4 +644,4 @@ nginx -s reload | |||
652 | 644 | ||
653 | 这篇文档是对一个月以来搞云服务器的配置的一个小小总结,本来以为没多少东西,结果写了整整一下午到现在,一个 Markdown 文档,手写居然达到了 900 多行、将近 40KB,令我也大吃一惊。 | 645 | 这篇文档是对一个月以来搞云服务器的配置的一个小小总结,本来以为没多少东西,结果写了整整一下午到现在,一个 Markdown 文档,手写居然达到了 900 多行、将近 40KB,令我也大吃一惊。 |
654 | 646 | ||
655 | 也许我之后还会继续鼓捣我的服务器,那时候就继续写下去吧。现在也许该考虑考虑期末考试了(笑。 | 647 | 也许我之后还会继续鼓捣我的服务器,那时候就继续写下去吧。现在该考虑考虑期末考试了(笑。 |
diff --git a/code/linux/gitserver.html b/code/linux/gitserver.html new file mode 100644 index 0000000..359d948 --- /dev/null +++ b/code/linux/gitserver.html | |||
@@ -0,0 +1,364 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang=""> | ||
3 | |||
4 | <head> | ||
5 | <meta charset="utf-8" /> | ||
6 | <meta name="generator" content="pandoc" /> | ||
7 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> | ||
8 | <title>自己的git托管</title> | ||
9 | <link rel="stylesheet" href="https://www.qin-juan-ge-zhu.top/common/CSS/pandoc.css"> | ||
10 | <script type="text/javascript" src="https://www.qin-juan-ge-zhu.top/common/script4code.js"></script> | ||
11 | </head> | ||
12 | |||
13 | <body> | ||
14 | <div class="pandoc"> | ||
15 | <div class="main"> | ||
16 | <p class="title">自己的git托管</p> | ||
17 | <!-- git 远程存储 --> | ||
18 | <blockquote> | ||
19 | <p>争名夺利几时休,早起迟眠不自由。</p> | ||
20 | <p>骑着驴骡思骏马,官居宰相望王侯。</p> | ||
21 | </blockquote> | ||
22 | <p>自打在服务器上完成了代码环境的配置,我就在想,要是有一个自己的远程 git 存储库该多好?</p> | ||
23 | <h1 id="gitlab">gitlab</h1> | ||
24 | <p>我按照网上的教程,我更新了清华镜像源,下载安装 gitlab。孰料一次一次在安装过程卡死,而且情况十分严重,CPU 占用率长期维持在 50%以上,内存更是飙升到 | ||
25 | 90%,不仅安装进行不下去了,甚至一切操作都无法执行,包括<kbd>Ctrl+C</kbd>想要杀死当前进程的请求也会石沉大海。没办法,只得强制重启。</p> | ||
26 | <p>如是反复若干次,最终死心,将 gitlab 彻底从云服务器卸载,“革职为民,永不叙用”。</p> | ||
27 | <p>经过上网查找,原因果然出现在配置上。<strong>gitlab 推荐的最小内存是 4G,但是目前我们只有 | ||
28 | 2G,内存爆满也就理所当然了。</strong>没办法,期限之内不能更改配置,就算能更改,我都穷到薅资本主义羊毛了,还能有钱升级配置?笑死。</p> | ||
29 | <p>就因为这个问题,我们就不干了?这是不行滴,小同志。</p> | ||
30 | <p>不久之后,黄四郎同志发来了一篇阮一峰的博客:<a href="https://www.ruanyifeng.com/blog/2022/10/git-server.html">最简单的 git | ||
31 | 服务器</a>。看起来似乎不错,但是失之简略。幸好,我在 git 官方教程<a href="https://git-scm.com/book/zh/v2">Pro | ||
32 | Git</a>上找到了另一部分,两个拼一拼、试一试,最终成功了。</p> | ||
33 | <h1 id="前置">前置</h1> | ||
34 | <p>首先,我建议为 git 托管创建专门的用户。这样做有以下几个目的:</p> | ||
35 | <ul> | ||
36 | <li>安全 | ||
37 | <ul> | ||
38 | <li>如果使用常用用户,仓库托管在家目录下的某一级目录,容易一个不注意自己把仓库删了</li> | ||
39 | <li>如果使用 root 用户,找一个目录进行管理,则权限过高,也容易被误操作;除此之外,root 用户一般不会设置为 ssh 登录,这就意味着想简单创建一个库,我们需要先 ssh | ||
40 | 登陆,然后切换到 root 用户、进入存放目录/创建,最后退出,整个操作过程较为烦人且无法自动化实现</li> | ||
41 | </ul> | ||
42 | </li> | ||
43 | <li>方便使用。创建专门用户后,我们可以为之配置 ssh 密钥,从而实现免密登陆,而且创建新仓库、clone 仓库都较为简单(因为直接托管在家目录之下,不需要记较长的路径名)</li> | ||
44 | </ul> | ||
45 | <p>当然,创建单独用户的理由不止这么简单,它在我们使用 http 来托管仓库的时候有专门的作用,下文会讨论到。</p> | ||
46 | <p>我为其创建了一个名为<code>git</code>的用户,家目录<code>/home/git</code>,但不授予 sudo 权限。</p> | ||
47 | <h1 id="ssh-服务">ssh 服务</h1> | ||
48 | <p>首先,本方法要求有一个本地 git 存储库,并且已经有 commit。如果是本地新建的仓库,需要先有一个 commit,然后继续操作。这个 commit | ||
49 | 可以用编写<code>.gitignore</code>或者<code>push.sh</code>等不甚重要的文件来凑数。</p> | ||
50 | <h2 id="远程仓库">远程仓库</h2> | ||
51 | <pre><code># 创建远程仓库,这里也叫test吧 | ||
52 | ssh git@127.0.0.1 git init --bare test.git</code></pre> | ||
53 | <p>注意,本处指明的 git 为远程用户名,127.0.0.1 代表云服务器的公网 ip,test.git | ||
54 | 为远程仓库名。使用的时候都需要换成自己的。如果仓库不想直接存储在用户目录下,需要指出其存储路径,如<code>code/fuck/test.git</code></p> | ||
55 | <h2 id="本地与远程连接">本地与远程连接</h2> | ||
56 | <p>本地和远程都有了,下一步就是建立联系了。</p> | ||
57 | <pre><code># 本地添加远程库信息 | ||
58 | git remote add origin git@127.0.0.1:test.git | ||
59 | |||
60 | # 此时尚不能直接推送,因为并未指定上游对应分支,需要指定 | ||
61 | git push --set-upstream origin master | ||
62 | |||
63 | # 之后就可以直接推送了 | ||
64 | bash push.sh</code></pre> | ||
65 | <h2 id="自动化">自动化</h2> | ||
66 | <p>整体操作过程可以说比较简单了。既然如此,<strong>脚本,启动!</strong></p> | ||
67 | <pre><code>#!/bin/bash | ||
68 | |||
69 | read -p "Local repo name: " local_name | ||
70 | read -p "Remote repo name: " remote_name | ||
71 | |||
72 | # 远程仓库创建 | ||
73 | tmp="ssh aliyun-git git init --bare $remote_name.git" | ||
74 | eval "$tmp" | ||
75 | |||
76 | # 本地仓库创建 | ||
77 | mkdir "$local_name" | ||
78 | cd "$local_name" | ||
79 | git init | ||
80 | |||
81 | # 本地仓库初始化 | ||
82 | # 编写.gitignore | ||
83 | cat > .gitignore << EOF | ||
84 | *.sh | ||
85 | *.bat | ||
86 | *.exe | ||
87 | *.[oa] | ||
88 | *.pyc | ||
89 | __pycache__ | ||
90 | *.vscode | ||
91 | *.swp | ||
92 | EOF | ||
93 | |||
94 | # 编写push.sh | ||
95 | cat > push.sh << EOF | ||
96 | git add . | ||
97 | git commit | ||
98 | git push | ||
99 | EOF | ||
100 | chmod +x push.sh | ||
101 | |||
102 | # 提交初始化commit | ||
103 | git add . | ||
104 | git commit -m "Initial commit" | ||
105 | tmp="git remote add origin aliyun-git:$remote_name.git" | ||
106 | eval "$tmp" | ||
107 | git push --set-upstream origin master | ||
108 | |||
109 | echo "Success!"</code></pre> | ||
110 | <p><strong>Attention please:</strong></p> | ||
111 | <ul> | ||
112 | <li>本地仓库名和远程仓库名不要加.git 后缀,程序会自动添加</li> | ||
113 | <li>如果要把这个脚本改写为其他语言的脚本的话,在转换本地当前工作目录(进入本地新创建的仓库)的时候,<strong>一定要使用语言自带的调整当前工作目录的函数,不要调用系统命令</strong>(如写为 | ||
114 | C | ||
115 | 语言程序的时候,应当是调用库函数<code>chdir()</code>而不是选择<code>system("cd <目录名>")</code>),否则编译器/解释器自动在这里作多线程执行,创建一个新的线程,运行一个终端,进入了该目录,然后没有后续,线程挂了;另一个线程在原来的代码上继续执行,但根本没进入目录,也就是执行操作的位置不对,最终出现错误。 | ||
116 | </li> | ||
117 | </ul> | ||
118 | <h1 id="https服务">http(s)服务</h1> | ||
119 | <p>到这里似乎已经万事俱备了,但在服务器迁移的过程中,我发现了问题:使用 ssh 服务,就意味着每个仓库记录的远程库都是其 ip | ||
120 | 地址(或者自己在<code>~/.ssh/config</code>里规定的服务器别名),当服务器迁移后,需要手动进入一个个本地仓库修改远程库地址,非常麻烦。相比之下,如果使用像 github 一样的 | ||
121 | http(s)服务,我们就只需要做好远程库迁移、dns 信息修改和服务器设置即可,本地仓库完全不需要改动。</p> | ||
122 | <p>于是,我发现了一篇<a | ||
123 | href="https://www.aneasystone.com/archives/2018/12/build-your-own-git-server.html">教程</a>,照葫芦画瓢起来。 | ||
124 | </p> | ||
125 | <p>需要注意的是,<strong>上面的 ssh 服务不一定需要专门创建用户,但 http(s)服务这里我推荐新建用户</strong>。</p> | ||
126 | <h2 id="配套软件安装">配套软件安装</h2> | ||
127 | <p>首先,我们需要安装<code>git</code>和<code>nginx</code>,这里不再赘述。除此之外,我们会用到以下软件:</p> | ||
128 | <ul> | ||
129 | <li><code>git-http-backend</code>:git 官方提供的 git 的 http(s) 服务后端。该软件包含在<code>git-core</code>中,一般会在安装 git | ||
130 | 时就默认装了,可以通过<code>which git-http-backend</code>查看是否安装,没有的话需要安装<code>git-core</code>。默认安装位置在<code>/usr/lib/git-core/git-http-backend</code>,需要查看自己的路径,后边会用。 | ||
131 | </li> | ||
132 | <li><code>fcgiwrap</code>:一个用于将 FastCGI 转换为 HTTP 协议的工具。</li> | ||
133 | <li><code>htpasswd</code>:用于创建和更新基于文本的认证文件,用于存储用户名和密码。它是<code>apache2-utils</code>的一部分,可以通过<code>which htpasswd</code>查看是否安装,没有的话需要安装<code>apache2-utils</code>。 | ||
134 | </li> | ||
135 | </ul> | ||
136 | <h2 id="nginx-配置与说明">nginx 配置与说明</h2> | ||
137 | <p>最初的设置是这样的:</p> | ||
138 | <pre><code>server | ||
139 | { | ||
140 | # 这里用于将 http 请求重定向到 https,是一种常用的方式 | ||
141 | listen 80; | ||
142 | server_name git.player.com; | ||
143 | return 301 https://$host$request_uri; | ||
144 | } | ||
145 | server | ||
146 | { | ||
147 | server_name git.player.com; | ||
148 | listen 443 ssl; | ||
149 | |||
150 | ssl_certificate /etc/letsencrypt/live/git.player.com/fullchain.pem; | ||
151 | ssl_certificate_key /etc/letsencrypt/live/git.player.com/privkey.pem; | ||
152 | |||
153 | location / { | ||
154 | include fastcgi_params; | ||
155 | # git-http-backend的路径,每次请求都会转发到这个脚本 | ||
156 | fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend; | ||
157 | # git-http-backend默认只能访问目录下有git-daemon-export-ok的仓库 | ||
158 | # 这里设置为可以访问所有仓库 | ||
159 | fastcgi_param GIT_HTTP_EXPORT_ALL ""; | ||
160 | # git仓库根目录 | ||
161 | fastcgi_param GIT_PROJECT_ROOT /home/git/; | ||
162 | fastcgi_param PATH_INFO $uri; | ||
163 | # 如果有认证,传递给cgi脚本git-http-backend | ||
164 | fastcgi_param REMOTE_USER $remote_user; | ||
165 | fastcgi_pass unix:/var/run/fcgiwrap.socket; | ||
166 | } | ||
167 | }</code></pre> | ||
168 | <p>nginx 重新加载配置之后,我们就可以正常<code>git clone https://git.player.com/test.git</code>了。但当我们 push 时,会出现 403 错误:</p> | ||
169 | <pre><code>$ git push | ||
170 | fatal: unable to access 'https://git.player.com/test.git/': The requested URL returned error: 403</code></pre> | ||
171 | <p>为了解决这个错误,我们可以在 <code>git-http-backend</code> 的官网文档 上找到这样的一段描述:</p> | ||
172 | <blockquote> | ||
173 | <p>By default, only the upload-pack service is enabled, which serves git fetch-pack and git ls-remote | ||
174 | clients, which are invoked from git fetch, git pull, and git clone. If the client is authenticated, | ||
175 | the receive-pack service is enabled, which serves git send-pack clients, which is invoked from git | ||
176 | push.</p> | ||
177 | </blockquote> | ||
178 | <p>第一次读这段话可能会有些不知所云,这是因为我们对这里提到的 <code>upload-pack/fetch-pack/receive-pack/send-pack</code> | ||
179 | 这几个概念还没有什么认识。但是我们大抵可以猜出来,默认情况下,只有认证的用户才可以 push 代码。</p> | ||
180 | <p>我们可以在仓库中执行 <code>git config http.receivepack true</code> 来开启 push 权限,但是这样的话,所有人都可以 push | ||
181 | 代码了,这显然不是我们想要的。我们可以通过 <code>git config http.receivepack false</code> 来关闭 push 权限,这样的话,所有人都不能 push | ||
182 | 代码了,这也不是我们想要的。那么,我们应该怎么做呢?更好的做法是这样的:</p> | ||
183 | <pre><code>$HTTP["querystring"] =~ "service=git-receive-pack" { | ||
184 | include "git-auth.conf" | ||
185 | } | ||
186 | $HTTP["url"] =~ "^/git/.*/git-receive-pack$" { | ||
187 | include "git-auth.conf" | ||
188 | }</code></pre> | ||
189 | <p>看上去挺简单,但是想要理解为什么这样配置,就必须了解下 Git 的内部原理。正如上面 git-http-backend 文档上的那段描述,当 Git 客户端执行 | ||
190 | <code>git fetch/git pull/git clone</code>时,会调用 <code>upload-pack</code> 服务,当执行 <code>git push</code> | ||
191 | 时,会调用 <code>receive-pack</code> 服务。我们可以查看 nginx 的访问日志,目录在<code>/var/log/nginx/access.log</code>: | ||
192 | </p> | ||
193 | <p>执行 git clone:</p> | ||
194 | <pre><code>[27/Nov/2018:22:18:00] "GET /test.git/info/refs?service=git-upload-pack HTTP/1.1" 200 363 "-" "git/1.9.1" | ||
195 | [27/Nov/2018:22:18:00] "POST /test.git/git-upload-pack HTTP/1.1" 200 306 "-" "git/1.9.1"</code></pre> | ||
196 | <p>执行 git pull:</p> | ||
197 | <pre><code>[27/Nov/2018:22:20:25] "GET /test.git/info/refs?service=git-upload-pack HTTP/1.1" 200 363 "-" "git/1.9.1" | ||
198 | [27/Nov/2018:22:20:25] "POST /test.git/git-upload-pack HTTP/1.1" 200 551 "-" "git/1.9.1"</code></pre> | ||
199 | <p>执行 git push:</p> | ||
200 | <pre><code>[27/Nov/2018:22:19:33] "GET /test.git/info/refs?service=git-receive-pack HTTP/1.1" 401 204 "-" "git/1.9.1" | ||
201 | admin [27/Nov/2018:22:19:33] "GET /test.git/info/refs?service=git-receive-pack HTTP/1.1" 200 193 "-" "git/1.9.1" | ||
202 | admin [27/Nov/2018:22:19:33] "POST /test.git/git-receive-pack HTTP/1.1" 200 63 "-" "git/1.9.1"</code></pre> | ||
203 | <p>可以看到执行 clone 和 pull 请求的接口是一样的,先请求 <code>/info/refs?service=git-upload-pack</code>,然后再请求 | ||
204 | <code>/git-upload-pack</code>;而 push 是先请求 <code>/info/refs?service=git-receive-pack</code>,然后再请求 | ||
205 | <code>/git-receive-pack</code>,所以在上面的的配置中我们看到了两条记录,如果要对 push 做访问控制,那么对这两个请求都要限制。关于 Git 传输的原理可以参考 《Pro | ||
206 | Git》的 <a | ||
207 | href="https://git-scm.com/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE">Git | ||
208 | 内部原理 - 传输协议</a> 这一节。 | ||
209 | </p> | ||
210 | <p>于是,我们对 nginx 的配置文件进行修改:</p> | ||
211 | <pre><code>server | ||
212 | { | ||
213 | listen 80; | ||
214 | server_name git.qin-juan-ge-zhu.top; | ||
215 | return 301 https://$host$request_uri; | ||
216 | } | ||
217 | server | ||
218 | { | ||
219 | server_name git.qin-juan-ge-zhu.top; | ||
220 | listen 443 ssl; | ||
221 | |||
222 | ssl_certificate /etc/letsencrypt/live/git.qin-juan-ge-zhu.top/fullchain.pem; | ||
223 | ssl_certificate_key /etc/letsencrypt/live/git.qin-juan-ge-zhu.top/privkey.pem; | ||
224 | |||
225 | location @auth { | ||
226 | auth_basic "Git Server"; | ||
227 | # 生成的认证文件,下文专门说明 | ||
228 | auth_basic_user_file /etc/nginx/conf.d/git.htpasswd; | ||
229 | |||
230 | include fastcgi_params; | ||
231 | # git-http-backend的路径,每次请求都会转发到这个脚本 | ||
232 | fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend; | ||
233 | # git-http-backend默认只能访问目录下有git-daemon-export-ok的仓库 | ||
234 | # 这里设置为可以访问所有仓库 | ||
235 | fastcgi_param GIT_HTTP_EXPORT_ALL ""; | ||
236 | # git仓库根目录 | ||
237 | fastcgi_param GIT_PROJECT_ROOT /home/git/; | ||
238 | fastcgi_param PATH_INFO $uri; | ||
239 | # 如果有认证,传递给cgi脚本git-http-backend | ||
240 | fastcgi_param REMOTE_USER $remote_user; | ||
241 | fastcgi_pass unix:/var/run/fcgiwrap.socket; | ||
242 | } | ||
243 | |||
244 | location / { | ||
245 | error_page 418 = @auth; | ||
246 | if ( $query_string = "service=git-receive-pack" ) { | ||
247 | return 418; | ||
248 | } | ||
249 | if ( $uri ~ "git-receive-pack$" ) { | ||
250 | return 418; | ||
251 | } | ||
252 | include fastcgi_params; | ||
253 | |||
254 | fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend; | ||
255 | fastcgi_param GIT_HTTP_EXPORT_ALL ""; | ||
256 | fastcgi_param GIT_PROJECT_ROOT /home/git/; | ||
257 | fastcgi_param PATH_INFO $uri; | ||
258 | fastcgi_param REMOTE_USER $remote_user; | ||
259 | fastcgi_pass unix:/var/run/fcgiwrap.socket; | ||
260 | } | ||
261 | }</code></pre> | ||
262 | <p>这里我们可以看到,我们对<code>/git/.*/git-receive-pack</code>和<code>/info/refs?service=git-receive-pack</code>进行了限制,如果没有认证,就会返回 | ||
263 | 418 错误,然后 nginx 会将其转发到<code>@auth</code>这个 location,这个 location | ||
264 | 会对请求进行认证,如果认证成功,就会将请求转发到<code>fastcgi_pass</code>指定的脚本,也就是<code>git-http-backend</code>,这样就可以正常 push 了。 | ||
265 | </p> | ||
266 | <blockquote> | ||
267 | <p>为什么不直接在<code>/git/.*/git-receive-pack</code>和<code>/info/refs?service=git-receive-pack</code>这两个 | ||
268 | location 中进行认证呢?如果这样做的话,会导致 clone 和 pull 也需要认证,那多不合适了~</p> | ||
269 | <p>418 是什么,http 协议没见过这个啊?这是 http 协议中的一个状态码,叫做 <strong>I’m a | ||
270 | teapot(我是一个茶壶)</strong>,这个状态码是作为一个愚人节玩笑而创建的,但是它确实存在,可以参考 <a | ||
271 | href="https://tools.ietf.org/html/rfc2324">RFC 2324</a>。我们这里用它来做认证标识,以免和别的状态码冲突。当然你也可以自己规定状态码。 | ||
272 | </p> | ||
273 | </blockquote> | ||
274 | <h2 id="认证文件">认证文件</h2> | ||
275 | <p>nginx 的配置中我们用到了认证文件,它的生成是这样的:</p> | ||
276 | <pre><code># 创建认证文件并添加第一个用户 | ||
277 | htpasswd -cd <文件名> <用户名> <密码> | ||
278 | # 在已有的文件中继续添加用户 | ||
279 | htpasswd -d <文件名> <用户名> <密码></code></pre> | ||
280 | <p>到了这里,我们重启 nginx 然后进行测试,也许就可以正常使用了……吗?</p> | ||
281 | <h2 id="问题">问题</h2> | ||
282 | <p>我在测试的时候发现了一个问题:</p> | ||
283 | <pre><code>$ git clone https://git.player.com/test.git | ||
284 | Cloning into 'test'... | ||
285 | fatal: repository 'https://git.player.com/test.git/' not found</code></pre> | ||
286 | <p>看起来很匪夷所思:我们明明把仓库放进了指定目录啊,nginx 也已经配置好了,为什么就是找不到呢?我在网上找了很久也没找到答案。最后自己发现了问题所在:<strong>仓库文件夹权限不对</strong>。 | ||
287 | </p> | ||
288 | <h3 id="linux-权限描述">Linux 权限描述</h3> | ||
289 | <p>当我们使用<code>ls -l</code>命令查看文件夹时,会看到类似这样的输出:</p> | ||
290 | <pre><code>drwxr-xr-x 2 git git 4096 Nov 27 22:19 test.git</code></pre> | ||
291 | <p>其中前 10 个字符就是用来描述该目录权限的。</p> | ||
292 | <ul> | ||
293 | <li>第一位字符代表文件类型 | ||
294 | <ul> | ||
295 | <li><code>d</code>表示目录</li> | ||
296 | <li><code>-</code>表示文件</li> | ||
297 | <li><code>l</code>表示链接文件</li> | ||
298 | <li><code>b</code>表示块设备文件</li> | ||
299 | <li><code>c</code>表示字符设备文件</li> | ||
300 | <li><code>p</code>表示管道文件</li> | ||
301 | <li><code>s</code>表示套接字文件。</li> | ||
302 | </ul> | ||
303 | </li> | ||
304 | <li>接下来 9 个字符每 3 个一组,分别表示文件所有者、文件所有者所在组、其他用户对该文件的权限。 | ||
305 | <ul> | ||
306 | <li><code>r</code>表示可读</li> | ||
307 | <li><code>w</code>表示可写</li> | ||
308 | <li><code>x</code>表示可执行</li> | ||
309 | <li><code>-</code>表示无对应权限</li> | ||
310 | </ul> | ||
311 | </li> | ||
312 | </ul> | ||
313 | <p>其中,读权限和写权限时不言自明的,可是<strong>当我们在讨论文件夹的执行权限的时候,我们究竟在说什么?</strong>其实,这里的执行权限指的是<strong>进入该文件夹的权限</strong>。如果一个文件夹没有执行权限,那么我们就无法进入该文件夹,也就无法访问该文件夹下的文件,即使有对应权限。 | ||
314 | </p> | ||
315 | <p>回到这个问题,我们可以看到,我们仓库存放的文件夹的权限很有可能是没有对应读写或进入权限。所以修改办法也很简单,改权限。</p> | ||
316 | <h3 id="解决方案">解决方案</h3> | ||
317 | <p>修改权限的方法有以下几种:</p> | ||
318 | <ul> | ||
319 | <li>直接把对应库及其下的所有文件/文件夹对所有其他用户赋予读写执行权限(权限使用<code>chmod -R 777 test.git</code>)。缺点很明显: | ||
320 | <ul> | ||
321 | <li>不安全,任何人都可以访问该文件夹下的文件,尤其是 root 和 nginx 用户,前者权限太高,一旦出错足以破坏一切,后者容易导致危险(如强制停止或内存泄漏时)</li> | ||
322 | <li>不方便。每次创建库都需要手动修改仓库及文件的权限,十分不便</li> | ||
323 | </ul> | ||
324 | </li> | ||
325 | <li>不为 git 仓库设立单独用户,直接由原有用户或 root 用户接管一切。缺点: | ||
326 | <ul> | ||
327 | <li>如果使用原有用户,仓库会和其他文件混在一起,不方便管理,且容易误操作</li> | ||
328 | <li>如果使用 root 用户,权限太高,而且一般 root 不会设置为 ssh 登陆,这就意味着想简单创建一个库操作比较复杂</li> | ||
329 | </ul> | ||
330 | </li> | ||
331 | <li>设立单独用户,将 nginx 的工作用户(一般为 www-data 或 | ||
332 | root,在<code>/etc/nginx/nginx.conf</code>文件第一行规定)添加到该用户所在组。这种方式避免了文件混杂不方便管理的问题,也一定程度上避免了权限过高问题(注意,权限问题依然存在),可以说是一个比较好的解决办法。 | ||
333 | </li> | ||
334 | </ul> | ||
335 | <p><strong>这也就是上文我推荐为 git 仓库托管设立单独用户的原因。</strong>因而,最后我选择了第三种方案。具体操作如下:</p> | ||
336 | <pre><code>usermod -aG git root | ||
337 | usermod -aG git www-data</code></pre> | ||
338 | <p>此时再进行测试,应该就可以正常使用了。</p> | ||
339 | <h2 id="其他存在的问题">其他存在的问题</h2> | ||
340 | <p>除了上述问题已经解决之外,还有一些问题依然存在:</p> | ||
341 | <ul> | ||
342 | <li>不管是 nginx 还是 git,在使用 http 上传的时候都会有一定的缓冲区限制,如果上传文件过大或累计多个 commit 才上传,很可能被拒收导致上传失败。这个问题在 github | ||
343 | 上也存在,但是 github 的缓冲区限制比较大,一般不会出现这个问题。但是我们的服务器配置比较低,所以这个问题就比较严重了。解决办法是在 nginx | ||
344 | 的配置文件中添加<code>client_max_body_size 100m;</code>,这样就可以将缓冲区限制扩大到 100M,一般来说足够了。</li> | ||
345 | <li>即使解决了缓冲区大小,偶尔也会被拒收,原因尚未查清</li> | ||
346 | <li>尚未能通过访问特定链接来实现 git 仓库的创建。据说是用 nginx 调用脚本,但暂时没弄出来</li> | ||
347 | <li>没有一个比较好用且功能较为完备的图形化界面(就像 github 那样)。 | ||
348 | <ul> | ||
349 | <li>GitList 的界面看起来不错,而且能展示源码、clone 链接之类的,整体非常像 github 的界面,可惜使用的是我不会的 php 语言,而且没有找到详细一些的安装使用教程 | ||
350 | </li> | ||
351 | <li>cgit 是一个用纯 C 语言开发的一个 git 裸库展示,虽然界面看起来比较古早,但功能也很不错,能展示源码、自由切换分支、方便地查看提交历史(diss 一下 | ||
352 | github,github 查看提交历史看起来真的很不方便很不直观)。美中不足的是<strong>无法在界面上提供 clone | ||
353 | 和源码下载功能</strong>。不过毕竟是个开源软件,而且是我比较熟悉的 C,等有时间有能力了看看自己能不能实现这个功能吧。</li> | ||
354 | </ul> | ||
355 | </li> | ||
356 | </ul> | ||
357 | <p>这篇博客前前后后有二十多天了,该结束了。闲言少叙,看电视去也~</p> | ||
358 | <p class="time">2024.1.3</p> | ||
359 | <script src="https://www.qin-juan-ge-zhu.top/common/js/comment.js"></script> | ||
360 | </div> | ||
361 | </div> | ||
362 | </body> | ||
363 | |||
364 | </html> \ No newline at end of file | ||
diff --git a/code/linux/gitserver.md b/code/linux/gitserver.md new file mode 100644 index 0000000..d0ed6d9 --- /dev/null +++ b/code/linux/gitserver.md | |||
@@ -0,0 +1,368 @@ | |||
1 | <!-- git 远程存储 --> | ||
2 | |||
3 | > 争名夺利几时休,早起迟眠不自由。 | ||
4 | > | ||
5 | > 骑着驴骡思骏马,官居宰相望王侯。 | ||
6 | |||
7 | 自打在服务器上完成了代码环境的配置,我就在想,要是有一个自己的远程 git 存储库该多好? | ||
8 | |||
9 | # gitlab | ||
10 | |||
11 | 我按照网上的教程,我更新了清华镜像源,下载安装 gitlab。孰料一次一次在安装过程卡死,而且情况十分严重,CPU | ||
12 | 占用率长期维持在 50%以上,内存更是飙升到 90%,不仅安装进行不下去了,甚至一切操作都无法执行,包括<kbd>Ctrl+C</kbd>想要杀死当前进程的请求也会石沉大海。没办法,只得强制重启。 | ||
13 | |||
14 | 如是反复若干次,最终死心,将 gitlab 彻底从云服务器卸载,"革职为民,永不叙用"。 | ||
15 | |||
16 | 经过上网查找,原因果然出现在配置上。**gitlab 推荐的最小内存是 4G,但是目前我们只有 2G,内存爆满也就理所当然了。**没办法,期限之内不能更改配置,就算能更改,我都穷到薅资本主义羊毛了,还能有钱升级配置?笑死。 | ||
17 | |||
18 | 就因为这个问题,我们就不干了?这是不行滴,小同志。 | ||
19 | |||
20 | 不久之后,黄四郎同志发来了一篇阮一峰的博客:[最简单的 git 服务器](https://www.ruanyifeng.com/blog/2022/10/git-server.html)。看起来似乎不错,但是失之简略。幸好,我在 git 官方教程[Pro Git](https://git-scm.com/book/zh/v2)上找到了另一部分,两个拼一拼、试一试,最终成功了。 | ||
21 | |||
22 | # 前置 | ||
23 | |||
24 | 首先,我建议为 git 托管创建专门的用户。这样做有以下几个目的: | ||
25 | |||
26 | - 安全 | ||
27 | - 如果使用常用用户,仓库托管在家目录下的某一级目录,容易一个不注意自己把仓库删了 | ||
28 | - 如果使用 root 用户,找一个目录进行管理,则权限过高,也容易被误操作;除此之外,root 用户一般不会设置为 ssh 登录,这就意味着想简单创建一个库,我们需要先 ssh 登陆,然后切换到 root 用户、进入存放目录/创建,最后退出,整个操作过程较为烦人且无法自动化实现 | ||
29 | - 方便使用。创建专门用户后,我们可以为之配置 ssh 密钥,从而实现免密登陆,而且创建新仓库、clone 仓库都较为简单(因为直接托管在家目录之下,不需要记较长的路径名) | ||
30 | |||
31 | 当然,创建单独用户的理由不止这么简单,它在我们使用 http 来托管仓库的时候有专门的作用,下文会讨论到。 | ||
32 | |||
33 | 我为其创建了一个名为`git`的用户,家目录`/home/git`,但不授予 sudo 权限。 | ||
34 | |||
35 | # ssh 服务 | ||
36 | |||
37 | 首先,本方法要求有一个本地 git 存储库,并且已经有 commit。如果是本地新建的仓库,需要先有一个 commit,然后继续操作。这个 commit 可以用编写`.gitignore`或者`push.sh`等不甚重要的文件来凑数。 | ||
38 | |||
39 | ## 远程仓库 | ||
40 | |||
41 | ```bash | ||
42 | # 创建远程仓库,这里也叫test吧 | ||
43 | ssh git@127.0.0.1 git init --bare test.git | ||
44 | ``` | ||
45 | |||
46 | 注意,本处指明的 git 为远程用户名,127.0.0.1 代表云服务器的公网 ip,test.git 为远程仓库名。使用的时候都需要换成自己的。如果仓库不想直接存储在用户目录下,需要指出其存储路径,如`code/fuck/test.git` | ||
47 | |||
48 | ## 本地与远程连接 | ||
49 | |||
50 | 本地和远程都有了,下一步就是建立联系了。 | ||
51 | |||
52 | ```bash | ||
53 | # 本地添加远程库信息 | ||
54 | git remote add origin git@127.0.0.1:test.git | ||
55 | |||
56 | # 此时尚不能直接推送,因为并未指定上游对应分支,需要指定 | ||
57 | git push --set-upstream origin master | ||
58 | |||
59 | # 之后就可以直接推送了 | ||
60 | bash push.sh | ||
61 | ``` | ||
62 | |||
63 | ## 自动化 | ||
64 | |||
65 | 整体操作过程可以说比较简单了。既然如此,**脚本,启动!** | ||
66 | |||
67 | ```bash | ||
68 | #!/bin/bash | ||
69 | |||
70 | read -p "Local repo name: " local_name | ||
71 | read -p "Remote repo name: " remote_name | ||
72 | |||
73 | # 远程仓库创建 | ||
74 | tmp="ssh aliyun-git git init --bare $remote_name.git" | ||
75 | eval "$tmp" | ||
76 | |||
77 | # 本地仓库创建 | ||
78 | mkdir "$local_name" | ||
79 | cd "$local_name" | ||
80 | git init | ||
81 | |||
82 | # 本地仓库初始化 | ||
83 | # 编写.gitignore | ||
84 | cat > .gitignore << EOF | ||
85 | *.sh | ||
86 | *.bat | ||
87 | *.exe | ||
88 | *.[oa] | ||
89 | *.pyc | ||
90 | __pycache__ | ||
91 | *.vscode | ||
92 | *.swp | ||
93 | EOF | ||
94 | |||
95 | # 编写push.sh | ||
96 | cat > push.sh << EOF | ||
97 | git add . | ||
98 | git commit | ||
99 | git push | ||
100 | EOF | ||
101 | chmod +x push.sh | ||
102 | |||
103 | # 提交初始化commit | ||
104 | git add . | ||
105 | git commit -m "Initial commit" | ||
106 | tmp="git remote add origin aliyun-git:$remote_name.git" | ||
107 | eval "$tmp" | ||
108 | git push --set-upstream origin master | ||
109 | |||
110 | echo "Success!" | ||
111 | ``` | ||
112 | |||
113 | **Attention please:** | ||
114 | |||
115 | - 本地仓库名和远程仓库名不要加.git 后缀,程序会自动添加 | ||
116 | - 如果要把这个脚本改写为其他语言的脚本的话,在转换本地当前工作目录(进入本地新创建的仓库)的时候,**一定要使用语言自带的调整当前工作目录的函数,不要调用系统命令**(如写为 C 语言程序的时候,应当是调用库函数`chdir()`而不是选择`system("cd <目录名>")`),否则编译器/解释器自动在这里作多线程执行,创建一个新的线程,运行一个终端,进入了该目录,然后没有后续,线程挂了;另一个线程在原来的代码上继续执行,但根本没进入目录,也就是执行操作的位置不对,最终出现错误。 | ||
117 | |||
118 | # http(s)服务 | ||
119 | |||
120 | 到这里似乎已经万事俱备了,但在服务器迁移的过程中,我发现了问题:使用 ssh 服务,就意味着每个仓库记录的远程库都是其 ip 地址(或者自己在`~/.ssh/config`里规定的服务器别名),当服务器迁移后,需要手动进入一个个本地仓库修改远程库地址,非常麻烦。相比之下,如果使用像 github 一样的 http(s)服务,我们就只需要做好远程库迁移、dns 信息修改和服务器设置即可,本地仓库完全不需要改动。 | ||
121 | |||
122 | 于是,我发现了一篇[教程](https://www.aneasystone.com/archives/2018/12/build-your-own-git-server.html),照葫芦画瓢起来。 | ||
123 | |||
124 | 需要注意的是,**上面的 ssh 服务不一定需要专门创建用户,但 http(s)服务这里我推荐新建用户**。 | ||
125 | |||
126 | ## 配套软件安装 | ||
127 | |||
128 | 首先,我们需要安装`git`和`nginx`,这里不再赘述。除此之外,我们会用到以下软件: | ||
129 | |||
130 | - `git-http-backend`:git 官方提供的 git 的 http(s) 服务后端。该软件包含在`git-core`中,一般会在安装 git 时就默认装了,可以通过`which git-http-backend`查看是否安装,没有的话需要安装`git-core`。默认安装位置在`/usr/lib/git-core/git-http-backend`,需要查看自己的路径,后边会用。 | ||
131 | - `fcgiwrap`:一个用于将 FastCGI 转换为 HTTP 协议的工具。 | ||
132 | - `htpasswd`:用于创建和更新基于文本的认证文件,用于存储用户名和密码。它是`apache2-utils`的一部分,可以通过`which htpasswd`查看是否安装,没有的话需要安装`apache2-utils`。 | ||
133 | |||
134 | ## nginx 配置与说明 | ||
135 | |||
136 | 最初的设置是这样的: | ||
137 | |||
138 | ```conf | ||
139 | server | ||
140 | { | ||
141 | # 这里用于将 http 请求重定向到 https,是一种常用的方式 | ||
142 | listen 80; | ||
143 | server_name git.player.com; | ||
144 | return 301 https://$host$request_uri; | ||
145 | } | ||
146 | server | ||
147 | { | ||
148 | server_name git.player.com; | ||
149 | listen 443 ssl; | ||
150 | |||
151 | ssl_certificate /etc/letsencrypt/live/git.player.com/fullchain.pem; | ||
152 | ssl_certificate_key /etc/letsencrypt/live/git.player.com/privkey.pem; | ||
153 | |||
154 | location / { | ||
155 | include fastcgi_params; | ||
156 | # git-http-backend的路径,每次请求都会转发到这个脚本 | ||
157 | fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend; | ||
158 | # git-http-backend默认只能访问目录下有git-daemon-export-ok的仓库 | ||
159 | # 这里设置为可以访问所有仓库 | ||
160 | fastcgi_param GIT_HTTP_EXPORT_ALL ""; | ||
161 | # git仓库根目录 | ||
162 | fastcgi_param GIT_PROJECT_ROOT /home/git/; | ||
163 | fastcgi_param PATH_INFO $uri; | ||
164 | # 如果有认证,传递给cgi脚本git-http-backend | ||
165 | fastcgi_param REMOTE_USER $remote_user; | ||
166 | fastcgi_pass unix:/var/run/fcgiwrap.socket; | ||
167 | } | ||
168 | } | ||
169 | ``` | ||
170 | |||
171 | nginx 重新加载配置之后,我们就可以正常`git clone https://git.player.com/test.git`了。但当我们 push 时,会出现 403 错误: | ||
172 | |||
173 | ```bash | ||
174 | $ git push | ||
175 | fatal: unable to access 'https://git.player.com/test.git/': The requested URL returned error: 403 | ||
176 | ``` | ||
177 | |||
178 | 为了解决这个错误,我们可以在 `git-http-backend` 的官网文档 上找到这样的一段描述: | ||
179 | |||
180 | > By default, only the upload-pack service is enabled, which serves git fetch-pack and git ls-remote clients, which are invoked from git fetch, git pull, and git clone. If the client is authenticated, the receive-pack service is enabled, which serves git send-pack clients, which is invoked from git push. | ||
181 | |||
182 | 第一次读这段话可能会有些不知所云,这是因为我们对这里提到的 `upload-pack/fetch-pack/receive-pack/send-pack` 这几个概念还没有什么认识。但是我们大抵可以猜出来,默认情况下,只有认证的用户才可以 push 代码。 | ||
183 | |||
184 | 我们可以在仓库中执行 `git config http.receivepack true` 来开启 push 权限,但是这样的话,所有人都可以 push 代码了,这显然不是我们想要的。我们可以通过 `git config http.receivepack false` 来关闭 push 权限,这样的话,所有人都不能 push 代码了,这也不是我们想要的。那么,我们应该怎么做呢?更好的做法是这样的: | ||
185 | |||
186 | ```conf | ||
187 | $HTTP["querystring"] =~ "service=git-receive-pack" { | ||
188 | include "git-auth.conf" | ||
189 | } | ||
190 | $HTTP["url"] =~ "^/git/.*/git-receive-pack$" { | ||
191 | include "git-auth.conf" | ||
192 | } | ||
193 | ``` | ||
194 | |||
195 | 看上去挺简单,但是想要理解为什么这样配置,就必须了解下 Git 的内部原理。正如上面 git-http-backend 文档上的那段描述,当 Git 客户端执行 `git fetch/git pull/git clone`时,会调用 `upload-pack` 服务,当执行 `git push` 时,会调用 `receive-pack` 服务。我们可以查看 nginx 的访问日志,目录在`/var/log/nginx/access.log`: | ||
196 | |||
197 | 执行 git clone: | ||
198 | |||
199 | ```log | ||
200 | [27/Nov/2018:22:18:00] "GET /test.git/info/refs?service=git-upload-pack HTTP/1.1" 200 363 "-" "git/1.9.1" | ||
201 | [27/Nov/2018:22:18:00] "POST /test.git/git-upload-pack HTTP/1.1" 200 306 "-" "git/1.9.1" | ||
202 | ``` | ||
203 | |||
204 | 执行 git pull: | ||
205 | |||
206 | ```log | ||
207 | [27/Nov/2018:22:20:25] "GET /test.git/info/refs?service=git-upload-pack HTTP/1.1" 200 363 "-" "git/1.9.1" | ||
208 | [27/Nov/2018:22:20:25] "POST /test.git/git-upload-pack HTTP/1.1" 200 551 "-" "git/1.9.1" | ||
209 | ``` | ||
210 | |||
211 | 执行 git push: | ||
212 | |||
213 | ```log | ||
214 | [27/Nov/2018:22:19:33] "GET /test.git/info/refs?service=git-receive-pack HTTP/1.1" 401 204 "-" "git/1.9.1" | ||
215 | admin [27/Nov/2018:22:19:33] "GET /test.git/info/refs?service=git-receive-pack HTTP/1.1" 200 193 "-" "git/1.9.1" | ||
216 | admin [27/Nov/2018:22:19:33] "POST /test.git/git-receive-pack HTTP/1.1" 200 63 "-" "git/1.9.1" | ||
217 | ``` | ||
218 | |||
219 | 可以看到执行 clone 和 pull 请求的接口是一样的,先请求 `/info/refs?service=git-upload-pack`,然后再请求 `/git-upload-pack`;而 push 是先请求 `/info/refs?service=git-receive-pack`,然后再请求 `/git-receive-pack`,所以在上面的的配置中我们看到了两条记录,如果要对 push 做访问控制,那么对这两个请求都要限制。关于 Git 传输的原理可以参考 《Pro Git》的 [Git 内部原理 - 传输协议](https://git-scm.com/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE) 这一节。 | ||
220 | |||
221 | 于是,我们对 nginx 的配置文件进行修改: | ||
222 | |||
223 | ```conf | ||
224 | server | ||
225 | { | ||
226 | listen 80; | ||
227 | server_name git.qin-juan-ge-zhu.top; | ||
228 | return 301 https://$host$request_uri; | ||
229 | } | ||
230 | server | ||
231 | { | ||
232 | server_name git.qin-juan-ge-zhu.top; | ||
233 | listen 443 ssl; | ||
234 | |||
235 | ssl_certificate /etc/letsencrypt/live/git.qin-juan-ge-zhu.top/fullchain.pem; | ||
236 | ssl_certificate_key /etc/letsencrypt/live/git.qin-juan-ge-zhu.top/privkey.pem; | ||
237 | |||
238 | location @auth { | ||
239 | auth_basic "Git Server"; | ||
240 | # 生成的认证文件,下文专门说明 | ||
241 | auth_basic_user_file /etc/nginx/conf.d/git.htpasswd; | ||
242 | |||
243 | include fastcgi_params; | ||
244 | # git-http-backend的路径,每次请求都会转发到这个脚本 | ||
245 | fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend; | ||
246 | # git-http-backend默认只能访问目录下有git-daemon-export-ok的仓库 | ||
247 | # 这里设置为可以访问所有仓库 | ||
248 | fastcgi_param GIT_HTTP_EXPORT_ALL ""; | ||
249 | # git仓库根目录 | ||
250 | fastcgi_param GIT_PROJECT_ROOT /home/git/; | ||
251 | fastcgi_param PATH_INFO $uri; | ||
252 | # 如果有认证,传递给cgi脚本git-http-backend | ||
253 | fastcgi_param REMOTE_USER $remote_user; | ||
254 | fastcgi_pass unix:/var/run/fcgiwrap.socket; | ||
255 | } | ||
256 | |||
257 | location / { | ||
258 | error_page 418 = @auth; | ||
259 | if ( $query_string = "service=git-receive-pack" ) { | ||
260 | return 418; | ||
261 | } | ||
262 | if ( $uri ~ "git-receive-pack$" ) { | ||
263 | return 418; | ||
264 | } | ||
265 | include fastcgi_params; | ||
266 | |||
267 | fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend; | ||
268 | fastcgi_param GIT_HTTP_EXPORT_ALL ""; | ||
269 | fastcgi_param GIT_PROJECT_ROOT /home/git/; | ||
270 | fastcgi_param PATH_INFO $uri; | ||
271 | fastcgi_param REMOTE_USER $remote_user; | ||
272 | fastcgi_pass unix:/var/run/fcgiwrap.socket; | ||
273 | } | ||
274 | } | ||
275 | ``` | ||
276 | |||
277 | 这里我们可以看到,我们对`/git/.*/git-receive-pack`和`/info/refs?service=git-receive-pack`进行了限制,如果没有认证,就会返回 418 错误,然后 nginx 会将其转发到`@auth`这个 location,这个 location 会对请求进行认证,如果认证成功,就会将请求转发到`fastcgi_pass`指定的脚本,也就是`git-http-backend`,这样就可以正常 push 了。 | ||
278 | |||
279 | > 为什么不直接在`/git/.*/git-receive-pack`和`/info/refs?service=git-receive-pack`这两个 location 中进行认证呢?如果这样做的话,会导致 clone 和 pull 也需要认证,那多不合适了~ | ||
280 | > | ||
281 | > 418 是什么,http 协议没见过这个啊?这是 http 协议中的一个状态码,叫做 **I'm a teapot(我是一个茶壶)**,这个状态码是作为一个愚人节玩笑而创建的,但是它确实存在,可以参考 [RFC 2324](https://tools.ietf.org/html/rfc2324)。我们这里用它来做认证标识,以免和别的状态码冲突。当然你也可以自己规定状态码。 | ||
282 | |||
283 | ## 认证文件 | ||
284 | |||
285 | nginx 的配置中我们用到了认证文件,它的生成是这样的: | ||
286 | |||
287 | ```bash | ||
288 | # 创建认证文件并添加第一个用户 | ||
289 | htpasswd -cd <文件名> <用户名> <密码> | ||
290 | # 在已有的文件中继续添加用户 | ||
291 | htpasswd -d <文件名> <用户名> <密码> | ||
292 | ``` | ||
293 | |||
294 | 到了这里,我们重启 nginx 然后进行测试,也许就可以正常使用了……吗? | ||
295 | |||
296 | ## 问题 | ||
297 | |||
298 | 我在测试的时候发现了一个问题: | ||
299 | |||
300 | ```bash | ||
301 | $ git clone https://git.player.com/test.git | ||
302 | Cloning into 'test'... | ||
303 | fatal: repository 'https://git.player.com/test.git/' not found | ||
304 | ``` | ||
305 | |||
306 | 看起来很匪夷所思:我们明明把仓库放进了指定目录啊,nginx 也已经配置好了,为什么就是找不到呢?我在网上找了很久也没找到答案。最后自己发现了问题所在:**仓库文件夹权限不对**。 | ||
307 | |||
308 | ### Linux 权限描述 | ||
309 | |||
310 | 当我们使用`ls -l`命令查看文件夹时,会看到类似这样的输出: | ||
311 | |||
312 | ```bash | ||
313 | drwxr-xr-x 2 git git 4096 Nov 27 22:19 test.git | ||
314 | ``` | ||
315 | |||
316 | 其中前 10 个字符就是用来描述该目录权限的。 | ||
317 | |||
318 | - 第一位字符代表文件类型 | ||
319 | - `d`表示目录 | ||
320 | - `-`表示文件 | ||
321 | - `l`表示链接文件 | ||
322 | - `b`表示块设备文件 | ||
323 | - `c`表示字符设备文件 | ||
324 | - `p`表示管道文件 | ||
325 | - `s`表示套接字文件。 | ||
326 | - 接下来 9 个字符每 3 个一组,分别表示文件所有者、文件所有者所在组、其他用户对该文件的权限。 | ||
327 | - `r`表示可读 | ||
328 | - `w`表示可写 | ||
329 | - `x`表示可执行 | ||
330 | - `-`表示无对应权限 | ||
331 | |||
332 | 其中,读权限和写权限时不言自明的,可是**当我们在讨论文件夹的执行权限的时候,我们究竟在说什么?**其实,这里的执行权限指的是**进入该文件夹的权限**。如果一个文件夹没有执行权限,那么我们就无法进入该文件夹,也就无法访问该文件夹下的文件,即使有对应权限。 | ||
333 | |||
334 | 回到这个问题,我们可以看到,我们仓库存放的文件夹的权限很有可能是没有对应读写或进入权限。所以修改办法也很简单,改权限。 | ||
335 | |||
336 | ### 解决方案 | ||
337 | |||
338 | 修改权限的方法有以下几种: | ||
339 | |||
340 | - 直接把对应库及其下的所有文件/文件夹对所有其他用户赋予读写执行权限(权限使用`chmod -R 777 test.git`)。缺点很明显: | ||
341 | - 不安全,任何人都可以访问该文件夹下的文件,尤其是 root 和 nginx 用户,前者权限太高,一旦出错足以破坏一切,后者容易导致危险(如强制停止或内存泄漏时) | ||
342 | - 不方便。每次创建库都需要手动修改仓库及文件的权限,十分不便 | ||
343 | - 不为 git 仓库设立单独用户,直接由原有用户或 root 用户接管一切。缺点: | ||
344 | - 如果使用原有用户,仓库会和其他文件混在一起,不方便管理,且容易误操作 | ||
345 | - 如果使用 root 用户,权限太高,而且一般 root 不会设置为 ssh 登陆,这就意味着想简单创建一个库操作比较复杂 | ||
346 | - 设立单独用户,将 nginx 的工作用户(一般为 www-data 或 root,在`/etc/nginx/nginx.conf`文件第一行规定)添加到该用户所在组。这种方式避免了文件混杂不方便管理的问题,也一定程度上避免了权限过高问题(注意,权限问题依然存在),可以说是一个比较好的解决办法。 | ||
347 | |||
348 | **这也就是上文我推荐为 git 仓库托管设立单独用户的原因。**因而,最后我选择了第三种方案。具体操作如下: | ||
349 | |||
350 | ```bash | ||
351 | usermod -aG git root | ||
352 | usermod -aG git www-data | ||
353 | ``` | ||
354 | |||
355 | 此时再进行测试,应该就可以正常使用了。 | ||
356 | |||
357 | ## 其他存在的问题 | ||
358 | |||
359 | 除了上述问题已经解决之外,还有一些问题依然存在: | ||
360 | |||
361 | - 不管是 nginx 还是 git,在使用 http 上传的时候都会有一定的缓冲区限制,如果上传文件过大或累计多个 commit 才上传,很可能被拒收导致上传失败。这个问题在 github 上也存在,但是 github 的缓冲区限制比较大,一般不会出现这个问题。但是我们的服务器配置比较低,所以这个问题就比较严重了。解决办法是在 nginx 的配置文件中添加`client_max_body_size 100m;`,这样就可以将缓冲区限制扩大到 100M,一般来说足够了。 | ||
362 | - 即使解决了缓冲区大小,偶尔也会被拒收,原因尚未查清 | ||
363 | - 尚未能通过访问特定链接来实现 git 仓库的创建。据说是用 nginx 调用脚本,但暂时没弄出来 | ||
364 | - 没有一个比较好用且功能较为完备的图形化界面(就像 github 那样)。 | ||
365 | - GitList 的界面看起来不错,而且能展示源码、clone 链接之类的,整体非常像 github 的界面,可惜使用的是我不会的 php 语言,而且没有找到详细一些的安装使用教程 | ||
366 | - cgit 是一个用纯 C 语言开发的一个 git 裸库展示,虽然界面看起来比较古早,但功能也很不错,能展示源码、自由切换分支、方便地查看提交历史(diss 一下 github,github 查看提交历史看起来真的很不方便很不直观)。美中不足的是**无法在界面上提供 clone 和源码下载功能**。不过毕竟是个开源软件,而且是我比较熟悉的 C,等有时间有能力了看看自己能不能实现这个功能吧。 | ||
367 | |||
368 | 这篇博客前前后后有二十多天了,该结束了。闲言少叙,看电视去也~ \ No newline at end of file | ||
diff --git a/code/linux/httpmyserver.html b/code/linux/httpmyserver.html new file mode 100644 index 0000000..9cb878e --- /dev/null +++ b/code/linux/httpmyserver.html | |||
@@ -0,0 +1,277 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang=""> | ||
3 | |||
4 | <head> | ||
5 | <meta charset="utf-8" /> | ||
6 | <meta name="generator" content="pandoc" /> | ||
7 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> | ||
8 | <title>http浏览服务器文件</title> | ||
9 | <link rel="stylesheet" href="https://www.qin-juan-ge-zhu.top/common/CSS/pandoc.css"> | ||
10 | <script type="text/javascript" src="https://www.qin-juan-ge-zhu.top/common/script4code.js"></script> | ||
11 | </head> | ||
12 | |||
13 | <body> | ||
14 | <div class="pandoc"> | ||
15 | <div class="main"> | ||
16 | <p class="title">http浏览服务器文件</p> | ||
17 | <!-- python实现服务器文件浏览 --> | ||
18 | <p>有了服务器,我们自然会有这样的需求:<strong>把一些内容传到服务器上,方便其他人访问或自己在其他设备(如手机)上,通过浏览器直接访问</strong>。我们需要它能完成以下功能:</p> | ||
19 | <ul> | ||
20 | <li>能让我们自己点进(或退出)层层文件夹,展示当前文件夹下的所有文件/文件夹</li> | ||
21 | <li>点击文件,能够看到文件内容</li> | ||
22 | </ul> | ||
23 | <p><img | ||
24 | src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAzoAAAIxCAYAAACFAc3DAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAJpZSURBVHhe7d0LYBXVnfjx382LhJcB0QarBSzsAqstuJWKLVhibQW1XUBsgdWtonYVdVdBFhBpF1GsPNqqaFugtFLCVgX2XzXYWmN9lKBthVYLbKUGVyvZSiVAIIE87v/8Zs5Nbm7mvpJ7k5vJ94NjZubOfc2dx/nNOec3gVP7nxYUAAAAAPCRQP9+pxLoAAAAAPCVQOEp/Qh0AAAAAPhKoF9hfwIdAAAAAL6SZf8CAAAAgG8Q6AAAAADwHZquIaNkZ2dLr169JD+/h+Tl5UlObq7kmiEnJ9suAQAAAMRHoINO16NHD+nXv1B69ewleT3y7FwAAACg7Qh00GlycnLktNNPk1NO6SuBQMDOBQAAANqPQAcdTpun9T+1v/Tv30+ysugmBgAAgNSjlIkOpTU3RQOLZMCAUwlyAAAAkDaUNNFhtKnaoMGDpG/fPnYOAAAAkB40XUOH0AxqHxt0lpNBLZ7Gxkapr6+Xuro6CQaDzqDz/EpruXTQGi4ddF1p876OpOuYflIAAMBPCHSQdlqAHjT4Y1JQUGDneNPg5vjx406A091pwJOfnx93nQEAAMAbgQ7S7swzPyp9YjRX09oaDXBqa2upVYgQuq9QIjVhiaL2BgAAdAf00UFa9e3bN26Qc/ToUTlx4gSFbw8NDQ1y5MgRJwgEAABA4gh0kDYauJz+kdPsVGvaVK2qqsr5i9iOHTsm1dXVdqrtqM0BAADdBYEO0ubUAadGbXKlNTlaU6EFbyRGa71qamrsVNsQ5AAAgO6CQAdpoamkTz21v51qSYMbba5GkJM87cvU1how1jcAAOhOOiQZgRZ6r7xyqjz55OYu00ypq3xmTUV8ySWfl+EjhsvAgQPltNNOk4MHD8qf9/1Zdrz6qrz+u9ed5RbetUDOPfdc+eY3vin/8z9/cual0+mnn+bU6HjRZljJ9DnR7/SVr3xFHn74YTune9OMbKecckrSN1yl2Vp6adII/V0yMVOe1gTqxQUdAADoLtIe6GhB/M55c+Wcc86RP/zhD7LsvvvtI5ltwcL58olPfELefPNNWf7ACjl58qR9JHOcffbZcsec2+XUU70DCrV//3558LsPybXXfa1DA52Pf/xsyeuRZ6eaaZO1Q4cO2anErFixQiZOnCiXX365VFRU2Lndmxame/bsaafiCw9y+vTp4wwFX/hnuW5YgRz+zRpZ/dxhJwD1dNVD8uy/nScfln5GZtxr50V1l5T8epIMkqPy+ncvlVsft7PjuatEfj2pf9Tn6Pft16+fFHxqivzzpwdKzVs/lM0v2wc9jJt6nQw7xU7ISTnw6k9k2x/tpKEF/8OHw76z/Y4t0ma8UyqfifjCLYKZf5jY9Fme+31fGTBggF0qc+l3/uMf/+h87zEz5sr4M+wDxvsvrZCS1+xEuDEzZG74gsf2yk8ffVretZNNzrpcbvrKcOllJ80ryksrSqT1S54ll9/0FRnevGD0924yRmbMHS9nvP+SrIi9YHq1+I7Rvl8UoefG+g52Gdn7U3n06VZrGACQpLQGOhrk/Mf8eTJy5Egne9SqVd9uqmHIdOf943lyxx23O+l9d+/e7QRomVSzM2TIEPnGNxdLjx49nOkdO3bIC2W/cgq0Hz3zo3K2eXz0eaOld+/eTmBRXX1MzjrrzA4JdPR3//jQs+1US9qhXvuaJOq8886TkpISZ/z111+XGTNmOOOd7prH5LWFA+T54ZNkgZ3VkTRo6d/fu2mgF90utL+UBrvRCuRa+D9w4ICdMmxBPhSuHo4TXKjmAKN1cOFp3FQTbIUiEu/naI2eBmbp4H7noTL1umEi4d+v6bsfNrM3i87WDIJdIZiJ59ixk9L/E5+S4b0PNBfUbTBzLKKAfdblN8lXTETSHIjYgCMy2Gn1/FAwExkMtH5+6/doLZFl0i6RQCWWBJ7vBp/HTJzzqBDnAED7pS3Q0cLuwrsWyt///d91uSAnJDLY+db9D2REzY7eSHL5iuWm0HWq7Nu3T9auWSfvvPOOfbRZYWGhzJ//HzJo8CA7Rzok0NEaJq9sa1rY/vDDD+1UfNo062c/+5kMGjRIXn75ZSkuLpbbb79dtm3bZpdIkBOUjJG+djJxb8vWGIHMNY+9JgvHHIy5jLdr5LHXFsqYvrFfPx4t/Ot+lghd9+efP0n69SPDHUQGDx4sx36/pkXQ4BaywwOTKLUoNqhpDjpsUCMRwY9H7YQbsOis8IJ8lOc3ifd4x2h3sBU30MmQWisA8JG0JCPwQ5Cj9DPrZ9fvoLVS+p0SLVim05e//CUnyHn33ffkniVLWwU5WgAeMXKEDDxjoDz//PN2bsfJz3drmSLV1dXZscRcffXVMnToUPnBD35gArb5TrObBQsWOIFeUh67RsYMHy7DvYb7XpMjZpG3t3o8ZoOQZaV7Ze/e1sPCMRo6nS2TPR4rXaZv7MUGOaYo+drb5rmvPWbmtE0yNWPa3IogByFefeQOHNFmfKfI6We50zJmqGiDtff3RRS6X9sn75s/Zwwd406f9Uk5q5fIsXd/3zII0Wnzkr30cWfGWfJJd0H5fcsFzbSzoHnczgo3ZpzTzK3V6/vMWZf/o/f6BgC0WcoDHS2E+iHICQkPdvQ7ZUKwM/6i8c7fzU9u9qxh0qBs8eK7neG6WdfZuR0nOyfbjrWk6zBR2lzptttuc5pSfe9733NSUX/nO9+R008/XW699Va7VPst++oY6fv2VpkUp1rlyGv3eQRC3sPWt+2TWlkmpXvdIOe+MdfINZPMsgfHyMI2BjvJBI7a7AoId0pTROMa2Fd7nhyWv9poYsxQp9gtrcvdB8SJic4YarZljXPOkl5yzMQ1kWHIu/LXw+ZPKICJFhAZ77oLOq8VKfQ5fheqAtKakblzZe4MG2iF0VqpuXNvkstbvIzWlOh8O9x0uQ28woRes2kIew37mNbmqDPG22X0/ZP+LNGEgsC98jJxDgCkTEoDHe2gq9m9NCBQv/j5L5w28Fq7EG/QLGcdTZukeX2WyEG/g34Xpd9twcI21CqkiKZs1r4Z2qlf+6x4ee+995xscV7D3/72N7tU+uTmRL93TqLuvPNOp+P3vffe6yQheOyxx2TTpk2yZ88eueaaa5w+Su22rFQmn/22bI0X5bSitTJ7ZW/0apvWzHvt3TtZBmjAZIKcx+zsBSbYuW/vcFm49zWteEqKNkdLlG7DQMg7R01YMfzy5kL4mBlOYoL3Xwo1WztLTm9K5hDJBjCWGyB5c2uJrIF9wxIVRDhwxIRKHkwg8Y9uNUdYP58kOIHIeDll70+dpCbO8LTIuPDoQ5vi2SZ2oWVeer+XDP+KDVLefVoeNfN+utf9hNp0zVkulc3LukmtFQB0tJQGOvMXzJdhw4bZKZGJkyY21SzEG7RQ29E0a5XXZ/Ea9LuEDB/+98537QynnFLo/NWCa7Qr+n/5y1+c2h6v4eDB9Ac67a3R0QQEX/rSl6S8vFx++ctfyhlnnCFjxrhXTBcvXux0qtcAqH2WSelkTZhwtnwyTryiwciYa0KhicYsC2XMwa0yPEqApMs3P6S1OCYomiyydXjL1wl57JoxMvy+vTJ8YZLBUxK0bxTBDkL+8sZ2W5i3tRMt+tyEOXZEwtJTxNBcExTP4UQXNNzaIo1z2hZUjBmnGdIiaptM4FLS1EFojMxwI7wWSRheK3lJ3jfPHH65R+1PGri1Vl61YgCA9khpoPPstm0trtprR3ntxJ/I0BkZzRoaGzw/i9fw5z//2T7LrZnQ79oZQv0ytEYp0Xui9OxZIFOvnOoMHXGPD60p85JIjY4mIFi6dKkTxN19993OvPDv+cYbb8hTTz3lBEOTJk2yc5O3rFRrV7bKa9pBx5neK695Vak4NTHNfW90cOOjya3mtxxek8ced2txZOtWeTtKX56mQZMlHHlNth682Eyn8Eqxpete110y/XrgX2PGjZPxp+yVn9oajBU/3SunaJMsr2ZdnSZVzbl6Sd+BdjSC2y/mmOxt9Qa2eV6vvhLlqSk0RtzWeb8j0xoApFhKA53y8h3y7VXfabpyX19X72Qq0w7z8Yao9/BIo+PHjnt+lshBv0N9vfud9Lvpd9yx41VnuqPpzUC10KrBxMcGfczOje3ccz/h3PxUkxgkc6POtopWc5PIDS41AYHeH+jHP/6x0wTPywMPPODUTmiCgrY0IdRsaZNlq4y5Zo+do7Uw98ne4Qtlb2R/mQWTwvrfaMASJXGB0zFHs6iF5o2Ra65ynztpwQKZ1DTfHXTxVq8z5hpZoLU75rnpoMkctm/f7pmhD91IICCn9a2Rl8IzmGnzrJfe1/Zscnl4s66EC/phSQziiOwbFFUKmnO9tk/TJoT61cxw+hSFc5vdhdVsNQ0t7/OTTiQhAID0SWmgo37729/Kd779Xaewq3frX7BgfkZkKmuryAxyK1esdL5jZ9Er8nrDP3X5ZZc5f+P5zGcvdP6++cabSfXraKsGGxRGilbTE6L3KNEEBH/9619l9erVdq5WiGx1+uWEfPDBB/Lggw86iQluueUWOzcxTkro4XvlvlbNzkyAMyZ2fxmtBTrbM3HBNfLYxWfLkdf+q1PuqZMMrTmlVqd7K/rYxyTvYEXrPi82m5qbJa1lP5yWbP8d26ytRT+cCC0SHETrh6Ns/53wZm2tkhC0xWslTX1rTLgj450gJjLg0fvW2JqtVkMSNwRtE5IQAEA6pTzQURoIaEDQ1YMdryBn585d9tHOs2XLVufvZ8d9VsaNH+eMR/PFS78o559/vjP+1NNPO3/Tra7eu+9QvIQToQQE999/f4v+JB/5yEfksoigbsOGDVJRUSH/8i//knBigqb73oQlA4jk9JfZelDGLIxsyqZ9Z962TdZaBkLXPHaLc0+c5z363yh938imatr87ezJLefpkEwXnURqyLy09Xno+v54IFd6F7r9/OJplW66yUBx45e/OjUtoYxprZuHtQyIzIIm5NFKotZ1RGe5C8qRUIeg9iYhCPPu0486QUuLgMc20XO/Y/SmbWlHEgIASKu0lXg0IOjKwU54kKNXwTMlyFF79+yVnz/7c2f8ppv+Vb70pStaBRG9e/eWa6/9mnzta//iTL/44ouyZ3dzU610ilajo0kEotUoaZ+bL3/5y06QXFpaaue6evTo0apvkf4m3/zmN53X1L/xaB+chG/u6TRX2yoHx9wSFtAsMLNDzdgeFrmlOThZOEbktfuiv64TPIU3UTODZ9M1MySTAE7XS1to80d0L9rcVWuC33/zDefeNqHU0C3Y++aECt3aMf6YCQJapXyOvL9O5H11Qlqlk35NnJZkrd47VKvRfH+dUMrq1n1nDBswySmnO8FKM9vXJQo34NEkA83c7+jx2RPVxs8SkpJaKwBAVGm9tKuBQegeNBrs3Dlvrn0k8/3H/HkZV5MT7sc/fkx+/evtTkf96TOmy5q1P5BvfGOx3L14kSy55z/l0e89Il/44hecZV999VX5wffXOOMdIVp2L61J8KrV0fmhYOXZZ591MqyFD/obPPnkk63ma9CkgcanP/1pufTSS53ne9I00gNek/sSCXKaaL+aMeJdSfOY/KVFrNBXhn/eo61bGul3b2ugc/To0Xb3ieuMPnVIjgY377xzQnoVFcnIkQPkzPe1iP+uPP30XlO4P0PGzwgv3NvsY+GF7neflqf3mlBn+FekedHmLGXNGdpekxLt33PGeLmpqX/PWXL55cOl17G95v2aC/FuNrPmGhV11uWXy/BeJqh5OtRnqHXg09Jr8rLWzkT0JxozY7wTgIUbMyPiPjZnnS5O3VEo+DLf8XdO8BX+2V16H5wWq8hT4p+ltVASgvbXWgEAvAX6FfZPe6eNc889V26/49+dTvya+akrGD16lNx6260Z/5k/f8nn5atf/ar06tXTzmmmnc+fffbn8t9b/9vO6RhaG/bxoZqarDVNhhBZSNb+NwsXLrRTbaP9er7whS8kmWxB74ezUAY8n2hNirv8GL335hH3pp+hOMhtFtfXubGoVwrpSFrD9MnfJ1eDE077OxUm2ATJi9aQXXzp5XKiusrOSZ2s7BwZP26MHHj1J7Ltj5ohcLiccUbrG9sifQImyPnDH/8olZUfkxlztdD9vrzUor+J3kQzojBugheve8OcdflNTTfLVMf2/rRFKuYmej8aJ1iyorxe6/eO+Gz2daK+j6WBSPjb6fK/6/sVM0/73DxqM5i1/p6eabQjP7sRuVxoPXg9P6HPovf0+YoJ/ux6ifV6AIDU6JBAR/U0BXHNctaVdJXPrIXeM886Uz56xhly+kc+4kz/ed8++f3v/9AhyQe8fPzjZ0tej9ZNFfXzaACmtTQh55xzjnNPo/b605/+JFVVyRTcEwt0NChxUkrLEXntvmi1PC5nWa09coKgsMAoGW9Hv0eP0nV4yimnOM322kNrhIYOHercpyiVNKub/hbhNLA69dRT49ZCaRa9VH+erkBrX959913nN23P99fX2b9/v5OxsKsmnXCDhsjAzG/Okstv+ooMl73y0/DsdwCAlOqwQAfdy+mnnyanDjjVTrWkBbDq6mo7hWRp0JBsYKjBUbT7Lmm2u09+8pMpT1KgAa3W3ulvrQGoTiciMihqb/ATCiLCg+tMov3NKisrmwKTRIPCSJGv0yVF1Hr4VoK1VgCA9iHQQVrolWltvhatcK0F4I64p4/f6Hrt2zfZKqL40hXsRDp06JAzaEKERAIf7dOliSq0BisZ4cGNFv7pUwQAQPdDoIO0KSr6iPTr389OtaZX+rmnS+I0aNR+Oe0JRuLV7Gh/unhpwFNFf3u9J9LJk9H772jNRqJBTii40dft8jUbAACg3Qh0kDbZOdkybNjQqAVr5ZWcAK1p8NGnT5+017hoc6kzzzzTGe8q/WVCAc5f/vIXtiUAANCEQAdpFauvTog2Lzpy5IhTYEVr2h9Hg45YAWMyYtXqRNL+Ihrs6E1b9WaumUa3Gb0/jNbgAAAAhCPQQVppgXrQoI9JQc+WN/yMpIVvbcKk9+DJ1E7jHUnXm6bp1kBDs+ilQzIBj9JA5/TTT3eak/XrF71JYkfS7G6a5Q0AACASgQ7STgvqgwZ/LOEsUpo9SgOeWH03/Eqbpmlwo+sqVTU4sSQb7ITTPj3aZ0iDn86o7dHanFdeeYW+OAAAwBOBDjqE9jEZcvbgDuvojo4Vqu3RjHDal0iDtXSjNgcAAMRCoIMOo0HOR888IyU3B0Vm0xopDXg0Y5o2c0t1UzdqcwAAQDwEOuhQ2kxq4BlFSd8XBV1fqpq6kYAAAAAkgkAHnaJPn97ykaKPODfARPcTauqWbLpsX9z9HwAAdAgCHXQard3R1NOnnto/7feHAQAAQPdCoINOp2mUNdjp07dP2lIpAwAAoHsh0EFG0WxdfU3Ak1+Q7wQ9WtMT+gsAAAAkikAHAAAAgO9wmRwAAACA7xDoAAAAAPAdAh0AAAAAvkOgAwAAAMB3CHQAAAAA+E6g3yn9yLoGAAAAwFdILw0AAADAd2i6BgAAAMB3CHQAAAAA+A6BDgAAAADfIdABAAAA4DsEOgAAAAB8h0AHAAAAgO8Q6ABABgmS8D9tWLfpxfr1H37TjsX6Tr0U30cnYIZ4L5fIMkBigvaoEAjodiXS0NDgjpv/6urqpLa2RrKzsyUvN09ycnIlK8uN7SOfBwAAAH9J+Q1DBwwYIBeOGy8jR54jObk5zryGhkbZs/tNefmlX8nfPjjozAPaS4OVUKDS2NgoJ0+elIbGBsnLy5PsrGw5XnNc6uvrnMcDgSwT8GQ5wY4GPeEBD8EOMoUG5aedNsBssLp9hg7N7vZZeeCA85dttm1Yt+nF+vUfftOOxfpOj5QFOgU9e8pXpk+XL1x6mZz+kY84Bc3GYKPzW504eUIaGxqkurpafr7tafmvko1Sc7zGPhNIXmhn179ai3Oy7oRTg5OTnSP5+fnOMkerjzqPh8sy22VuTo4Jhno4B5XQa3DgQGcJbX8fMcfNa675mhQNHGjnNZ/sguZY+uKvXpSnnvp/zrSK3LbDt+XQeHfHuk0v1q//8Jt2LNZ3+mUX5Bd804632YDTTpOFi74hl152hXOl/I0//F5efOEFefr/bZWXX3pRBp4x0BQ+C5xlzx9zgQwfMUJ27fydHD9+3JkHtJUGOSdO1jq1Obpja5CTbQKZ+rp6E/ictEs102X0OUq3VT0gqNBfoKOFtr1Jl11ujo+flr/+9f+ci0I1Ncfk2LHjznFSj58jzHEzv6BA9u7d4ywfOqGFhtA8NAutD9ZteoTWCevXP0K/A79pxwitI9Z3+rS5RicUOfbs2VMWL1kq533qfHn/L+/Jpp9skF/+4udNhcnTTj9dvrXyO1JYWCj19fXO0K9ff/nD73fKf9690PyINU2v1XUUywNPf1PGVD4hn7v+ITsvkl1GXpUll98pZXYuUkebq9XUHneCHKVXQPr07iNB80/75mgNTyzaxK0gv6ez7bH9ZZBb1smvriyS15ZcJvPa9MFvlbW/miZD98VaP5ln5j9fIxdf/Hn5/vcekVdf3WHnus4//9MyfcZME5wH5I03/iAffvih5JiAPnTFT4Uu4Ol+sL+iQn7zm1fdGQkqfuAZWdz/2RbrzJk3plJee61IxkQ8Fs8ta1+SUbvGy/UP2xmdqLPXbWiblCft+iheLk8v/rRUhqYd7j47cvc35fKmDd9uy3YqvqPt2G/arnPXr66jS+XDsO/tbrd93IlI1YkfE1u+TmLr1nnOyN0x30P3jUs/DP+dvdhjeG93qvq1eMunVufvM91LZ65v3R6vTPwgE38fco5vI2V3JxyLvLS76dq/XHe9XP216+S9d/9X7r93iezdvduZr5Hnl/9pqnx2/Dg546NnOoXSEA12tC/Pxg0/lh+tW2vnxuMe8Is8d/bWBT/vA91b8uTnZklC5117IrLHGCP8IOfzgmYXUVNz3GkWGaqiDQUuGmTXnqiRxoZGt/mk0RzMuH9D26M+p2dBT2c8Nra/DtNNA50ZM6+Wz3/+Elmz5vtSvv3XTdtpKAi/4IIL5CtfnSF9+vQ1Jzxt1qDbtfOnie4K2i+tvr5BHvvxetmxo9w+Ep+zzYaCGec3GCahE5o4j1XKvqHDmgrd+2wh3Xtbj6XjC+OdvW5dkQVydzt1gx93f9UgZ9WzImVlbVk5ka/fcTp1/TrHyv7ybNixtcW2HE6XvUNkVdgxMWYhL5GgyNlXzM9o399575iBTrEU3zJR7rjSHN+d198ml+qxuvlgb3VO0BrS2fuM87sURVv/9hhvp5qE/V7ev6uu05Uid3it75DOWe+ZcYwK055gpT3PTQN3bbXRqacOkC9OmuQUODc+9iMnyNHO3uqCCz8js77+dRl4xkedgqf+WKFB+0ZUVVXJxMuucF4jfbRgOV4+Z4cn9w2TK3+1Tm6xj0ajO8ivnB+p+bmf+5zuHM/IA8V2objKZN7l5nnxDpLppgfhXyXzubsG3abqG+rNjm32bCvXbHuh7Uurenv16uUkHnAey82V3r16S6+evaTABOE6rkFOY6P7OunB9tc5HpLrdZ2FFXK08PGrBNZ9pgmd5HQ737Fjh/xo/Q/lySd+Khs3brDDT5qGkpKNssEch7dvf8U5EQ45+2znuW3WqpC3y12vn/umvFZtZxll8y4L206bhyf3ucFQ68cy4+TXYevWOQabfdopmPWRMYt1PDQtMvRKHXcLXr3HfFMWL/6mme5622qkjli/zn7tXBDSY6tdr2tvtY8molg+VmQ29de+6bGdmiHu8dMEqJcOM8/fmNgFLEeZlD18p1z+uSdkX+9Py4xb7LG66X3d/Wvfk5mxn4Tr1OORh1a/W+Tvpcew8MedY0/L9a3HqZbLZc56z7T13VW1K9D5zPjxcvrpH3ECnF89/7z5UbJMAdQtNH7iE590fqTcXO34nef8UOE0OUGv3r1l/Oc+Z+ek38PXmwOLOSBeGqO0qAfOK4dqATVyY9edI/MOPN2V9r/Rqx0humNrkK0B0EnzWNA8ptMBMz/0mCYi0O1Tn6fVvk7CjIZGqbNN39KN7Q+x6PHSntdaCZ3wfv/7XfLss9vk+V8+5wy/fO4XTcNzv/i5vPBCmewxx+MePXqYs6PzlPhsQdyplRk6zYybgPpjZr4phC3WguPTy2Wku6QbhNtCuUuvrNoCZsSgV1PdQrzHkFRhtP06bd2GtCpwxRiWvCphcaTL/kZrMzT66az1q0H2kteOmqjgCWfd6Xj1h390H3S25YjtrkUtufoH6W9mVP5vywOrE0Also3eMrMpQA29h7MfhfadiMH5/fRqtxPIuhdkMqFpp5dO32e6Gf+t70qJ2K06TbsCHSeFdHa27Pnjm1JXX2eCmcamgOa1V3fIT02E+fimTfLmG284V9nr67RKzS1oZtmMV8NH/oOzfGa4VWaYg9S+JxNsXmS4V4pDB7KWV+GcQoEpJISKtU3TTVf4dGh9lb7la74kT8e7jO8cOJuXD50MnffT5idNVxHD36t1ASXyJBr6vLeEPk/TgV+bWYQ/t+OvPrrbm7ut6XaUnZ3jBDQ6/+TJE07Ao49rYBMKanReTa02aWtwtkHdXrVpW/pqdJLV9ba/yPdo2jY85oW/TuR7eBfgIrbRyIJH1O9hP4OzvDvuNq0KXfUNX08R79Hic3eGtp+ddPtX2Saoj7ywFNPDs5oKiW6B0QTU/2vmhwrnl98pboNkDda1MN6yRsdt6hFWUNcr1Waud22OfZ9O0QnrNlzEcdpriLqv2d9o1yi7bAcHionpnPU7sn+fpuBGx5vY4KfFEBlEFn9Misz2+2FoA0+KOXaY82vkdu5s31ECWzeo+V+prHaPRXrcizwWhi4ktL5I8Izzrh2rk/eZbqdrre/W264dImtZI4a4ZdoUc9dMG+Xm5ZjCY6O8//77JoLMF814pZGkNhPasf3Xsvb7jzr9cP6r5CdOn50+p5wiffr0kd5mOPTh35zs4Frj02Gcg1rrqzdNbhklQ5M56A2dJnfISnsQc6/WXxnvBKRXekbtss/RAoMJQu4IK1yZk+GMptc0w5NvOVeLvAuCyhxszUYlYVW4uz7mvp5TKDHPby6I2BoB54Tr9jdpeh9zAigyB9ZWG6D5vJeGPo/TFEgLhm5b8tBzE22SlUqNjcGmnVkDHd3mdFqDad3hNX20M20Ca005rfNCwY9uq85jdlqHDuHD7e/hXWb76t2/6Yp/6Aqp9B4plza9qM47Krufdb+3BkdOG/aw99CTesv30OB8lOwKLaMFFL1CG/p+ug23KGSsFLnU67u7zRTcwnWoKaENJO1+oH0k3Ncw60PM+unUYCfKJb0ERG7H0a4OJizsqnRzbY9OR2/f7p743N/NLdR5Bb6dpZPWrQYp2qSmTJsrhba18CEUOL4lz+oB2lnO+2KHG2ia7fnDS816jjjm2uNL5+mM9es2PXOPqc3jTnNKr/55um7DmzeN7G8KZG278nzLWrcfYNI1MmUPyfX2mDT00uUirZp+uttD6wsFl9kX6EidtM90W11rfUdrttyy3Nl66MikGqpdgU7A/NOr5zOvvkbW/Ogx+cH6x2Ttj38iDz26Rhbfs1QuGPsZZ7k3//B7+e6q5Sb42S47X/+d/PiH6+Tpn/3MFE7zzK/jLJKw8Cri5iFWx7IQc8K9w+38VxLzwJTEQc8c5Jp/sIekRAtTQ0fFLvDrlZ6mA7AphD2rBcWwQqE5EF8fvhE8vNE56BV9LEoxwaPw/PC82O2Kb5nhrodV4e9j3neV+fy9x8yM+Pz25GsVP3CpDI147sMlepVsmIyK+cVTrXnD0SBGAx3tb6M1NFp7o/O0eVuotkcPAlpzE7p3jlOzaAIdFXF8iIntL8LDu5wAq+m312Ct+i3ZZwKo/k3tnTSAs9/LBBeXDjUHwFVh26h9j6GjWgYqLWq27PbZ9P2cAkp4UGi+yzyPgk0Mzn7QoqDisT66KN3G23TSdIKZZ+SB3W4NQmhoru1pnueuN21+415A0SCnZc2Zu284F0XCCpdRC6FdRJvXrRenVtIcPzSxSKKJSgy3gGGX19doCiQzp7lIWyW3fvUiyluyy1kR7gWVD3fb4LrFMbrl0PKiSusrzy0D+5aD81w9jmlH+XZsx85vGNmnxKdSus+EiTwfe12obdGEMCMuuKRfutZ3oor1ioP0kZEZciJtV6BTp4VFU0rUmhzt+N27d2/n7+kfOV3GjLlA5i1cJKP/8VPOsj8vLZV7vrFI7l44X574rxI59dRTncLpyZOxUwBH8u40GLoiFqnlCdc5mXSFA0uLJjluIbp3/yhN/Mq2yW4tJGo1d0I7se18uXtbq/VQ9r+V5v9F0qJMW/1hU7MV5TQNiDx4tGr3nH7ujuzSvjdu0G0CG/NPm0VqYKN9dbTZWijo0UGTE+hzNehpMIGRCnupuNj+Ij0ku/Y1Bym3jBpmtq2NsstsSqF5zkFv3y63UOYEKOEdspvfo6VQ4aVZi+3TCbDs67SpGY+7H7QqzDhNPbsZ+3s7hTsnmLlMnr20ZZOEVgU/j3XefHXP7g82MLp8njgFz+i10t1VWNOnNhSYnWaj+ltoDW03KTB7s/0enYt+Gui5tbih47N2No88bjdd3LBNAiMHr8A+NDjPtTVDI0O/Qdjg7CuR50gdIs7PTu2n3Y9aNgFyj4ctm651fPPwriDyd21VU6AX9sIe7977SUexTfBfe9Wc7ydmRGDZrkBn7+4/OgVK7e+gzYJCg14tP3z4sPTI7yHFn/+8s6xeSXeY5bV528hzznUKm7t3v+nOT4uWWa/inkx2f9gJNRMtOSevFk1yohWiQ+xBXZv2hA6u6b5qEesE0EG0lkavWOh2lWcCZg1eTtbVSU5ujhPc6Dap26HWGjpBkRm0CZubaa1RQrU5+ljTtply3WH7049tCgVFHzPbnAYPbhM1p0mbU/tSLJeONAe9XeHfPWK9hIakCns2s5pWkYcK4G0IeLwD185J+qDH0sjmB22V1GuF99GxnKDF6c8Q+VvZ/jctfs+QUH+nOSKrzLK7RtlCWnjBrXWfsI7QaevWiF67EJ51rfXg2Y497CKE3qPI+U3aUauQKp23ft3jwLP9v+lccJPXNsruiH4DmhSjdU18ZLO/5fJ0tPOmrvMox5ZQU8LwwdmPIgvYOkQUsp2Lhs5x04pyXm3Vr6iDdN5v2j35ZX2HWv2UzLtTnq38tNzRGQf8CO0KdF761a/kWHW1cwU9XHZWlpPCV6+e9+3b15mnAZAWKHXlj//cBBk+cqRzB9hfv/SS83hGCNWOXNpZ1Zu3yihzUNbCV3PQYPs8xKNXmPSgqAW/mE1vykQvjPf2iLSdK+/Vu8V2pfDkFGrjNY/qAKFU0lqb42ZT0wQDuo3lOLU6oQQDupzS5mwa5JgnOTU9ofvrZAWympbpdF10+yt7drcJss02d8tEGSl2+3FqXLT2JbxpiZFwMKfPtaOW1ha12j7DC+lJbZfR9wNYTnPBorB+X9okKEq/BKcA7hbcm5KfaO1Yq8JbsmnSu76WqYPDBw0aE2nHHgogzXDph00F6I68sJTp3ObTGtDMlJFNNYtmsMH6vn2RAXt4M0G3WbFUagYOD9q0tmhaG2uOo3GPtfuepYYBPmLOA3qD6SdtUK/7pYyZ0+nH+3YFOn/720HZ9sxTUlhY6BQ0NYjRq+l//eADWfGt+2TR/Dul5LHHnAKp0mU0wJl5zddMINTTac6mr5E5tHbEnHycmpHIqmI9yaf7BP1H+dAcrcObCTkdHu24p+LlsjbWh3IKlmH9JQznpGC+Y4tI27zOHVrdGOfA6xRqtUlWi4O+ORF3cNtXbfbo1sRowoE6qa2tceZrbY3eRFRTRoeCodC2qU6eOCEnTtQ6y6msbO3f495rp/N1we1POQGatsc1G1lTk0ht0mbm3aFXd8KaPzY1tWz5/W5ZG/ndIpIkmAOoXpltanJpppNpCuXVLNNNpNB6P3g6pQWaxIWOk819x5K7IhdaPvR884Lu33bQmh2n47vZ9p4ONb/0qkHQgNMpVDYX3JtriGyfCecYodt4x9eYZeK6TYhuj+EJM2I1vdFmoRFNjTtK565fc/6xCXmWmMC8OX2/O7/yyVly/fW7ZJTnOUq3TXe7vtxs197rVrfZb6Y22HH6LbZunptJuuw+00V19fXtNL90bvTdsm/t5Ut2y8jFndt0uc0pz3Sl6g/z+KaNMmLkP8gnPjlaPvzwb06ztGPHqmX7K6/YJV1aKP38F74o0//5ajnjox+V3762w+mro0KvlRm0Kvwht2Ptr16SK+3cjrlbrjmgrpooTy/Wpjjm5Gbse1IPsOZA7Ex5MBvSrhl6te+bdkbE5zSPP2sev1KbR1wZesxsfGV6lVCr88OfNz7+92t6bvNndJsizYp+Ak6THnk9pNYELcdrjts50hTwaL+c/B4Fznaly2j/nEhus7cedipTdLHtz1Emz+6eI2PMQq+FVbdoIHHllXozvfD+YFpoKHOayGn/pdD306Zy17f4bub77u7vrIPFdo6zTOgI+vBG+VALz00ryN0Go5Yb9KrspeZ7aE3DYrusFs53m4Kkc4NGux9ok5PLO6cpkCZ20Ttaf+GLl8qE4oud81Qy57rQ8nl5uTb4r7WPtJ3zO9lI16nYs01tWm6G7vFAMwaGb6PNaX/d3zy0TS+O91ulQSau24Q4x1s7HpMpsOuNK3d/M+K36Ridt341UHFrGT/nbHhlzvd3tjW9cNd0zDDH1VUaND4jl4Zto7es1WNb66QC4SmrXboN/4N73lsr7W4u6NROm8/cYh9wmuCGzqmR3rJ/O05G7DO2OX7oHKDCzwNuk8RQGUZ1xHkyPbrsMUovxmg/bae5pseFGD2GiS6j5+uOP/arQL/C/kmsSm8DThsgd86/S0af9yk5cuSwHD9+XMp//bK89T//4zQrGjRkiAz7+7+XESNGSkHPnvLbV1+VFQ8sk4MffGBfAUiOBsf6TxMQ6A6t98QJp03Yevfq7Sx37Hi1U6sTTm9uq0k0tDmbNnXLnEAb3U3oQs9HPvIRufqaf5GBA8+w87Kck1ei9CSn+4G+1vt/eV8ee+xH8sEHf216/ahCJyoz6hQiZJ3b7Cw0HX5WClvWKVTsqJQxFwxrXi7ycY9Ch1sIrXSaD6Vbp6/bVmwNgruCxA2s29B8qcV6trSw38H9dTp7/TrbUv9nm7+3NqEMNZn0XBeh9W8KXE+KXKlNAUPrP/RcR5QCs7Pe+8uzSz6USyPXf0L0dbX5ppuNMNQ8sdX3CBd6zw4qIHb2b9rddPb6Dl0USJY2cde+cVdqFtUEg8um9+rgY1VKAh1V0LNAvjpjpnxx4uXSt+8pTiFSC6JK+0Fohqu//t//yS+efUZ+ummT1JhgCGir0M6r/XI0CYFeDQkPZvQ+Or169jJBUI3UnjjhHABCQjU5uXm5Tt8dDrzIFFoTedppp0tWdsDZLs0h2n0gIXZ5s61/8MHBVsF9d8e6TS/Wr//wm3Ys1nd6pCzQCTn1tAEybtxFMnzEPzgZsFR9nZtdbfvLL8nBg5nUJwddmR4INEDRv1qzo0kGdOfWZBh5PXo4yTCqjx1t2uF1WT2QaJDj1OTY5xLkwI/YttOHdZterF//4TftWKzvZikOdHSlxnu5RJYBEqM7s9IdWhMMaH+cLDMeSit95OhhfdSpxcnNyXHm63j484BM0t4TlG7abNbeWLfpxfr1H37TjsX6Tr2U1+gAAAAAQGdrV3ppAAAAAMhEBDoAAAAAfIdABwAAAIDvEOgAAAAA8B0CHQAAAAC+Q6ADAAAAwHcIdAAAAAD4DoEOAAAAAN8h0AEAAADgOwQ6AAAAAHyHQAcAAACA7xDoAAAAAPAdAh0AAAAAvkOgAwAAAMB3AkHDjgMAAACAL1CjAwAAAMB3CHQAAAAA+A6BDgAAAADfIdABAAAA4DsEOgAAAAB8h0AHAAAAgO8Q6AAAAADwHQIdAAAAAL5DoAMAAADAdwh0AAAAAPgOgQ4AAAAA3yHQAQAAAOA7BDoAAAAAfIdABwAAAIDvEOgAAAAA8B0CHQAAAAC+Q6ADAAAAwHcIdAAAAAD4DoEOAAAAAN8h0AEAAADgOwQ6AAAAAHyHQAcAAACA7xDoAAAAAPAdAh0AAAAAvkOgAwAAAMB3CHQAAAAA+A6BDgAAAADfIdABAAAA4DsEOgAAAAB8h0AHAAAAgO8Q6AAAAADwHQIdAAAAAL5DoAMAAADAdwh0AAAAAPgOgQ4AAAAA3yHQAQAAAOA7BDoAAAAAfIdABwAAAIDvEOgAAAAA8B0CHQAAAAC+Q6ADAAAAwHcIdAAAAAD4DoEOAAAAAN8h0AEAAADgOwQ6AAAAAHwnEDTsOAAAvnPy5En585//LHv37pU//elPdq7IWWedJcOGDZORI0dKr1697Fyg+2DfgN/5LtDRr/POO+/I448/Li+99JIzb/z48fLVr35VPvaxjznTAGL729/+JjNnzpSf//zndk5LX//61+Xb3/62FBQU2DktNTY2yu7du+WnP/2pvPbaa9KzZ0+ZOHGiTJ06VU499VS7lH9w3MlM+/fvl+985zuyYcMG+fDDD+3c1n7yk5842zvQXXTFfaO95yV0Uxro+IUpXAU3bdoU7N+/vwZvLYZBgwYFS0tLnWUAxHbw4MHgF7/4xVb7UWgwJ5Tg8ePH7dIt1dXVBR944IFgnz59Wj3v05/+dPC3v/2tXdIfOO5kntra2uDDDz/s+Zt4DaYwZ58J+FtX3jfac15C99WmGp2HHnpInn76aTuVvKFDhzpXOf/u7/5Ohg8fLoMHD05JBP7HP/5Rpk2bJnv27LFzWvrMZz7jXJ3Q9wMQXXuunD3//PMyefJkOXr0qJ3Tku6j3//+96Vfv352TtfGcSezHDt2TO677z5nSFQmXbX2i//7v/+T//iP/5ADBw7YOc1OP/10uf/+++WjH/2onYOO0NX3jY6u0WloaJCVK1c65zQvd955p3z+85+3U8hYTriTpCVLlrSKpNs7XHTRRcFvfetbwYqKijZf/fze977n+drhw3/913/ZpQFE09YrZ/X19cEFCxZ4Pic0aE1PeXm5fUbXx3Enc+j2p7WJXr9BrCGTrlr7xebNmz3XtQ53332381uh4/hh3+joGp23337baYXg9V4mwAm+//77dklksozJuvbiiy86V3+GDBnitOP/7W9/67TzT0asdqYhZme3Y+gI2tER3UddXZ0cPnzYTnnTmh69UpbJ9PMl+hk57mSOnTt3yurVq+0UOovWHDz11FN2qqWBAwfK5ZdfLtnZ2XYOOgL7RvLKysrk1VdftVMtaZ/ToqIiO4VMlpHppbdu3Srnn3++3HrrrfLBBx/YufH9wz/8gx3z1qdPH5qPpJkW6P7nf/5HHn30UadK91vf+pZ9BN1Bfn6+0zQ1lk9+8pMyYMAAO5U5Dh06JL/4xS/ktttuk4suukj27dtnH4mN405m0MD0Zz/7mZMUIpZx48bJvffeK1u2bJFVq1bJ1VdfTaE7xbQ5Z7TmRV/84hfj7jNILfaN5On54JlnnrFTLY0YMcLZjgOBgJ2DjGZrdpKSjqZr0YbPfOYzwd/97nf2nWP761//Gpw8ebLn6+hw8803B6urq+3SSJWqqqrgCy+8EDSBqdP5Onyd67aCrqc9TQT+9Kc/Ra3u1+H+++93EhZ0Nv0M2lT2kUceCV588cUtPqMJxoJ79+61S8bGcScz/OUvfwl+7nOf8/wNdNAmk2vXrs2Ibc/PtImUNk3z+g100CZt6Fh+2Tc6sunaL3/5S8+EOjrcdtttTlIHdA0Zf8PQX//613LddddJeXm5nRPdaaedJt/97nflmmuusXOa6Wt885vfJB98imntjV79njBhgpOkIt4VI/if3nvhe9/7ntM8JZzWbCxatEhuueUWycnJsXM7z7Jly5ymsiYQidrZNBEcdzKDdnrX41E0miBDk0ZkwrbnZ//7v//r1Ix60Vr+sWPH2il0FPaN5Jw4ccKpAfNKqKPnsS996UvSo0cPOweZLi2BzujRo+ULX/hCq0GrRXUjSdbvf/97uf322+Wtt96yc6LTm1ytX7/eyRH/wgsvOPe00J187dq1ToEEQPqNGjXKaYKqN6HT/fCVV15xguB77rnHl4V+jjudT/uFeGX4CtFtsm/fvnYK6UK/hszDvpEcbbb83HPP2amWNFg/77zz7BS6grQEOnPmzHHa50YOevKvqqqSv/zlL7Jx48ZWV3xj0QPngw8+KDU1NXZOdFlZWTJo0CD53Oc+5wRXemClLSXQsfTq4N///d87+6GmWPZLOuloOO50rnfffdeOedOUxkgv+jVkJvaNxAWDQae8Gu12AZdddpnvz2V+0+FN17QwcMYZZ8iMGTPk//2//+dkW9NCUCJ+/OMfy8svv2ynAABApnj99dfll7/8pZ1q6ZJLLombqATobJWVlbJt2zY71dKnP/1pKS4utlPoKjq1j44GPePHj3c2qvnz59u50Wl7yU2bNjnVsAAAIDPQrwF+oP3BowXr2gVDb3aPriWgGQnseMK0nf3ixYvtVGttuZOuNkl74IEHnI67sWgO/v/+7/+WMWPG2DmdRz+zdvDT5nhKqzM1bWaiHfr0HjN//vOfnfz24VXLeXl58olPfMJ5rY985CMpr+rXFNDvvfeekwJUq2cj7xei/Q20Q/nf/d3fySmnnGLnetPv/5WvfMXpR+VlyZIlcvfdd9up9gl9bu2r9eabb7a4R4+mwNSmEbrOzjzzzA7rVBn6DfUu4Er7n5xzzjkpuzNzZ+noO1DHo4cpvV+N9vnR4eDBg/YRl6arHj58uLPNnnrqqc5FlHhiHcc0BfZPf/pTp+ldptH7i+nxQq+e/+lPf7Jz3XXw2c9+Vj7+8Y+nbPvXpki6b+sxKrS/6fFJj7/arj+T+ltpc+h//ud/tlOtpeoO77r+9aqvrvvdu3e3KtjrNqjbov4Ouq46Qvj+ofeyUvr+eizsqKZiej7RDu1eTX60s/u6deu6XJOfWOccpb+1JjTRmqrevXvbuckL/X5vvPFGi31N6fl45MiRztDW7amj9o10S/d5SS+ia7KcH/3oR3ZOs0wqeyJJGugkK1566bbeSdfs6EFzoPR8zfBh1apV9hkttSf1YDLP1VSx+hn69+/fYplEU9JqStt/+7d/a/V8r2HcuHHBJ598st2pDE0wEzQH0YTfVwdNrai/hynI21dJXWrxRNNAhj737bff3ip1dbRBl9Pl9XObQol9pfj08+jn8npNHXT70O1E6e9hTh5BUxButdwrr7ziLKPbyde+9rVWj4cPia6HkFh3atZh5cqVSX3naNqzL+k+oPuC1/N0SCbl+OHDh531rPuB12t5DaHf3xRA7avE/0zJDKHfN6Sjjju6L5SVlcVcXodzzz03uGnTpjanitX3+c1vfhMzZbYOehwxwWLQFD6c5+l68VouNKTyDuvx1lsyQyLbo+5TetzW7+u1z3sNun6uvfZa5/YIuk6Tkcy61M91zTXXtFom2WNLe+j60WNP5GcIDZq6OJr27D/hUnXcCf3Wunyi5xwdRo8eHdywYYN9lcToeUTP74kc33R70vO3frZY0rVv6G+gv4XXcjroe+p7x9Oe3ztV20o0r776atAENJ6vredybhPQNXVq07VIerVHo2mNnGPRKx5e1eMdQa/cm5OX3HHHHZLIHdHDaQ2QXm34x3/8RycdbSLP1z5JV155pVPtv2vXLjs3OZoJSj+zKQAl/L5K1/ETTzwRM1tLOoV/bl1viaau1uV0eb3ivGDBgqRuOpsIverzH//xH86VpVgpO/Vq9xVXXGGnvO3YscNJx5oo3fajZTTS/UZTffuhs68pbIgpADhXz3Q9J9M3T39/vdKuTWn8Qo8d9913n3z5y1+OejUzRK8KT58+Xb7xjW8k3cxX93mtgdV26Jo1LxY9juiy+l6JZMTsqvT4occRrWXX7xtrnw+n60cz8enxXo9jejxLNU3wc+mll8pjjz1m53SOWP0atA/uxRdfbKcym27/mgJff2ut7U3mdgl6bDZBiJ2KT8/nem7XIZHjm25Pev7Wz2aCyoQSMyFxDQ0N8vTTT3uWd7Tp5T/90z9xm4AuKqMCHaWdvbT6OxZtKpRoYT2Vjh8/LkuXLnUK/8nSk+XXv/71NgVISu9LoDuaJm9IlBYW9bNqFqjOPhEmI1WfW09a3/rWt5xmE9rMJxX0YPjII484J5xE6D0jNB1lNNosSJt8JEKbM2ia5mi++MUvOk1mujptLqIncr0HTaKFSj+rrq52CtpayE7mAo8GRrqt6jabCL2IM2vWLOd5ybyPHpvuvPNOef/99+0cfwgGg8593LQTvR5HklknkfQ4pgHJs88+67xuKmhwOW/evIzYR2L1a5gyZYqTjTDTtXX7T5b+/lu2bHHO51qwTpZ+trlz5zoD/ZVTJ979n7Q/ObqmjAt0tLOiXpWORa9YdkYtg15J1cxvydID6A033CAbNmywc9pGry7927/9m/zhD3+wc6LTwqIWcvTAncxVqc6mJ4H/+q//Sunn1sKKZvnTq5/t9bvf/U5Wr15tp+LTFMN674hYNHiJbPvtRbf5aLU5Sg/GXf2Kk/7+jz/+uNN/Jp2Fja5Cg35tP59oYB1JaxS030Y8WmBasmRJmy7iKM2gqccmP9HjhdYmRut/mCwNSPT1tO9Xe4Od2tpa+f73vx/zeNBRdNt56qmn7FRLXSWldHu3/0Tp764Jlb72ta+1+/ym53ft16znerRfrPs/kVK6a8u4QEdpxz7tDB+NFoA6uhCkneD0IJjs+4YOoFoQiOWCCy5wMnpoYTXW1S896WqtknYSjiZUWFy4cGGXKyzqTbr+9V//NeWfWwsZevUzWm78RGhTKN0GkjlB6QleT/R6wo9GD66JBO7a+Xn79u12qiWtCb3wwgvtVNel61ZP4PF+f00SELoR8YQJE6R///72EX/R44Y2QWsr3d61CVqsgnWollKH9uisJq7poBeTbrrpppRfJNLafM0w2t6LLvr5SktL7VTn0hrpaM0pu0pKaa2NSuRCZOg8rYOOJ0t/93jnZT3/azkgkffQJtrR7luExMW6/xMppbu+jAx0tK9BvKruv/71r3asY2h/Ac24kSx9TqwChN40VWsJtACrJwst6GuhXA+60daBFrZjneS0xkuDoUSCBW07rQdLPdDrHd216lYDM925vRQWFjYd6HXQGyNq+9Vowguk4YPeLT7yKp+2Ydf3jve5tc+OLqefVT+zNgPQQkm8bUYDCv0t2tq2+Ve/+pVzhTxZeqLXE340+tuHZ8/yooVR/a7R6IHYD2kvtQCnNXDRaH8QbbqqBXjdX3TQK3EHDx50Bg0MvG5EnJub22pb1OlodJvWbTt8+dCQn59vl0o/Pc6F9gfdvu+66y5nu9f9VZtT6b4Qj65PvVATjRZUE9mudX2EjhXJvH86aFY9zUYV/ruMHj3aPupNHw9fPjToMS2cFnr0+Bnvooj+Hhq0aPMj3Tf1rzYxjLVdKQ2etIauPX0H9ebZ7blokyrx+jV0hZTSWpuuTcKjnXf0eyxfvlwOHz7sNNELHXd0XDPcab+c73znO3H3Bd2XV61aFTV41os1+rjuj1oOCL2Hvr4e97zoZ/7hD3/YojyUzn3Dr2Ld/0nXAymlu7hgG5hCZlMmCq+hvdl1qqqqgldeeaXna4cGr/dIZzaP8MEc+IL/+q//GjQH+KA5wTnD9773PSfzTXjWtffeey84YcIEz9fQ4ctf/nKwsrLSLt2SZn7RbFP6Xl7P1fWj6ylSvMwoocEcOGNmJdP5u3fvdr5TZJapcKnKdFNfXx+87777PF8jNOi60Ow90TLQmYN9cO7cuZ7PDQ2aUcWc1OwzWkp03YUGzUhngqymbUB/L12vJnCxr9jMFMA9XyM0mAKSsw6i+ctf/hL83Oc+5/lcXS/mIG2XTI327Evt2SZiHVs0M9G7775rl4zOFL6CJnCMm30n1nvp5w/fl2PpiOPO1VdfHTSFSfusZprx7IYbbvB8TmgYNmxY8Pe//719Rku6zd19992ezwsNsfY7/V6aiSzacSp8SGXWNS/6+l7vGxoSff94r6PDN77xjagZmHS+KRjHXSexPk+8rGvhgwmsgvfff79zDNDjkAmEnW1bj4Xx9oH2ipUFUrP2ffjhh3bJ6Nqz/4Rr63En3vvPmzcvoQyG+hlN8GmnWtLz6Q9+8APP19dBtxU9f0Q7H2s5QcsLXs/VQc8vsaRi39DvF+v8qOtQ12U86TxeJrqthNPj2m233eb5elpeePXVV+2S6KoyskZHc8XrvTAykdZ0PP/8807NgLbb1A7zOpgdzMm9Ht7kTjuemhOPnWpJmzKZA69znxwvWtuhfTuidWTXq7T79u2zU820Nkdv2haL3qtI72lw9tlnR207rfP1M+qV3mi1O6mkHQFjNe8zJwIxwaTTQT3aFUKtJdLvdvPNN9s5remVR61lS6RPTDR6JVevYmpfIk10ENoGtB+QOVl5rq/zzz8/6m+pfvOb38SspdSrt1rz50Vf97zzzrNTXZfWtJmAzk611rNnz4Tuj6BXNHU/7Or3MgrRTGt6RVn7e0XSq8Bz5sxx7vsTjXZaD93nKVKsDrgh//mf/+lkDfPa73Qda62G1jT5gdbmbN682U55M0GFk5krWn84nf/v//7vcdeJHoe0lqA9tO+nZuzSLJBaO6/HIa091sQVWuOW7tpHP/RrMIVnJ2tcNHp/nETuS6X7QrRkMPr62pw8mltvvVWuuuqqqOdjLSdcc801dqo1bW3QnnNad6blKK1B82KCKufefOjaMjLQ0c51Jiq3U5lDC7h68tBCq9cBSeeFblSoVcqxMqRpSsl4O5BWG2sqSS9aYI/M1mUCV6fQEqutvJ4YNVtLooVA/T4dcfPNWGmTlQYU2iQp2okgRAsZGuikok+MFw24NCvPpEmTmn7rcOHbQLh4SQn0M7399tt2qiX9XbUJQ7SmFXqTSD80MdB1pzd+jUab+L322msx+5v4kRZwol0QUdo0UrfHWKIF0XphJNZ+pxkwteO01zYdoscHDYS0mVJXp0GhpnyPRvuD6Y0X4x0T9XH93WJd3Ih2sSpRGgBr0g69wONFf7N4x8v28Eu/Bj3mxPo99WJlMrcA8KI3G43WNErPVXqRLN42pTcMjdY8Tvfj9gbN3ZGeS7SJYLRmoHp7CFJKd30ZGejolYlYV7c7i564tFCZCE21Gis7mrZ3j1WoU3qSipWUIbKt75EjR2JmCNK+T9dff33G7bjazvu3v/2tnfI2depU6du3r52KLZE+MW3tZKyfQwsYyRYgdHm9OhQtANMgRk+oXoV47V8Rrd+Kbh9amEpngaaj6NVnvZN7NLqOtJCp7eF1W+8O9Ap9vA7JehyJVaMTjW5r8dKu67aeyFX5008/3fmsXZ1ecIl1EUQLPh/96EftVGzxLm54XaxKlF5w0VqAWAFwuvmlX4O2HvGqLQ3R47JemNSr/m3JcKb7WayLCZ/61KcSWlca0J5xxhl2qiXt79UZt9zo6mLd/0nPq3p7CHR9GRno6H0jol29DtEDfUfSIEFrFOIFJyF6BSha0KFXZfQKvBZg4w2xara0mU94x3o9cca6p4LuuLFqOjqL/t6xbjio2cSSKchpExu9SV8sbb15X3uu8MQLwLTgUFVVZaea6W8aLdDRm/F9/OMft1Ndn570Y9GTud6LasiQIc7NhRNNzd1V6TaTSG1drABReV040v0uWi2i0uNUvP0oXDLLZiLdjmIdP/UckMy9NPTiQ7ztWdd/W2ooO7u5qmag1CbSXufpZM+VnU0voEVrORGiTYs1eNN1rimd9XdrbGy0j8am+1msZDOaOEC3Pa/zf/igNWjRAi0ta2gTPCQn1v2f9CJFrAAYXUdGBjq6w8a6w7AeSBO9qpYq2sxMC1eJinVVUKuZ9Y7vAwYMiDvceOON9lnx6cFQXzsavfrf0QFiIjQFd6yDtF7FSrZp1uDBg+2Yt7bU6GjBT5sPtJUGYNq8J9pvoE1mIgueoauB0QJ/v1Wta0CbSBMoDXj0fkZaM/p3f/d3ThOe9jYvyURaWExFbZ0WtiLFqznX/S5asygvXaVgG40W3mMdh/T4r8fkZGhNV6xsXHpFWe+JkywtmHdmc1U/9WvQ7VZv5qrlinj0/Kr9ofTiktZglpSUOOevWPT3jVUe0KbQked9r0HP39o/GKnhh/s/ITEZGehoM6ZYB4a2nHDaSwvOyRQo29o0qj3i1VJo8oFMpIV4vVoVjTYt0AQVyUhHoUubibQ3SYZeEYzWbl+3+cj7a2gTLb3q5EXbwcdLG9rVaMFQa2zipQoPp/va4sWL5ZxzznGa87S1tq67idcJW495mgCiu4gX+OkFCu2YngwtKMXq39RWsRLJpJtefPFbvwZtNZDsDW81CYTeAFZrMvWiS7SARy/KtCeVONLDD/d/QmIyLtDRDnV6AIlFr5BpgagjperKKrou3QbaW2jR/g5aCxGN9hEIr73RK6fRmq35Nb+/Ng/SDHvx7kcSSdfbww8/7Fyd1SxEbWkSBHQFnVl75sd+DZoI4LbbbnNqhpNt9aDNHbUZ7bXXXhszayQyhx/u/4TEZVygo8104qVH1qxnfkkdi+5HA5RofaW0+Vp4s02t4Yl2ML7ooos6tcCTLnpBQYOVUNrcthQ8NFOYJp0AkFp+7degZQpNCa4XSbxuOhyP3shba5Spvcl8sdLqd3b/N6ReRgU6eq8HvT9NtP4ISguI8bIQZTotuOlVfS3wtmfQ9vPJ1DJlah8GzbYVq6mDJmRINtuN9leKJdkmKKkUKymBJmXQjq9K9wOt4fHSHQ7Gun3rPUs0NavecyrZ5mxr166N234e0elVz+5UK6ZX9WMF1dqHR4dkaN+oWM3htGlgV7pY4fd+DfrZ9biq93TTCyWaaTWZCy1bt26Ne6E2ktZce53fkx3Sfc8kP/HD/Z+QuIwJdPQE8sMf/jDmTSOV3k8l2SYtnSFWfxht+/6DH/zAaR/ankGr2cMPbol0wA/P0pYpNOtNrAPLu+++GzP49fLnP//ZjnnrzExl8ZISaKCjv5PW7ES7p4cGyt3lYKzN8/QGiNqMT++jo1ddEwl6dB/Zu3evnUIk3f5ibUO6vr2yAEYTb5/LdLpfxmoSrc2Sks1spc+J1d9UM24l2/+wM2n/t2gFxHT1a9CLVolkVtSgPNFMaPFoE2VtgvfjH/9Y3nvvPaeZ0/Tp0xMKevRG4eH3tNH+xLFqub761a86z4k8vyc7dHbWQz1HeyU9iaS/kV5E6SwarGu2Ti9d6f5PSFxGBDoa5KxatUoWLlxo53jTK0Zf+cpX4t5YKxPoCSwazdyihfdU047ysTL8aDOoWOlkO4vW5mjmrGh+97vfxczCF0kPZLHuYaTZa+IFhekWKymBbh96FVgDHq+027of6BW87kb3e222unTpUqcj6aOPPir9+/e3j7amBUwCneh0v4uV1EWbAGohLxF6DNf9tCvTi0axCuq6L8bKahkpkfuDaQKNriJWEgINANLVr0GD7UQCHT2nJvP7JEovxOlVfs2wprXL8TKh6nYSnuRDm8TFKg/oOTmRACHTaaCTyIVUPS53RrKmkFhJCPS86sd+r91dpwc6eoVIDxzxghz19a9/PWZBPpNoatZYV1j0ClGyzSDi0fSYsWq79AS1fv36lL9vLHrgi3f1Rq9oxkpHqgfQ0tLShJuv6ffUm7xFoymMk2kGlQ56JV1Pnl60yYTeFyHazRy1s36mZtDrKFpI/9d//VenXXystLBtDey1uWRH7iedIV4BTAskWsOeyH6nBcx4tfFdgaZtjnXVXtv1J3qzWi14axOZaDTTV6wLPJkmXhKCtjaljbcdasE0XrNrPcfES2KUCloI1gxr2poimsh72mjzxFjHa+3vFC2DXSbRCwGxaqb0GBDrfkEh0S7gdQTdTqIlIehq939C4jol0NET5+7du2X+/PlOMPDYY4/ZR6LTtrLXXnttl2n/qztNrKBMCwXRmiXFEy1wOOWUU5yTZyzaZO4nP/lJwkGDFvZi3bQ0Hr2inkjBQPtdReugrzZu3Bg1+1g4rc3R7xjripGuI11XnU2ryLWq3IteHY920tCrTn5MxqFXjOvq6uxUYjRojXWzv7bW/uqJWJtu+ZleYIjX3CWR/U77VmotW2depU0VvU9WtH1SaR8MLSjF67ukx1c9zsZad/o+idy7JVPESkLQnn4N8fpGaaF0y5YtMc9ZGgw9+eSTdio5ej6NdzEunH7eCRMm2KnW9LtEFpb1vnnRvqN+P20i15b+hKlsrhePlr3inTc3b94c83yvTTn1mNJZYiUh6Gr3f0Li0hLoaHvTb33rW62GRYsWOdmU9H4kukHpPM0xH48W7PS5WoXcVegVZ72fQDRaKNC8/XoijHfSDNEDyLe//W1ZsWKFndPapEmTnMJfNFo7cv3118uCBQs8r2qE6ElFr5BdeeWVUTvEKz14xzrB6YlRrwJGfkc9OIfP0yYj+tmj0fWlNXrPPPNM1AO7ZruZN2+erFmzxs5pTQsX//RP/2SnOpfe9DZaYPrTn/7UOXlH0pvUdfVkHNHojfU0y5rWOiZ60td9IlY/klhXUuOlqNcLMFqID9eRBYuOoNtfrIJ9aL/TY7rXcUqv8t95552+qM1ResU6VsYtPX5qZq0f/ehHUWv8dNtdtmyZcwf9aDTA0b4ZXaV/jn6naEkIdPtpT78GXQexanSUppt//PHHPfc9vZim22Bba0X0goZeRNV+G4nu25HHhXBaSxfZJDRWU2WlSZj0YoFuX4nQz6nNIvVc3pG1I/H6tuqFAP2tvPYNPVZouSNWa4t0i5WEwG8330aztAQ6eiVLa2sih3vvvddpG5lIcBPymc98Rh588EGnX0VX89nPfjbmXd61ilvTcWoqXE1pqZ0uww+02uxL28hrFhet0dIbperNFGO1V9aDrB6049FgSduH6+uuW7fOeX8d9EClwYI+pk2k9OplLBroxDpJ6YFbmxjdfPPNTpCid9PWoPXf//3fW9wRXNt262eJVaujfQa0EKKF/e985zvOXaJDn1lfX/tv6AkjllmzZnV6/5wQPcHrlVCvK336Xb0CUU1CoBcK/EprD6+77jrnQog2D9E28V7bu+4n2g9rzpw5UU9cesyItT3Fa/6nhXc9+WlfIN3ONmzY4OzP0W7g2hXpvnvxxRfbKW+6LepxSr+7rgNdF7ova6FFg26d5xd61Vov7sS6Yq/nL91G9Xij26ge00LrRJtgay2Z3sA2VqFVj9FdKWtiuvs1xKrxULrO9eacGhxqX5nQ+tb712gZIdpV+kTpsUSPrXpu0e35/fff9wx69JystUuxmtprrWDkMVovBk6dOtVOedMMk/pdvvvd7zp9UsP7u+hn0Ztqa02/BtB6gUK3v47uF6dN4+NdSNWLVV/+8pfl+9//vvM7hc75nX2s0PWn24wXDUK74v2fkKBgGyxZskQv7aV9mDx5cnD//v32XeM7ePBg8Itf/KLna+nw9a9/PWgKUnbpltrz3FjMjh4cNGiQ52u2ddD1H4s5KQSnTZvm+dy2DK+88op95dbMAThoTvaez4s1eK1Pfa2NGzcGzQnP8zntHUwwFKyurrbv1pp+Hv1cXs/VQbcP3U5SSX8r3c693i9yGDhwYNAU6u0z06s9+8PevXuD5mTo+Twdom2/sda/OUkGTYHKGUwhNNi/f3/P5cKHePtsvM8ZbYjcHzLhuKOfyev5oSHWMWP37t1tWg/JDj/5yU/sO6aHvr7X+4aGZN4/Hcft0GAKgcHKykr7Tt7i/Z7pXpfh6uvrg3fffbfn50jVMSmZ42C04fTTT4957oi2D0Q7DugxRo81oeOOHoMil/Eaov02eu7Rc5DXc9o66OfWzx9PqvaN2tra4G233eb5GokO8X6ndB0vf/nLX0Z935UrVzrlD/hTRmRdi6RXdpYvX+5E/53daby99ArN3LlzY16tSjW9eqS1Z3qlLd30Cqi+TyramutrXXXVVU764FTTK0x6lTXTqqZjJSWIpFfEumLNZipofza9aquDNn3QK7yxaHMabRoaqy+T1uzpTVe7u+HDhzu1uO05RmnNmday+oXWZt93330pP27rdqnN2rpSrWxH9GtIpMYjFi0nmEAmpUla9Bijx5rQcSeRPrXasiBa02g992hLho44L6eLtrzQ36mt53vdn7Q2TGukOpI2pdOWMV61rHrs0u24q/T/RvIyLtDR5kvaFEWbpPihvaR2XNSmW+k4acaiBWLtlK/3HUo3bYKhTTFSQdeX/vYPPfRQytbX1Vdf7fTbydTCRaykBOHa0+G3O9HmFdq8I1azNaUnbW3KGG85v2vvBQbdT7Vpyqc+9Sk7p+vTdaL3TdG+OKm62KYFXL1419W2t47q16ABggYKydLtT8+v2uysM02bNi3uxTQ9Lz/88MNdOtjRIEUvIrWFHmO0+WFH035Y2oTOS7ru/4TMkRGBjp5IdAfQTGx6YtETgZ+iay28z549W/77v//baVfbHnrfkETbQ+t61ROr3qMo1v1G2ku/n16p0oAiFULrSztAa7vpttICr2Z40SBH77KfqfT3jHfi031Ca3QQm14o0e1Gr8gnQjMjaifgrl5z3F6hCwzaxy2ZY4WuNz1ma1DgN3oOmjJlirM9teeCka5PPQZr346uViPbkf0aNEDQQEEDhkTp9qd9TDuj8BwS+n01iUoiF9N0G9i0aZPTl6W9F/M0OUBHXkBVeqzQvlHJBDv6GbWvtZYT9PkdKRjsnPs/IXN0eKCjByY9QOqVGy2EasYUjba1sOG3ACecfi+9cv/iiy862WPidQCOpMvr+tJOiv/yL/9i58anJ4/bb7/dyZymVfvJFOi0479mTEvkSq0GEtr5UJuvJPIeeoCJ9VvrY3rlSK/C6GfQq32JHtC1dkQLbHoX/RkzZmT8QUxTkeq6jtUcoDtcddL7NGjNoGa1SmY71YKGPk/vP6SFjWSSTYQKs3oRIpHCrH6urpIpK1laANHaZ80+pesz1v6mj+ky2tlY15+ux3gpeuNl1spU2rRPUxfr9qXfOdFAUC+0aDM1Taihx+Cu2EJB7+UVLaW0JqiIdV+VttBAQfdhDRziHQP0ooZufxoYZWW1vSijF5q0OVUy5xilv68mo9Bza7K/r25Dum3s2rXLeW4yxztdVp+j963R+4jpPfs6mn5XzZqriSHi3dtQz236O2lw1Bnn4nTd/wldR0A76thxdLDDhw8790rRjC8Hw24wprQwpZnPzjzzTKfglqr7pmjaaM3kpll09ApHZOFEs7Zpdjc9iLf1PTVLltbOaUaY8O+l30nveaJtuvWEFivQ8aJZaDQDlL623owvnKbz1AKJDnoSSfa1O5tmkNOCdrRMTZoBLFYGP7/RLEOahVD3D70YErl/aHCoF0Y0w5Gm6U5F8KGHQk0bq4UPLZyG7xtaSNf30sGvgU4kvZqvmSG1IBfKfKffffTo0U7mpchmlHqhQwMlLxrEa3riePft6Qp0Xfz5z392tsvIe11pQVm3ET2OahDQngJ4Z9N+Ddp3S6/ER9J9TwvZ6bzvSLTziL63ZmlryzkkHn1PvdeLXnz1yviov68W7PU8c+qpp6bs9413XtbjjwY4ul2l8n1TQT+77g/6O4Wfl/Uzax9l/duZn1drUqP1/1q7dq3TfBn+RqADdLJYBQqlV530ni6pSPgApEO8bVj7T2iNdGdcfUbbaKFba0u8mvzcdtttTj84mvwgk+n9n7QmSZvXRtKWH9qEUC/swt+67uUmwCdidZRUmhks1U1EgFTSmtZY27DWEJNIo+vQ65/0a0BXl+77P6FrINABOlGsAoXSWhw9IHe1pnjoPvSqqTZbi7YNK00qkqrmt0g/+jWgq9Pmf3rDc68bb+t5VfsOaRNo+B+BDtCJtJ2/NkuLRq+cxuvsCbSH9kPQ9vXa/CxZ+hxtrqbJP6LRJiIdfd8MtE95eXnUJASkuUdX0BH3f0LXQKADpFlkh9YQ7fS6YMECp8O3F73qpFnjuBKOdNIrn5qCXTP7aRalI0eO2Edi279/v9x4441OxqpYNPV0Mpnw0Lm0hk4TR3jRoFWzhwKZrqPu/4TMRzICIM00dbpmD9Kqcu2MXVdX56QZ/8lPfiLvvPOOXao1va/JvffeS1t4pJVmM9R0tdr8TGnWQk1nr4M2UdIgJZQ16a9//auThU2bhOgQLUtgyJe//GXndTP1Zr1oTbNo6e+qmQ8jaQryvn370pQWGU2LtXrBRrflSHos035mHX0/H3QeAh0gzfReC3ojvGTolVO92WtXu8Egup7IQCdVNB3uj3/8YyeZBgAAnYGma0CG0QKi3oyNIAddFUEOACATEOgAGUSr1O+77z4ZP368nQN0LXqTQL1JH0EOAKCzEegAGULvNfL44487nbdpA4+uRmtxVq1a5aRLJ/0wACATEOgAnUw7f2vmqpdfflkuvfRSghx0qPz8fJk/f77Tl0yD7WRoDeQ//dM/OXcY/8Mf/uD09SGbEQAgU5CMAEgzTdeqWde0IHjw4EE7VyQvL0/GjBkjo0aNonCIjKCng6qqKtm3b5+89dZb8u6779pHmul2e84558iZZ57pZGQj/TkAIFMR6AAAAADwHZquAQAAAPAdAh0AAAAAvkOgAwAAAMB3CHQAAAAA+A6BDgAAAADfIdABAAAA4DsEOgAAAAB8h0AHAAAAgO8Q6AAAAADwHQIdAAAAAL5DoAMAAADAdwh0AAAAAPgOgQ4AAAAA3yHQAQAAAOA7BDoAAAAAfIdABwAAAIDvEOgAAAAA8B0CHQAAAAC+Q6ADAAAAwHcIdAAAAAD4DoEOAAAAAN8h0AEAAADgOwQ6AAAAAHyHQAcAAACA7xDoAAAAAPAdAh0AAAAAvkOgAwAAAMB3CHQAAAAA+A6BDgAAAADfIdABAAAA4DsEOgAAAAB8h0AHAAAAgO8EgoYdj2rNmjV2DAAAAAAyX0KBzq9//WsZOXKknQIAAACAzJZQoAMAAAAAXQl9dAAAAAD4DoEOAAAAAN8h0AEAAADgOwQ6AAAAAHyHQAcAAACA7xDoAAAAAPAdAh0AAAAAvkOgAwAAAMB3CHQAAAAA+A6BDgAAAADfIdABAAAA4DsEOgAAAAB8h0AHAAAAgO8Q6AAAAADwHQIdAAAAAL5DoAMAAADAdwh0AAAAAPgOgQ4AAAAA3yHQAQAAAOA7BDoAAAAAfIdABwAAAIDvEOgAAAAA8B0CHQAAAAC+Q6ADAAAAwHcIdAAAAAD4DoEOAAAAAN8h0AEAAADgOwQ6AAAAAHyHQAcAAACA7xDoAAAAAPAdAh0AAAAAvkOgk4CqrYclEDgkAxcek1o7DwAAAEDmItCJq1Y2r2l0xuZeVSD5zhgAAACATEagE8+uk7J6m/l7SY5MGcXqAgAAALoCSu4x1UvZ4w2y04xNmp4rQ9yZAAAAADIcgU4sB2ulZJmOZMmsK2i0BgAAAHQVBDoxVDxVL+vM36IFOTJpgDsPAAAAQObLyEBnwYIFMnjwYAkEAs5fne54x2XLg0FnjCQEAAAAQNcSCBp2PCNcdNFF8tJLL9mpZuPHj5cXX3zRTqVf7QuHZUhxo1ROzJG3S/vQPwcAAADoQjKqRkdrbryCHKXzO65m54SUbjBBjhmbdUMeQQ4AAADQxWRUjY42U3vnnXfsVGuDBg2S/fv326k02ndULhtWL6VFWfJ8xSlSTLs1AAAAoEvJqBqdWEGOivd4ajTKzq0myDFjo+/IJcgBAAAAuqCMCnS0xiaWeI+nRG2NbF6lIwGZPbmnMwsAAABA15JRgc706dPtmLd4j6dC1bZ6uVc751ybI1OHuvMAAAAAdC1kXWuhVtZNqpHrt4ncVdZHlk7IsfMBAAAAdCUZdx8dDWbmz5/f1ExN/+p0h6SW3nVSVpsgR0Zly1SCHAAAAKDLyrganc5TL2ULj8rFy0Qm/bBAnrmWLAQAAABAV5VxNTppV31cVl9XJRdfd0R2Vtt5qqpWtpggR1fJrCsIcgAAAICurNsFOpVPnZRb1gelbH2DzFpTY+eaOOeFBllt/hYtyJFJA9x5AAAAALqmbhfoFA7LkrF2/MLh2XasVjavaXTG5l5VINTnAAAAAF1bN+yj0yi1VfUmtMmSwkKbcGDXETlvdIPsvCRH3v5FHxnizgUAAADQRXW/PjrmK+cX5jUHOZqE4HET5JixSdNzCXIAAAAAH+iGgU6Eg7VSQhICAAAAwFdIL11fJ1XVugrCmrIBAAAA6NIIdAAAAAD4Dk3XAAAAAPgOgQ4AAAAA3yHQAQAAAOA7BDoAAAAAfIdABwAAAIDvEOgAAAAA8B0CHQAAAAC+Q6ADAAAAwHcIdAAAAAD4DoFOO1RtPSyBwCEZuPCY1Np5AAAAADofgU6b1crmNY3O2NyrCiTfGQMAAACQCQh02mrXSVm9zfy9JEemjGI1AgAAAJmEEnqb1EvZ4w2y04xNmp4rQ9yZAAAAADIEgU5bHKyVkmU6kiWzrqDRGgAAAJBpCHTaoOKpelln/hYtyJFJA9x5AAAAADJHRgY6CxYskMGDB0sgEHD+6nTmOC5bHgw6YyQhAAAAADJTIGjY8Yxw0UUXyUsvvWSnmo0fP15efPFFO9V5al84LEOKG6VyYo68XdqH/jkAAABABsqoGh2tufEKcpTO7/yanRNSusEEOWZs1g15BDkAAABAhsqoGh1tpvbOO+/YqdYGDRok+/fvt1OdYN9RuWxYvZQWZcnzFadIMe3WAAAAgIyUUTU6sYIcFe/x9GqUnVtNkGPGRt+RS5ADAAAAZLCMCnS0xiaWeI+nVW2NbF6lIwGZPbmnMwsAAABAZsqoQGf69Ol2zFu8x9Opalu93Kudc67NkalD3XkAAAAAMhNZ1xJSK+sm1cj120TuKusjSyfk2PkAAAAAMlHG3UdHg5n58+c3NVPTvzrdqamld52U1SbIkVHZMpUgBwAAAMh4GVejk3nqpWzhUbl4mcikHxbIM9eShQAAAADIdBlXo5N21cdl9XVVcvF1R2RntZ2nos2vqpUtJsjRVTXrCoIcAAAAoCvodjU6lZuqZOAM9yuPXpUvr99e4IxHm1+19bD0m9IoRQvypOK+XkKoAwAAAGS+blejUzgsS8ba8QuHZ9uxaPNrZfOaRmds7lUFBDkAAABAF9EN++g0Sm1VvQlhsqSwMDyxgMf8XUfkvNENsvOSHHn7F31kiDsXAAAAQIbrfn10zFfOL8yLCHJU5Px6KXvcBDlmbNL0XIIcAAAAoAvphoFOgg7WSglJCAAAAIAuifTS0dTXSVW1rprIJm4AAAAAMh2BDgAAAADfoekaAAAAAN8h0AEAAADgOwQ6AAAAAHyHQAcAAACA7xDoAAAAAPAdAh0AAAAAvkOgAwAAAMB3CHQAAAAA+E43DHRqpeSqQxIIHJKpm2rtPH8pv8f9foF7jts5IcflXp1vhnt32FkAAACAD1GjgzQ5LitHa1BVJev22VkAAABAByHQQVrUvlAnK3aZkWtzZOpQdx4AAADQUQh0kAYnpHRDo1SasTnT86XQnQkAAAB0GAIdpN6+k7JuvflblCWTxuW48wAAAIAORKCDFGuUnVvrpdSMjb4jV4rz3bkAAABARyLQUVU1Urr+sFz/hSq52AxTbz4iJTtO2AcjVB2XdcuPyMrlR6W8ys6L1LTMESmN6IhfteOoM3/l+uPiPL3+hJRvOiK3XJXAe4erPC4lD7X8zFt2JfC8uBqlal+1rFt8WKba175+3lEp3Zvga9fWyOZVOhKQ2ZN7OrMAAACAjpaRgc6CBQtk8ODBEggEnL86nS61O47IxSNq5bLrGmXdc0EpM8OWRxtk5tjjcuFt1VJhl2tS3SCl8xpkrhkqqu28SGHL7Dxo51m1Fe78udsa5ND+arllnHmfGQ2y+omW733xsuPinfzavO+mw3L2wBMy87aWn3nqaPd5h+ySyTshZYuPyIhhdXL9PY2yxb72uuX1ctmIKOsjQtW2erlXO+eQhAAAAACdKOMCnYsuukjuv/9+eeedd5xp/avTOj/l9pyUWZMbRKbnyPN7esqhQ73kUEUPWXt7QIrMw+UP1cnMqAFHO9U3ysrpdVJ6VrY8Y9/7wJ5cWXqF+3DZwpOyelejOxGm8omjJjBqdAKOsdc2Pzf0uXcvPCGLtrjLJqdOyu+pkYvvCUplUUCWlubLAX3dQz1ld2m2TDIrxFkf366xy3uplc1r3M9819UkIQAAAEDnyahAR2tuXnrpJTvVks5Pdc3OlnsapGpeD3lmVR8pHt5DCgvzpHBwT5m1qpdsWRJwlilfaIKRiFqZlNjaKJvH5crrj/eVSfa9i4b3lrtKcmWORlkSlI0vRDQXq66WFbeZQMSMjl3SQ8p+2Pxc93P3le2PBWSnpnVOUu1zx2XK4qAZC8jG8r5y18QCKdLXLewhIyb2lc1PZMlo82j5HSdlS7T1scsEZ9vM31HZMnUCSQgAAADQeTIq0Nm0aZMd8xbv8aSZAvnS23tK6/7yuTL2phyZ5YybgCQy4EiJgCy9sXfrWo/ePWXqDe7ozvJ6J6gJqXyqXlbqjKKsKJ87S4ZcnScrRtnJhNXKljVuOujRD+TJjMGtN4v8z+bJTOd1G6Ws/KQzr6V6KXu8QXaasUm35TlBEQAAANBZMirQCTVXiybe48kquioneoF8QI4UT3NHS/Y2uCOpNCpLzvPsw2KClRFubVJL9bJ7p9a4GFdny4W93dHW8uVC2/wtYVX1sv0Jd3TmJdESCARk4DB3bE+lx/o4WCsly3QkS2ZdQao1AAAAdK6MCnQGDRpkx7zFezxZF3rUXDTLlyHn2tF0GGYCBzuamHqp3O+OTTk3x6M2J8R8p1w7mqiqoBywo3NHH5JAwGuokZk2GCqrtAFXmIqn6mWd+Vu0IEcmDXDnAQAAAJ0lowKd6dOn2zFv8R5PrUbtn59BGqXCBhqS6u4vJnAJ5S8YMSEgxZfEGVq1tzsuWx50g5+5VxXECMIAAACAjpFRgc6yZctk/Pjxdqolna+Pd5yTUrHXHSuKFljU278dIkuGTHbHqqpb16g0q5eao3Y0UWcGZIozEpA5PyiU538RZ7i1ZfO22hfqZIUmQJiYI1NGZdQmBQAAgG4q40qlL774osyfP7+pmZr+1Wmdn2rb97VO39wkrN/K1HPCIp3eoSZnQakIzxQQ7qB5zI6mTpYUOtnYRMp2Nrg3G/VUJzufs6OJGhCQIc5IUHbu8Uo0EMsJKd3gJjKYdUOefR0AAACgc2Xk5Xetudm/f78Eg0Hnb7pqciofqZMyz5t+ajOxelntjGdJ8dg8Z8xRmCUDmwIOr3vKNJpAw80+llp5ct44m6Tg0XrZHCVIq33upFu7koz8PCm+yR1dveFEckHavpOybr35W5QlMyb2cOcBAAAAnax7tzOqbJSZNx+VPVXhQUODVG47KjNvdJuHjV2VJ1NadK7Pk7HXumNlS05Iyf7wDGSNUvXcUZk9z06mWNEVOU332Ln+6qNSdjD8c5v3fvOozLrGzLOBWOJMoHNdtozVURPgzVxYLZWtmuU1SNWuozL30eN22rXzqXopNX9H35ErxXTOAQAAQIbo1oHOlLuzpfi5ehk54rBcfN1hWbn4sEwde0QGTmqUcvN40dU5svH2AnfhJjlSfGOOzNBgojIoM4cckQuvOiyLlh+W68celn5faJTzVmXbPi8p1ru3LN1qA5IdjXLxaYeb37v4sIw4t14qbu4h6252lk5K/qcKZPWqgBMjlS+rk4FnHZLLbj4iK5cfkUU3V8mFw45Iv9H1srLFzUKPS9lj+jcgsydHS0sNAAAAdLzuXaMzIk82lufKnBEiZesbZe49jbJlh5lvSvszHsiTnT/s493nZHAfWbctW2ac406WP9Eo985rlHUHAzLnZwXy8DSv++CkRv4FvaX0Nx7vvUek2Hzm0rt7Sj/3oSTlyujb+8jOMvvalSKljzbI3HkNcu+jQSnfJzLppmx5/obm5mlNSQiuzZGpnvcEAgAAADpHIKgdYbq9BqmtqpeKvQ2SPzxHBvbOk/yEUjiHPy9XBhbmdmBq5eb3lsE5MmRAop85EY3Oa1dVmteXbBlRlCX5rb7bCdly3XGZul5kzi/6yIpLUp3zGgAAAGg7Ah20zb6jctmweik1QdDzFafQPwcAAAAZpXs3XUMbNcrOrSQhAAAAQOaiRgdt4DZtqzVj+Qk38wMAAAA6DoEOAAAAAN+h6RoAAAAA3yHQAQAAAOA7BDoAAAAAfIdABwAAAIDvEOgAAAAA8B0CHQAAAAC+Q6ADAAAAwHcIdAAAAAD4DoFO0uql4onDMvWqw1Kyt87O69oqN1VJIHBIAlcdlUo7DwAAAOjKCHSSVVkji65qlC1PNMrMxbUEBgAAAEAGItBJVlGOnHeBOzp2dLYUuqMR6qVqb41U1trJVKiulZ17T9gJAAAAALEQ6CStQOa83FsOHeot2xf0lHw7t8lvj8jIgUel34gTUnbQzmuXE1J64yEJ9KmR855osPMAAAAAxEKg0xY5uVJYmGsnItSL7Elpe7agVFXZUQAAAAAJIdABAAAA4DuBoGHHu5+qGindWiel2xplT5VI4dAsmTSth8ya0EOqdhyVdS+bVTMgR2Zd2zOsL85JKV9fK9sPmuXH5cusC/KcuRVPHZEte3WkUeY+6q7SGQuy5bx+zmiLZRNSdVzWramXKgnK6yWNUrLLzJuYJSsmBNzHTYw65c7eMsROuRqlap/5TtvqpeypoFTorMKAjB2XJZdNLpCxZ+Y4S0XSrGsDZ5jPPC1HDjzeR4rsfFed7NxQI2W2lmrIFT1lyvDw12mQyh3HZfOWBtmin9EYcUm2zJwe5f32VcvKrY1mJPT5T0rFthOy+okG2fmemX1mQGZMy5OpEwui9H8CAAAA4svIQGfBggWyadMmeeedd2TQoEEyffp0WbZsmX00FUxA8NxRmXpNY1MBPtzYW3Nl5fn1cuE1XoX/Wim5qkZmPiEypaRANk93e+mU33NILlzsjHoKXzYh75nPd1a9bLGTrWXL9mBfGWunpLpG1t1WK9evt9MeJq3qIRtvDw/aXNEDnUap2HRELjSP6WqaYb7DxvDvEOc99f02m/dr8a13HJHAWO1rZD7/0RzZPuOEzH3KfSjckGtz5Pkf9okI5AAAAIDEZFzTtYsuukjuv/9+J8hR+lendX6q1P62WiZ9wQ1yiq7Iko3lBXLoUC85dCBfnnkgIJUP1cnsVcnFfyOm5cnzZWZ4JLRKA3LX43aeGRaN865NiWpArixynpsrd11i591gCv/29XT+CDvbCb5utgFHUUDm/DBPdh8w30e/U4UJbhYEnOCl9I4TMume42bpxNTuqJaZNsjRoGVdi0At7D0vyJK1oXV4qEC2/zDLCcD0/eY+FS1TXFA2zjshK6rDnms+69pb3RqrivX1sjLqcwEAAIA4tEYnU8yfP1+ji6iDPt5+x4MrLvjQvN6HwaKrjwTftnObNQQPlVUFR5vHdRmZdiR4wD7iqglunOY+NqWkxs4LU37YfZ4cCm58185rl+b3kyXH7LxwDcG3f3DIfbzIvGdFvZ0fzixTcihYZD/X2rca7HzXAfNY5HetMd+juMh937HmfVt+07D3HFUV3H7Uzm5iHn8s9Pjh4Ot2rqNp/Zhh4uHg7jo7v8nx4NqJ9vGbjgYP2bkAAABAMjKqRkebq8US7/GE7KiTFTt0JCBLF/fyaBqVJYUT8mXRtXYy49VKyWITFxiTlvSQGYOznfGWsmTI9DyZO0rHg7I6Xk3J/qMya3KDU+M1dkmelN4dmUa7+T1nLc6Xsb2d0TDm/a7Ikdk6usu8ju27E+muO3vKiFYVXQVSPN32Q3q0Ufa4YwAAAEBSMirQCTVXiybe44moeKPRaYoll2RL8dBoX7+HjG7q9J/hdtXLZucLBWTKhAJnlreeUnyNO7bz5Xo3UYGX6uNy7/R6KTGvqf1kNt7dq3VSgKb3zDLv2cOZ1Uphlgy0owc+qLdj4bLkwtHezfmGDMu4FpUAAADoYjKqRKmJB2KJ93giKivdmgjtVxKro3tBkl1qOk11UHY6IwEZOdQZiWpgkQ3etrr9blqpapSlM07Ioh0iRVfHSAbQ9J6Nclm/QxIIeA3mdZxlTHB50CvQCUg/0qoBAAAgTTIq0NHsarHEezy+Wql4w47mdpEamzgq37WBmwkc2u2DoFR8YMdjaH5PkbGXBKQ4zjCktz/WNQAAALqOjAp0NIX0+PHj7VRLOr/9KabzZMhwO3q0MWb2sZpqO5LhioaEfsKgHKqyo1HUhCpWTPDR8l451rBseXhTjswwD1ZuqJeLrzvq2cSt+T2zZOnPCuX5X8QeVlwRpXkbAAAAkCYZFeioF198UebPn9/UTE3/6rTOb78sybc38JTnYnV0Pyl7djbXWmS0MwMyxRlplJ179Uac0dRLxRv2O40KNPWfiVQwuI+s25rtpIfWFM8z7zkmreKnAQEpdkb0PZ0RAAAAIKNkXKCjtOZm//79mvra+ZvKm4WOHpvt1mbsapCNz9U581rZd0JWP2rHM92ZuTJpojv68CPHoicZ2F8jq5e7o3dNzI/IotZS/gW9ZePP3HvhlC8+2freO0NzZJKTwU1k45ZjMWvGAAAAgM6QkYFOWl2QK0ttYLDymmOybm9EsFNZLYuurpfXPdt2JaAoVMMSlNf3RAmkkhLW3K68wSOQyZeZS9waGG1uNnNhtVRG9v0/eEzuva5etphRTTJwy4R4mRY0PXQf2VjiNnErX3xCpn47PNgpMO/jPrbznpMya01N61ofqZfKF47IvVsJgwAAANDxul+gYwrpsx5x+6FIZVCuH1EtI790WBYtPyK3fOmQDBxYJ+uG5ciWB9rYgX5wcw3Lyi9Uy4XXmde+uUquf6KtBf4sGT0hy62F2lYvF55bJbcsPizXjz0i5c7jJtT5VO/moGRZnQw865BcbN535XKz3Beq5OzTTsqiF0yQMyFbtjzSx32tuPTeO71kyxJ3PZTecUJmbWr+DkXT8mXdre5jJTfWSr9h5jvOO2Le84jMva5KRg48KgOLG+R14hwAAAB0gm4Y6BiD+8jG8lyZYwOSPU81yr3zGmT1UyLn3Zkr2zWtcpvTS+c7gdQsm+q5fL157UeDUtOOrGj5E3rKlvvcQKbyzaCsvqdR1u3XdwrRoKSv7Hkjx/1OlSJl5n3nzjPLPReUCvPEGQ/kyc5f9PW4uWcsuTL27nx5JhTQzKiRmU3BTr5MerCn7C7Jkkn6XfcFZd3yBvOeDbJyfdDp/zRjidae5TlLAwAAAB0pENSOMN1Wo9RW1cuB/fVSW5QjAwtzpDDfjf12Ljsk5y00IzflyqFHere+aWZc9VJVFUoOkCWF5rXbrfqkmI/ryO+dJ/nRXlKXO1gvr1dlyXmDsyW/MDdmn5z2azDrscGsxzqpMu81pDBgvm+ufQwAAADoeN080ImmVtZNqpHrt4kU/yBfnr+hwM4HAAAA0BV0z6ZrcdS+ckJWmyBHTTqfIAcAAADoarphoHNCSr99RMr2e2VEa5CqXUdl1rRG2Wmmim7KlVk2jTIAAACArqMbNl2rlZKramTmEyaQOScgF47LkguHmNkfNErptqCUveku5WQo+1mynfdjcfuxJJaELNAB/WoAAAAA/+qGgU697Fx/TBbdZwKbfXZWuKEBmX1briy6qZcUpSB/QLPjcm/ghCyyU7EFZOO7hTLjTDsJAAAAICndOBlBKONanVQcMpP9sp0MZenLFnZC9rxg3s9OxRaQkWN7ShFVOgAAAECbkHUNAAAAgO+QdQ0AAACA7xDoAAAAAPAdAh0AAAAAvkOgAwAAAMB3CHQAAAAA+A6BDmLbcUQCgUNmOCLldhYAAACQ6Qh00AkaZedyDZ4OyWXra+08AAAAIHUIdLq9Bqndf1z2HLSTHaG2Rjav0pEsmXUFd0UFAABA6hHodGeV1XL9sCNSMOSEbNln53WAqm31cm+lGbkzWyYNcOcBAAAAqUSg053VB+VQBwY4rlrZvKbRGbtrYr5QnwMAAIB0INBBx9p1UlZvM39HZcvUCTnuPAAAACDFAkHDjncTJ6V8fa1sPyhSOC5fZl2QI1X7jsvmH9RLyS7zcGFAplybJzMnFkih+wSRqhop3XpStmwKSoWZHGIK6TPu6CnFRdnu42p/tax8wq2pGHFFb5k0PFoMeULK15yQ7VUi+Z/qIbMn9DDzaqV0+UnZY8ZGTO4rk4aakcrjUrKhTjY/FxSzqPOeU27sYR7LM1Ne6qVyV608s6VBSne4z9HvMmlyrsyc1lOKwmKKqh1HZd3L5mc/1CgblwVlp5k36aZsKR7iPi7D82ROqO+MZl0b22BGsmV7sK+MNeuvYtsJWf1Eg+x8z8w+MyAzpuXJ1PD1FVW9lC08KhcvM+/3wwJ55lrqcwAAAJAeGRnoLFiwQDZt2iTvvPOODBo0SKZPny7LlpnScUrUSslVNTLzCZEpJQWywkxfOCMo2mUk3JBrc+T5H/aRgaagf9nkBimLXEACsrS8l9x1Qa6dPi4rR5+QuSZYKlrSQw7c3dPOj7DvqFw2rF5KzfPXvlUoszSoMc+9N3BCFpmxpeWnyIx3TTBwVaMTVEUqvq+HPLOgZ8smX1XVMvf8OlkZrRna0CwTMPWRKYPd4KtyU5UMNN85KvP5g6HPHx7oHM2R7TPMd3zKfShc0dXmscf6SChW8nSwWq4/rU7Wifk8H5wiU+ifAwAAgDTJuKZrF110kdx///1OkKP0r07r/FSr2lYrM+8QuaU0Xw4c6iWHKnrI2lsDzmMV6+vl3oeOylwT5Ow+P1uerzCPm2XeLs+R2RfoEkFZNPm4lDVlR+4pU25zn1v5SH3Ue85UvNxgghxjWrZc5gQ5LR14rlpmmiBn9AO58rp9zwN7cmXFNPfxsoUnZNYTESmZq4NSYYIcrZXZvLPAeY77WbNlRpF5fF+jzH7guFvLYxSOy5Pny8zweLYU23mzHrHzdDCfrbWgbJx3QlZUZ8nacvseYeurcoNZX1tPOOPRVDxVb4IcExQtyCEJAQAAANJLa3Qyxfz587WaIeqgj7dfTXDjtA/N6+lwKLi0/KSdHxL+uBkmHgm+bR9psvNwcLR9fGl5g51pvHskOMXOv6uszs4Mdzy49hL38Vlbau08dSy41D5Phzml4Y+FmM91tV1m1OHg63au49Dx4OsV9XaipZpfVAWLnNetCj5zyM4MCfu8S8vtvEjlh5s+l1xwOLj9qJ3fxHynifbxq48ED9i5rR0LrhjlLrdiZ9g6AwAAANIgo2p0tLlaLPEeT9q1WjsTanoWki/Fk91aCnXXnQWtm2ONypGpWlNivF5x0h1RZ+bJzGvd0XXPnZBWt8LcVSernzN/i7JkxkTtm+Ph2lxZ5PlYvsxYaGtgdjVI6W+dma7CAhk92KsWxjzr/GyZ6ow1ys52Zli7676eMra3nWhSIMXT7fra4PZh8lL7Qp2s0D5QE3NkyihyYAAAACC9MqrEGWquFk28x5NVPDbbswN90ZDQasmSC0d7ZQbLkiHj7GgLPWTS1VmiMVDl+nrZ3iLSMYHGcw1Ox//Rd+RKcZR++DMm5kbv1D88p6mp2etvtQqjmtXWSVVVrex84Zhs2drQHHzU279tEm1diAwZFm8zOiGlGxqdflCzbsiL3Y8HAAAASIGMCnQ08UAs8R5PVmHv5pobbwHpFz+VWAv5E3Jl7igzUtkopS+HRxa1UrrKHZt5SZREBcbIs6LU9DhMgGX76rTUKFX7qmX1zVUycuAhCRRUS79+NXJe8UmZep35HHap9kl+XTTZd1LWrTd/Y9VkAQAAACmUUYGOZleLJd7jmaGnFF/jjq18rrap+Zo23XpYqzScplvuvDZpVSvTKBVPHJXzhtXJLY8GZY8J3qbclC0rHsiRzWV58npFrtxll+wcjbJzq2aZi12TBQAAAKRSRgU6mkJ6/PjxdqolnZ+6FNPpNfqKHJmkI8sbpMxJdVYv259LRdMtE9Rsdcfyc2xt1HvHZK5NRT3jsQIJvlUomx/pK3Pu7CNTJvSS0YOzpMBdsnPU1shmpyYrILMnR6/JAgAAAFIpowId9eKLL8r8+fObmqnpX53W+V3G0DyZ5SQl0OZrJ0WqamWLE6PFb7r1ekWMvje76mWzHT1vmPs6leUNskVHRmXL3Ks9qksqG2S3He0MVdvq5V6N8K7Nkake6bQBAACAdMi4QEdpzc3+/fs19bXzt6vU5DTrIZOmu6t29baTsueFBlltxvX+MRfGabq1ZUNdlMxldVJW4iYz0KCmONT8LdSU7bSARxKDRql4rkFK7FTHq5XNaxqdsbtMENbWLj4AAABAsjIy0PGD/HE5cpemX3u0XhZtcgv7c68qkLhdVLbVy8yF1VLZoi+OCZbWHJOZy92p2Ut6yGh3VAoH2CZsGtDsqHPHHY1S9Uq1XD8vaKc9nJklI+zo9jdq7FgK7TppAj3z1wRmUyd4Z2wDAAAA0oFAJ13yC2TqHToSlC1PmD8J3j9m9pJskWV1MnBElUy9+YisnFclF597TEbeGHT6+Iw1Qc6KK5qbv+WPy5WlF+hYUBaNrZYLrzssK5cfkVu+dFhGjGuQolUm4HKW9NJDihe4Y6U31spI85xF5v0uXH7cndkuzem0J92W1xSYAQAAAB2BQCdtsmT0ZJuUwJhydW5CSQgGXtJbSn+TLVM0QHq0QeYuD0rZm+aBoQGZU5IvZXf3bFkrlN9T7nrKBDsT3cny9Y0yd16DrP5NQGZuKZCN07NjJCPIkeKFPWTpBHdqz1ONcq95v4p23W/HakpCkCWzriDVGgAAADpWIKgdYZAeu47IeaO1ViNLNn9wikwZYOe3clzuDZyQRWZsaXk/ucupoWmQ2qo62bM3KAOH50hhYW6cZm+NZvl6ObC/XmqLcmTIgDzJT7i1mL6XGZzxgPNe7VW19bD0m9Iocmeu1DzQO36TPQAAACCFqNFJm3ope9xtuqVJCCZFDXKiyZb8wnwZfUGBFMUNclSWWT5PhozqKSOKkglylL5XnglwdGh/kNMiCcHEfIIcAAAAdDgCnXQ5WCslNllcQkkI/IQkBAAAAOhkBDppcVLKHqyTdWas6KZcmZVAEgJfGV4gZYd6yaGXe5GEAAAAAJ2CQCdlTkjpHVUyd/FhuezcY3LxPWZWUUBWzuvZ/e4fk5/rNoPrnW1nAAAAAB2LQCdlglL1XlBW3tMopW+aGGdClmwu7yMzBrOKAQAAgI5G1rWUaZTa92pl+1tB6TckT0YMTiSBQEhz1rP83skmEgAAAAAQiUAHAAAAgO/QrgoAAACA7xDoAAAAAPAdAh0AAAAAvkOgAwAAAMB3CHQAAAAA+A6BTkc7eFxWXlcl1y8/JlV2FgAAAIDUIr10B9u57JCct9AdX1reT+66wB0HAAAAkDrU6HSwIedkSZGOFAVkxJnOrMxVXSs7956wEylUe0L2vFnr3CAVAAAASAcCnQ5WeEUfqTjUSw5V9JUpGRvonJDSGw9JoE+NnPdEg52XGju/fUgGFhyXkUvqaLoHAACAtCHQ6XBZkl+YJ4X5mbzqg1KVpiiktlqk0o4DAAAA6UKgAwAAAMB3umEygpNSvr5Wth8UKRyXL7MuyBOpPC4lG+pk83NBpznViEuyZebVPWVsUbb7FE8NUrnjuGze0iBbdrlzRl+RI7PM80YUnpTS5Sdlj5k3YnJfmTTUfdyxr1pWbm00I1ky5c7eMsSda7T1c52Q8jUnZLsukG8ev7WX2weohbBlBufK7GkFku8+0FLVcVm3pt68V1BeL2mUEv1eE7NkxYSA+7j9zP1eOSrryt3NZvT0vlLs0QSvaodZ5mVdJksm3ZojFQ+566PihQZZvc2MjArIXTOypJ8uLAG58IY+MrbQmQAAAADaTwOdTDN//vzgoEGDtJTs/NXp1KkJbpz2oXntD4NTSmqCb/+sKjjWjOt0i6HoUHBp+Un7nAhHjwfXXuvxHPu8FTuPBpfa6aXl9jkh5YftsoeD2+0sV9s/V415zdCyc37R+jPXvFwVHO08fii4saLBzvXw7pHglND7eA72Mx89Flx6gTuv6M6j5pNHOFodvGuU+/iUx/RRs3yL14kczOd6130qAAAAkAoZ13Ttoosukvvvv1/eeecdZ1r/6rTOT7mXT8jMLzXKwAdyZfeBXnLoUE/ZXZotk7RKpDIoi26vkZ3ukmFqZcvNtXL9eh0PyKwHQ8/tJW+X58icEUGZe22dbHaWbaMkP1f+BQWy8m53fOXiyM9cI6vvbHTmTXksX2YMjvGTD8iVRWV58nxZrtx1iZ13Q46Z1nnu/BE6r3dPmbM8S0ab0crl9bJ6l9ZQhZj3WlMn92pt0LQcWXG11h1lyxT7Gg/f4Cwkckm2bG563TwpHmDnAwAAAKlgA56MoDU3+pGiDamp2WmuOdFhTukJO79ZzS+qgkX28RU77Uzr0M9Cj0Wp8amrCa4Ne/221OjokOznCh49GpxT5D6mNUKuhuDbjx1yX3PakeDbdm58YZ9lyTE7L9LJ4PN32mXMax+wc4MVoVoh79qj7Us8ngMAAACkWEbV6GzatMmOeYv3eNIm5sjsiXl2oln+JTkyy45v3xN+t5daKd3Q6GQNK7ozR+ZckOvODpeTL7MWZju1HW2W9OcyeveWRT9w79Gz5Y4TUlZtRg4el5XzTFwhAdn4QK+w/kCpkCvF83Jltr7hE/Wy4rk6M3JCSh+oly1mLG7tEQAAAJBGGVUSDTVXiybe48kabQIH78J/toycZkfD1dbL60+4ozMvyffu0K9GZcskO9oWSX8uq/CKfFl3kxmpbJRFa45J2YN1stpEZWkLOgb0lqU2uNImc+Uv1MqiR81EU5M1AAAAoHNkVKAzaNAgO+Yt3uPJGlIUyiaWoINBqXBGAnLesBxnzFtACuxYWyT9uZr0kEkLc2SGiTzK7zgpF99jZqU56Ci8ooesvtqM7GiQC4u1L1A6ao8AAACA5GRUoDN9+nQ75i3e42n3XtBpluWIFed0pjN7yMzJdtyYckVumoOOfCmeFrYZTc6WsTRZAwAAQCfLqBLpsmXLZPz48XaqJZ2vj3eqooBMsaM1EV1kWqhtlEN2tKPVvlLjNh8bKk6As2VerWx5z3koPaqPyYrFbta1IXq/oK31suiJWCsHAAAASL+Mu/T+4osvyvz585uaqelfndb5na4wIAOdkaCUv3HCGfO0t1HK7GiHqq6WRdPc5mNLN/WUjUvMvMqgzF541EmgkHp1UrbkpJNKeux9PeT1DW4ShpLb0hxcAQAAAHFkZBsjrbnZv3+/pr52/nZ6TU5IYY5caJMBrFtz0vbXiWQK/yUNEfey6QgnpHRenaw0Ec3ou3Nlzqd6yNib3KxolRvqZU4aalmqnjouM5ebkVFZsvLWnlJ4QQ9Z6iRDSGdwBQAAAMRHZ4qk5MuUG9wsY7KtXmYurJYqZ37ISdmz5pjM3CDuMh2o8okamaVN1oqyZOltvdyMcAN6y6IHA85naV3LUic7H6qSi79QJat3aWrocHkyZLgdLW/wDujeOyqzb3RTbc9eki9je+vM5mQI0YKrosE20cLLjbJbU2ADAAAAaUCgk6T8S3rKliVuYb18WZ30G1Yl1887IivnVcmFw47JyBtFbtmaK7c4S3SQ/Udlzm1BJ+iY8aAJNga4s1XRtB6ydKIZiaxlea/WBERBKXsuKLdcWxNRA5Uloyc0B3QXnlsltyw+LNePPSLlzuO1UrKwXkrMixVdnSOLrujhzHWc2UuW2vXj1YRtyFiberuyUS4e7a67W750mKZuAAAASCkCnaTlyti7e8rrDwZkhEYC+4KybnmDzF0elIr8gDz8m55y1wUduVpN0LHYDTo0lfTSaZGppAtk1n3ZMtaMtahlGZAt513gjhaNy2qVmS1/ggno7nNrgyrfDMrqexpl3X6t02qUik21MmeDLhWQlUt6RdRemde6oYes0Nf2asI2tJc8/Lh9P7vuVj8VzNwsdgAAAOiSAkHtCIO2qa+TqoP1sqfSBD2Ds6WwMNedX3lUZg40wYcZXbGzn8wZ5c7OOLXm85u4J9987qh32qk+KVX17mh+7zzJT1VA4ry33fTMixbmE3MDAAAgdQh00qD2hcMypFj7r2TJ8zWnSHH67tcJAAAAwAOX0VOuVrY86nbSl5uy5TyCHAAAAKDDEegk67dH5d6tx6Wq1r1JZgu1tVK6sFZmPqETAVlxY08pdB4AAAAA0JFoupasHUckMLbBGR17SUAuvCTLuYloxW8apfSJYFMq5lmPF8jaVokBAAAAAHQEAp1kvXdM7p13Uh7eJC2ziVkjpmfL0oX5MuWcPDsHAAAAQEcj0GmrUMa1PY1SIwEZOCJHBhaSPQwAAADIBAQ6AAAAAHyH6gcAAAAAvkOgAwAAAMB3CHQAAAAA+A6BDgAAAADfIdABAAAA4DsEOgAAAAB8p1sGOpWbqiQQONRqGHhulVz8hSq5ZflRKX+v3i7t4b2jMtXj+ZHD1E219gkx7DgiA+3yF6+psTNjK7+n9XvpcPZY9/PPNZ+/dO8JSeDdW77WddVSZecnqmJ92Lq86mjrm6imcl0BAAAACaJGJ0zlm0Epey4oq+fVy4VnHZXLvn08oWCh7eql7GcNTcFB2SN1stOOt0XFDvfzrzSf/7IRx2WICdxWvnDCPpqA9fWyeZ8dT8hx2fIgt2ECAABA5unegc7kHNl9qJccCg0H8mX7lmyZMtR9uPSOEzL3qViBQkDWvhH2/Ihh3eQ8u1wUB2ulZJk7OnqU+d+uBtn8QoyapEgLclu834E9PeT50hx5+M6AjChyA7e5xcfl4sXxa2qKzPIiJsjbetyZTkTtC3WyYpediKud6woAAABIQvcOdHJE+hXmSWFoKCqQsZP7yuadeXKXBh7G6kdPSoU76qkg/PmRQ37s1Vv1coOs05FpOTJ7ojNL1j2XWJMzR0FWi/crGt5Tiif2kdkPFMrud3vK8/cFROOXsnvqZNI9sWunLpycJaPN352r6qQsoQ9QKxuXNzq1UVOmBdxZcbRnXQEAAADJoHTppXcvmXWzLbxvcwvzqVcrm9c0OmNTJufKzEuynKCkclm9lB50ZrdPTg8pXtBXtpe4wU754ji1U+dnyUwN7iobpWRbAs3ddp2U1dvM36JsmXqFOwsAAADIFAQ6URT0tiPGoWR76CdiX50JKHTEBBiX5Ev+hFy5xWk+1iilLyfRryamLBkyvUDW3eROrTbBTrQ+QFvey5Ypt7nB3bo1sWuxnL5Fjzc4rzXpvjwZsp9+OgAAAMgsGRnoLFiwQAYPHiyBQMD5q9Mdq1EOvGcL76MCMrDQHU2dRtm51QQLOnptthQP0JF8mXSH/k0k0EhGD5l0TbZTq6N9gMpi9KkZckWOzNKRbfWyLlZfoaa+RVky64p8ZxYAAACQSTIu0Lnooovk/vvvl3feeceZ1r86rfM7zP5jsmKVOzr2mlyn70pq1Uqpff050/PFjaOyZPQl2e57bTMBSVLZz+IYlSUz7ej2PTE64AzIlxk2prx3Q22UBAYmSFtf5/QtKlqQI5OcIA0AAADILBkV6GjNzUsvvWSnWtL56a3ZaZDaqhOyZ9sRmXpJvZRUmoL8hGxZeUOBfdxLUJ555IisXO41VEetldFsZQ9rx5+iLJk0LsedqUblyuxLdCS57Gdx5WdJP6dKR2TLPrdfkLccKb7OBC86Gi3VdG2NbLZB2tyrCiTx+py2rSsAAACgLTIq0Nm0aZMd8xbv8aQ9Ud90s85A4IgU9DsuIyc1yJZqkRkP5MnOX/SVsWF9dbyULGuQufO8hmhJDE5I6Qb3saJrc+TCFpFCgRRPd/vJJJ79LBFZMmScHY1naJ7MulZHvIOtqm31cq9++Gk5MnNUcptP8usKAAAAaJuMCnRCzdWiifd4SgwPyNLHesrGO3tJUVhli7eA3PV4njxf5jXkygi7VAsH66R0vTt6y5da14gMuSRbpuhIZaOUlSdxT52YGqXiCXcs/nfqIZOudjPAtQ62amTdA26N0F03Fbj9fhLWhnUFAAAAtFFGBTqDBg2yY97iPZ60aTlyINhPgjocLXDvO7M3KIu+cFxmbkqsOmXk2F5SPMFrKLB9b1qqeKrevXeOKfgX1tRI2QvHWg5viYz4rLNAjH4ySapqlAN2tHhoth2LTjPAzfVINV37wklZscOMjMqWqRPiRkytJLuuAAAAgLbKqEBn+vTpdsxbvMfbpXe+FC/oJVuWuE3HSu6olZL9sfqztIUJbDaFUjEH5Zbik3Jxq6Fe7n3FLrK+QcpScE+d2t80yGpnLCDFo3s4Y7H1lJnzbKrpB0IpqZub3E26LS8NCRoAAACA1MmoQGfZsmUyfvx4O9WSztfH0ytXxt7dQ1ZcYEYrgzJn8bHU9h3ZVSern3NHR0wwQccl0YchzlKNsu6p9nbUqZUt9sakMjFbioe6o/EUTc6Vu7Rt2o4G2ayppvedlHXa5K4oS2aTUhoAAAAZLqMCHfXiiy/K/Pnzm5qp6V+d1vkdo0BmP5QtY81Y5YZ6WfpUqm7e2SjlT7k32ZRLcuSZskJ5/hfRht6y9k7nSVK6qa4dGckapGJDrcxx+ucEZOmSAhtAJSC/QKba+/rcu63WfPZ6KTXjo+/IJaU0AAAAMl7GBTpKa272798vwWDQ+Zv+mpyW8j9VIEttoLH6xlopq3bH26W2Rp55xB2dND03TsCRIxdOdBMCyHP1smVXG5rQ1Z+QsmVH5cJrgk6t1NgleTLnU8n0q8mS0ZNtqunldTL7MR0JyOzJPXUEAAAAyGgZGeh0vlwpnpcrszXSqGyUuQ8ck2gNyGqqTkpV1KHOLhWWltkEC1PGxW/6pQkBbrFpzVY8XuP9/jWNrd6zYle1lCw/LJeNOC4XL3SDnOL7ekjZ3T2TuOeNNTRf5tiAb+cu879rc2Rqgk3fvCS6rgAAAID2ItCJZkBPmfOAvafNPXWy8rdeqZ6Dcv25x6Rfv2hDjZQ7y52Qsqdsrcy0bLksoWAhXybZpmOV6+tlu1eks6yu1XuePbpOZs5rlFK92efQgKx4uac8v6ANQY7DBHwzspsSD9x1dX47sqMluq4AAACA9iPQiSpLhlxtExOYQvqiW4/b7GNtEOrIb0yZnJvg/WeyZPQlNsiISPMciyY5mHVnjmzeWSA1bxXKnM8mkmUthlF5Mnui+TsxR2a1IaU0AAAA0BkCQe0IAwAAAAA+Qo0OAAAAAN8h0AEAAADgOwQ6AAAAAHyHQAcAAACA7xDoAAAAAPAdAh0AAAAAvkOgAwAAAMB3CHQAAAAA+A6BDgAAAADfIdABAAAA4DsEOgAAAAB8h0AHAAAAgO8Q6CSkXiqeOCxTrzosJXvr7LxM0ii1VSelyhky8fMBAAAAHSsQNOw4oqk8KjMH1kuJjk/LkQOP95Ei54FOVFsr5VtPysZNDbL5KfMR7eyQIRcEZNKMHJk9vUBGDMi2cwEAAIDugRqdRBTlyHkXuKNjR2dLoTvaSU7Knk2H5eIhNXLhDBPkVARk6t3ZsnZLnjxfZobSHHn4gSwpLgjK5tvqZORpR2Tq8mNSWW+fDgAAAHQD1Ogkqr5OqqpFCgtz7YzOUCtbrquRqetN7DUhS1auypcZo3rYxzwcPC4l952UOd82P/GEbNmypbeMLSS2BQAAgP8R6HQZtVJyTY3M3CAydkGulN7XO8GapQap2FotM6c0SvkF2bL9ub4ytrd9CAAAAPApLu93CY1SsabWDXKW5HkEOaFkBHUmHIqULUMm95GNjwVEdjTI7G8f91gGAAAA8JduVKNTJzs31EiZ9tovzJFZN/SMWiNSteOorHvZrJacLJlye28ZIielfH2tbD9onjouX2ZdkGeXVLVSuvyk7DFjIyb3lUlDG6Ryx3ETWDRI6T4z88wsmXVjD5lxQVgTs8rjUrKhTjY/F5QqMznikhyZbT7PiGjNyt47KlPPqpctrWpkGqXqlWqZfVODlLxpZw0NyMNP5EjVxDpZNC48cUKNrJtUK9dvC8jatwpl1lBnJgAAAOBLGVmjs2DBAhk8eLAEAgHnr063X64M6R2UufMaZO6NdVJmghZvtbJ5Sb2z3Mb6LBPkqEap2GaeZ+aVVjQ6c5o1yk59TTPsPFgn5fcclYFjzfMfDUqZCWTK1jfIzLHH5eJlWpNiXueJw3L2wBMyc16jbNHHzbB6Xp2MHHFESvZHvrYyr7/JBDlmbNa8Hi2CnIpNR2TEOBPk1AZkaUmuPF+WKxuniSy91gRRGtANCEi+u7BRIFNv0J87KCUv1LizAAAAAJ/KuEDnoosukvvvv1/eeecdZ1r/6rTOb6/CidkyxxlrlNKXTzhjreyrky3bdCQgsyf3dGYl6vVHjsmU0oCsLS+QQ4d6yYE9ubL0CvexsoUnZOWaapl5VaMU3Zojrx/oZZbpKbtLs2WSVrlUBmXmzcekwl08TK2UrjJ/irJkxsSwWqH3jsncGUGpHJUlz/+mr9w1vbcUT+gtM+7rJVvMe+7UZQZmtai1KhydJVPM37KX61ulowYAAAD8JKMCHa25eemll+xUSzq/3TU7+fkyyb7EuqfqnGZjkSpeaJBSHbk2R6Ym2bxry3MiKzf1kVkX5EthYZ4UDe8td5XkyV2j3McX3dggFXfmStmDfWR0UZ5ZpoeMmNhXNj5if4ZtDVL+njvaZF+D29zu6my5sKl6plHK19tansX5UtyiyVuujB7nTo/uHXD+NhmcJSP07xtBOeDMAAAAAPwpowKdTZs22TFv8R6PL0eKr8qW0Tq63gQQrZqv1ciWR9wuS7OuyE36fjmj78iTGSaYaKF3gVym1SiOgCy9sXdYczJX4dgsmeGMBaUiMtCpbJQy86d4WHbY82ql7BH9G1HLY+X3cQOcIUURgY55/wL9s0tfAQAAAPCvjAp0Qs3Voon3eEJG5chMp4alUTY+F1Hc31UnG00Q0KqZWIKKR4UnKQjJkiFDbcAxKkvO86olKsqWkXY0UuW7buBVGF47816DvK61PJPNa0dGTUbVB+5zBvaO8vNeErAJCgAAAAB/yqhAZ9CgQXbMW7zHE9NTptzsBg1bttaF9VVplJ3PNTh9W0bfkSvFHgFEPP365NixKIYFZKAdTQnzdk4NTYRDlTbQOS0i8NpvAiT9awKvfs4MAAAAwJ8yKtCZPn26HfMW7/FEDZmQLZN05IkGKWtqKmY7/bchCUE6FZ3lBmUVNniJr1bKtnovW7Wz0enXM2VcTtLN8gAAAICuJKMCnWXLlsn48ePtVEs6Xx9PiaF5MutaHQk2NV+rfaFOHtbqnYnZUpxJ95gpypJi82fnWw3NyRPOzJbztO3ZE43OvX3C1b5yQrbYTAOHjta7I44aWfdAo/N6s69oQ3UVAAAA0IVkVKCjXnzxRZk/f35TMzX9q9M6P3V6SPEV7lcvfaJOKqRetj/X6DRjm3VDnr13ToYYagIvDWoebZDXm7oU5cukeVrT0yiz7zgqOw82mPF6qXzhiEydFpSZS9yECxs31EiFxjq1NbLlthMyd4fIjAfNd2+6Fw8AAADgTxkX6Citudm/f78Eg0Hnb8pqcsIUTsyRuzSA2NYgZW/WSqm+RRuTEKSXCWru0L+NsnprKNLJktG358vGq0UqN9TLeacdkUDgqAwsbpCBD+bLjCtyZfZk97Gzcw9JoKBWpj4UlFklBbJxGrU5AAAA8L+MDHQ6RH4PKbbN18pWNchGM9bWJATpZYKa6TkywwRlW+6olZL9jXa+CWge6yMHynPk4QeyZcUPc+X1A31lrRPIFMisx3vK61tyZIV57OGSPNn9gXlsOkEOAAAAuofuG+iE3VOnZL3bbG3mJRkaCJzZS5auCkhRZVBmTq+W8mo733yHogv6yOw7+8qca3vL6KJsO9/I6SGjJ/eROeax2dN7yYgBYY8BAAAAPteNAx2j6Z46xsQcmTIqU1dHlgwxwUqpBjs7GuTC0Ydl3Zsn7WNx1Gv/HQAAAKB7CQS1Iwy6iAap2Fot19/cKGWVIkMmZsnsq7OleGyeDAnPF11VL6/vaZCdTzXIuq1Zsu5AXxlrHwIAAAC6AwKdrqiqRkrXnJClPwhK+T47z0uRyKTJufLwI70zK5McAAAAkGYEOl1ag9RWnpSdexqlxs5xBWTI6FwZUphrpwEAAIDuhUAHAAAAgO9072QEAAAAAHyJQAcAAACA7xDoAAAAAPAdAh0AAAAAvkOgAwAAAMB3CHQAAAAA+A6BDgAAAADfIdABAAAA4DsEOgAAAAB8h0AHAAAAgO8Q6AAAAADwHQIdAAAAAL5DoAMAAADAdwh0AAAAAPgOgQ4AAAAA3yHQAQAAAOA7BDoAAAAAfIdABwAAAIDvEOgAAAAA8B0CHQAAAAC+Q6ADAAAAwHcIdAAAAAD4DoEOAAAAAN8h0AEAAADgOwQ6AAAAAHyHQAcAAACA7xDoAAAAAPAdAh0AAAAAvhMIGnY8qjVr1tgxAAAAAMh8CQU6v/71r2XkyJF2CgAAAAAyW0KBDgAAAAB0JfTRAQAAAOA7BDoAAAAAfIdABwAAAIDvEOgAAAAA8B0CHQAAAAC+Q6ADAAAAwHcIdAAAAAD4DoEOAAAAAN8h0AEAAADgOwQ6AAAAAHxG5P8DXriVETd7UEQAAAAASUVORK5CYII=" /> | ||
25 | </p> | ||
26 | <p>点击进入文件<code>nginx.txt</code>,我们要求看到文件的内容:</p> | ||
27 | <p><img | ||
28 | src="data:image/png;base64,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EREREREREREREVEbnT3EkYiIiIiIiIiIiIjoT8YANhERERERERERERGtSwxgExEREREREREREdG6xAA2EREREREREREREa1LDGATERERERERERER0brEADYRERERERERERERrUsMYBMRERERERERERHRusQANhERERERERERERGtSwxgExEREREREREREdG6xAA2EREREREREREREa1LDGATERERERERERER0brEADYRERERERERERERrUsMYBMRERERERERERHRusQANhERERERERERERGtSwxgExEREREREREREdG6xAA2EREREREREREREa1LDGATERERERERERER0brEADYRERERERERERERrUsMYBMRERERERERERHRusQANhERERERERERERGtSwxgExEREREREREREdG6xAA2EREREREREREREa1LDGATERERERERERER0brEADYRERERERERERERrUsMYBMRERERERERERHRusQANhERERERERERERGtSwxgExEREREREREREdG6tEERtNf0J8jdGEOgMISxwxYYNmoLO1S4G0TwTkGb68AzCfGcFVOXnTBqi+oUJKSf9sC8Ta8taCx3w4+Q3gXPrjziv/bAttugvdOhpzH4f+iF+wszWu+pe7kbo/D+aoPnCwdMm7WFnXheQEGnh75lOciIn3Uh+a4X7oOmNT/2l/LLJIbnTfB9Yoex8sA6SlczMtLfjiH2thvuA68ivVp+vifyU93+C7FoVcdZlsakMw7ThAv2NnWYiIiIiIiIiIjePOyB/YrkbocRz2kzlWQJkxdDSDzR5rug3+2C+zMPPF92MB00Qbo9jdh3wxg+m4SsbaPO8yR82/sxcr3RwVaQUxi7kUJhswlGyYOttjHEHmnvdaBwJwrv+TF4b7bZz2rIWQT/6O0ueK3aLCHoHEX4t6a5I+iwCWGkZF11MPdRBpnn2utKT9OI/9rFTYYK8l0/xq5J2lwHXsgI35Yg18ZtRT6kJoYx8m0cuVZJa0gH8zEPjNf6YPooirUvrVJ+xkX9Vw9b/mUSQ0f8iLbLMzmN6PUM6teSIV8bw/QNqcF7RERERERERET0pvsLBbALyMzHEbvmh//GKwiSdsmw14LciQ8weqNBQHK7FdYt2usu6ToJ0j6KYmTvIGLv+BBJ55E4bYFOe6vO20b0wwybpYMe1f/oKQYdjYeCCA0kMHo9XVreVhrBiVk4L4Ywtb/xfgq5DsKPam/dZv6m/VtFRuGp9rIhM1yHZAwP+BAvBnplSHfjiIt6VDmlHovje5BeWXZrWuRvH2xHg/VB7LfM6Lk9hMFv0tpNAxmZG5OY/LrdNIahA15MOofhv9tF1Fnfgx7t5Qo9bBPTcBW86DV+AO98t6FdI5ynAuj9QaT9FUWF9W+Vjlq324PQkSX4dgxh+rfiosZ0ZtjfiWLoX5NINzgm656179n/0p5mRH2JIXzWj+gqblj9FRV+U8+fMPxnX8XNEXp9Stff+HwUwTOjGPw6qS0nIiIiIiIienl/oSFEJMS+nsb0hUnoLmQROdTlEBevwpMwht7xQPdjGqGDpeNJnt0A6x8JKBOW4vyaexTG8N4geiem4D3UyRAQSfg3BGB8HIHzbW1RA7lrQ+h9OAbltHbczzOI3gbsB0zNg+Oa3PVhmD/MYXDCDlPDlbOIXwgBp2KIHDM32Z44zu0B5D+1oldbUpa/H4L/qRWBgZqBUvIphL7PYej6LMb/2eQoRRmNnNFh/IqjNMyKXIC8UQ9dxbAWapkFtlXUqac5FN4yNM/b53GMbR9Gz80sxt8X8y9kFF7ooK88hGLdkDCmjGPVNeGuHxsuGJH90Ym62l4cmkNC+MOtGH4QQCrtgbn0TocKSP+Sh/n9xoPPyPeiSOgdsK3iRoyan+7NKaS+KB9RAcnvIlh4DvR97IKlacbK4rNWWGNDSM2Pw6zmZzEfIxiSRP1d5U2hV+ZhDJOXphH4RofJNufX/wrp5iSmvwtgUjfZuN7SG0q9/kaREa+yd0T57oquXCuIiIiIiIiIXtIbF8BOf+WHfLJZ0C+H8Ie9iBx4VQHsHKJfxWE92XngJf11P+wvgsieLAXrkmc2wN1TGbxbA3IBBTXo+jCI0eMSHFd8sHec/IoAtiGHzN0FZP/Q3qpQmPdjKOfA3CFTcV7+NQjX53H0X4ghItLSJDxcHPt6dEcQ1mTzAGP6Gyv6fxxE4pYo16bBS/U4reIfBeO7tUWauuB6WTG4uYAxxddVkLjwMInU4yVtDshc+wBRQwTjA+Lg5AzCn49iYd8sQhftTcYWl5H8Zhr4xANLsx7zXQaw5d+imL5Z05tfimMsqce4s7+mF3Yemaioc44YQnvjGPrRjNlztpUyymWQzGSxksIuFZKYPOpFDE6EkqHlcpWfxBG6lm47lIc0P4ZpuKtvOGTjCHwTQ263r3U9eBrFyD8isGdDcKh1/JHIR2MCrvwU7E3rzuvU2Q2iv5Rf/PC/GK87T8uK5+uNoVcWwG59jXhDtcnT9aRpe0xERERERES0Sm9YAFsNUAdh/PF1BbCT8H8kwXW1i8DLUwmSzghjMZBZOr7Zg9nlHtl1nov1ZbH+W9p8J9Rg6MEgev7lQ+CkpcuhFFYCbPaNhdIQJZv1dQHp1QUlJIQ/GsHC4Qh8exsflTrus+3AAkYrAqGNlfJOOt5tAHsVvZxrekzX9cBeC6s4NrkgQ1fZjbtpD+w0/L1j0M/Pwf2utqhG3bYqFNO7ZRGRw43D86202m7ZywW4ZOQeyTBs0eqTmgcHgFR2vGkP88JDCbptxra/FHg1/vcC2Gr5Bo2R1xTAbneNeDO1y9P15OXObyIiIiIiIqJ6b9AY2AVkvvPAc12b/bO9yCF2ygNvu+GJ1d6t5bGS1em+BOnn8vwsEneATU8XVt6vmcITQ9i6YwjhLh6QWHRXQv4tfWfBazmH+HflsZdDSEDC7IUR2HtNcN3MVwf6Go47LaPQdmxkdbiHEczucaP3hhfT8/Uj3sr3JjF0YBaDN4Kvd/iH2jRurBnuoyEZmV8bjG+ukRvVk1ZjeHegXWB4hdh5To+eFuOlN99WDtkH4p+Nm0qzXerkGPVvGYFsvm1P7ZLacckTWJBSy/PR2wlgxxKk5fdrpluTcG3fClurB5m2IksIf9VgvOZcDMFX8UDSN1zh1yA8x6Pa3J/tNV8jXpHXm6dEREREREREr19XAezc/CRGLFuxYcMGbNg+iLFrmSZBoQLS349icLtYb0Mv+px+RH+rXLOA5PelB9eN/J8VW8+WHvhU+GUawzt6xWe2YuT6SnBQ7RG6YUMP+j4NIwcvrOr+i9MQws0ejpaLY9LZh16x3lb7KIL3mhzpTytp6t1RSlN1YE3t0Sf29bdeDH4ljvP6cHGbpf37UfeoKoMJZrMVtgFb/bR9E7I5J+wHGrynTZbtPcAnY6sI6Low9klpeI9a8m9hhCsfDKgzwHbYBfcXHni+HIYVRgwen0FCySJ0aBOinw5hTHu44JhjKz5Q060GHZdlENzX+uGA0jUvIjtnEPrEAff5YRRO9WLrmZUgYjF4vW8avRdDGN/daWBWbDddH6RMZMRxPF4Jai5PyYWGQVJ1OI7lhyceH0TvnlFEH8rI3Q6uLK+YQiL50q2pqmXeIzb07RiG/ydtD3IG0W+090+JPDUOYvrX0lslSfhNg/De+hOCnk8kpNAP4yp7/KrB935jk76xLxGEz/0mFctf93dRx3MF5EuL29DBuLMf1j2Nz5dekVLDwBAcDd4rTWZRux0YPVz/INPKc3/DditGToj6/u+VOlpsdzZtxXC64twptwe9g4jVPsBTUM+1sX+V250xhH9rlkrRBn49Amu5jfyXWPfX5udTx9R274hoU4vt01YMngjXP2hUI93ya+1tqY2cLtdljTpe9eTXXox++AH6PlLbXuFRFGN2Nc96i+3Ccs6oPeHFdnp2jCAsVvRa1P2XpqFrTer8ixziXw+jr1esJ64no9+XH3xarTJPi+X0dRy5mnq4qmtEp96kPO1Q2zxVx29Xj9M+KVquiut5b59IfwzNb921VionbdKu++V0lqY1KC8iIiIiIiL661GHEOnEwhW7Ytg9rsw+Xiot+H1OGd9pUNyxfGl+2ZKSmLAp9nNzSlZbNZ8OKe7dFiWQLs2r62R/nlPm4rNK4CAUTCSUpaRPcV1IKPk/FCVxWiw7HFGy2trLHocUB3xKQputl1VCYnuOCZ/iOT2rLD4rLc3HfYrF4FQij0vzZdkfnSJNbiV0X0vD7yll5rBBsajHU1pSTRwjDobqj6tDS//1KNg7oyxq840kJqCYL6S0OeGPrLJwR82rFtOP44oNLmWq0XuxKcVpEPkJi+JLNkpVQvHBoYQq8kY9Bl+y5rWa9s9mlWJOpQOKWf2MpM7UWlIWfpxSIpmafYnPOM6livma/++4YhHHM/7f2rrTSqlsy8dVKRt2FOtQnRb1ZemZdnxqug6EtDJZUvJanWlJ1NGGnuVL9Ubd7/I2y9R8Hl85lgbHthhPtKwbdZrVR0lse2dAKdeipXw3+awep0lxfBlQAudrpi9EGyDOo5nasi1bWlAiFxp8rvxZGBTn5QVlqZj2irxYtUVlZi8Uz3+bHI+quC+3MluTBWp7Yzk8o6R+Ly/IKrOnbYqhJj8Xr4q6VZfHS8rsMdHOhGtyXuS7c5tdCSRX2pPQSXvpXKlqe7JKRG1njoWUBW3VfHpGnKfNztEOZWYUu9jGeCxbqod/5JW502bFcEw7bysshp2KTey/nP6lx3OKb79Rcf9nZc18ptSGhL40F/NgUaTP80VEWRQbL+aLwbdcx1Y0P0/LiufrQZ/i+0JcTyQtveJ64tst6sePNTn9s9p22xVfXFuultNJi2I4XHt+aVqc86vyhuRpNzrK098XlLmrHlF33YrvnKu4bjH9edE+7EZVmmo1bY81+ZhHMdS2j/enFMfpubo8JSIiIiIiIlJ1FsB+IL7E1wUsF5Qp8UW2KtgqLMXHFcPHkbovoksx90oAtIIaIMUxjzITrvg6+8eSktfiGlXaBidKX/SxrzZInFciH0OxXa5Y+mxO8Ygv8TMPtPmy4vLKYHuFlwpgLylzX5aOIf9gYTm4Xy2vzH7WIDBWDow281JBmw4D2GrQWkt76oJZMZyca3JMS8pSswCveG/hiksxbnM1D4I2tbYB7GWNyvRxRPF8MaPMVt4IWJ5CyviATfHEWtQCdb919UTN54pjKR7byk2H2YtOxQAoFpGvVefIs0UlUbX/iumSS8HecSXScrk43t0GxVZznjalBr8NjfOsmM97p5SFpuUrVNbVpvmfUMZhqz/3uiXaJRs8ylw+qyxkmoS+ijdb6o9BrcPjcW1mmTj/jq0E/lWlYGv9Oa+eF9XnaamNsVe2MUVqWqvPL/VGlqGujdKW767ef+cWlZl94piuVm914aJFQcXNjCK1Pa9dpspMKbYGy4t5cMCj+C5X3thrdrOnwwA26tvefFStt5X5oqbJ0OAGRWl5wyDqS7WFtd6cPO1cF3lazMv6G5XFQHuLAHUxbS3eL7aF28aVuYpDyEc9ja+5REREREREREJHQ4hI82HEPnPBXjWshQnu23kkjlU/Oi39UxDWvda6sZh1JiscN9KNf3r80ATboYohKjoag7g5xyEbqh8/p4d5wIH4nXTpJ9tCYT6KyT3DGNymLSjbbMPQUQmh+bS2YI08jSH8tR3OASP0W3RInBjE0Nko1NEvVsgoPAV6N9ckvsFDFV+1xNXScBjq8BlFBiNM1yVRfmnEr+ow9qGtyTHpoNuovSyTZciFDIJH+uBK2zCbnoHr3QaffskxoteODOmbHHoaDklhQ99bevSb1uLxc0b0a9u0HwshqyhInLNVnzubjc2HpDGLWq7vg7V2+WczUP7r04bVsKCvtxf2gWaPOKxWSMcRPWxp+EDEbE6cvXv6Yaot30od1VWR7sNxpKsrf9fSN6axcNIOq96A3udBDNlH6sdaF3UvvVPUSW22zPiuFeHvg0iL822FHvbz7qYPg2ypkED8e5vI8+qWR1U9mngB8RuTsB4erGmjxJmzdwijj0KI39MWdONhHOFbbrj2V2/V9Fkc+TueqjTlfo4h5rDWp/PdfljupSA1Gp1CtAOWQ5XDsIg2usUY620dGIatpu3Vm0X+3Rb1orz/e1FMp0cxtLeu9DB42IrpW4mGQwStmTctTzvRdZ72w1gznNWmVud/RyywfRRGPFkeLEWcE3d6YdupzRIRERERERHV6CiAncvFYd7eW/+AQDVYVfVlNgfpfg5RZ2kM0KrJOIyo+BLfaIxTWPrqgjkvpcED6IpfuiuerJe5Nw3sMKJRGNK4zYp0MrMc7F4L6R8CmP3MjSE1aLPRCMfFCHyGCGw9leN9ZyHdAXr/0dGjGF8RUYaSHY6j6vjYHrg/nioFmgxG9BkWsPB9CAHzGFwdBxtkpL8dxKaePoT1PvgOGJBdfqhlxXTNC+s7g5huMlZ5OW/KgfXKaeqWyL9kqG755KXZVY/VKvaEUO32itMUZosPOSyt9Wfo/OGNjYjyvGFE71vabEsFxG/OYnyftS7gq5LzaTi2rEXg3gDzHhum76QatwedeBpD8MLKjRT9+x5ErjqRPdWLXpsfSW2M4tzjBUC0Xb2l2WX6feJ83JfB2I4N2GoZgf9aEjn1YHSrzOvnBVFDTR3kcwbpfzcbY9wI4540EplVtDxPc4jvFOVc23SoNwNrgqLSwyhwxlrfRm+wwi9KRG50I2lPP/rWMrgqzp+6Vrp4Tq3sP5dJIL1H5ElptorB2A/8Oy1y8xV60/K0A689TzWW/W7EbiVK5//TOBLv2FZ344iIiIiIiIj+J3T8EEfjW50HVR3hrDo0SYNpHBZtnf8pj8LwHe8Rk73iJoAOpk+CiE4YEPwwiLga4JDzyOdsMHQUbHw15IIeziuzcL1XmjcddMNSPB4jzAfCGDkSx+inleloofggTfXBhXlgIoG5C87qnsKV054+9ObM6N/ZLIAoq7FYWD8qBdYrp9F9RsAyXLfcc3QQapxwdSFJK4Zrt1ec1IeZaau8IZZg6uyBjg8jCKbHMDTQKMdykH4TtcBQGwpeHeOAqAtfhxGr6gHdKRnJi15EDvvgrryR8pYNvmsh2DJe+LSbQksFUWm2GBrUV3H+HQpg7nEes+dswE0XzMYP4L39Mn169ejpvJlce8YGNxmbEedj4zY6AucqH/75l8Q8fTV22jB8O4q4ON0KdxLo7fAXIkRERERERPS/qaMAtm6zGdEHTXoFPi9U/ORYD8MWQMpltfn1Y0kcJ95aGd7A+K4TyOYb/gRdHSrBYDY17J3dPQnhMx7Il6fgqh2uRByN5XQIkYk+GNXeh09zYm09Nq2yE2j3ZBQeqcOCSAhNjMH7XQzSi5Wdy7kM4tenMf19XCzXo0cNZL87DPvulXVyPyXreznnkgieGsHodRmOS3MIftJp//r6nvMrDLDFFuB+X5vtxNsOhB6Pd96z73kawR/SpV6BIlWp2l7ixSmBhW5inC8kxG7+GX0am3giIWPY1EEQv4DYBT+ME64m+SVqyXUbTMY1qpzbbHDuCyJ4o6b2/BJF9In2ugn57iQ839kQOtNgGJstTrHNAGzbS4F29dcj+HuL9G/UwzTgxHh4AdmkC9JHXsQqy3djh+kV6+mQgdTm2EXLA9Nh0cb83rDlQfaBAf3bV9Hy6HQw31ho8qsRcZ5X7M5gsDVt+14reUkcU+9y72bD9n4YHog8Kc1WKfwulh42NexJvGb+Cnla47Xn6TIzbB8lEJ0X1xgOH0JERERERERtdBTANg8Mw/xdBHHtZ/krZCTF8pUQlA79A25kr8ZRP4K0hPD3cS04uHbSN2J1AYbC8yXtVVkB6WQcroqxuQ0DQ3D9O4p4XQ9QdYxnYGxfJ2HPAqI3yoNENyLy5+wwPJjEVNMgrhGO085S0OCJhKg65uir7q33IoPgR1Zs3bAJ/Sck2JIxRC4HMGbRQbo9De/RIXzw4SiCohD7D7jh/tiG3l/88D7ywbcjgMC1cokXkEpnl8POhd9iiH4fRixnxPC5GUwds8O4Zj1SjbDsM0Hf1dAdDcbjbmKpkMTkhMiLw2Yt2LkyPnX1ZEVfp2l6LvJ5Ig7TfpO24M+gjqNeQKF8ook6ldhjrBtCo5Z824dRTMG3v0nixHZSHQ2R0YBcgHQvhvC/JzH5TRDRX9Qwn6gjX44jdcaL8KPSaqpCVmrdRjwKw3VgFoM3fLA1GX5Bt9sDzz/VUlSHNAIc22rPvQKSdxvcVNjihOvjBDIVx2N4p684Nnt1iyJhofa0N5hh2xdF4n7N0d9LIKK9LDHAdsCF6Rvx+mDnvThCGIO9m5s0ZWqP1p1BRG7X5558dxqRijQZLQ5YGrZ9anserWjP18i9KGK1gf3CUk2eikX3k4iLtsZaroLv20VuNBoTXB1HfFrUA1tHNxkbXSM68qblaSfWKE/Xgnm/G9J3Y4hw+BAiIiIiIiJqo7MhRHa64DsYxfBR9aFn2pd5uYD0d6MIbRuq+vKp3+fB5I4A3J+HVx6Q9jSN8PFpYKBBj8k/tKkTb5tg3TmL+E+l0I/8MIzI89qe0mJOfBEP3tPCQy/U43TDnfHBva8iOPeWA+PhJYx96EXsiZYm9Tg/dyPimK4emqDsXTPcd8T+tcBFYX4akr75V2/pmgsuaQyJq1qAuo3ieL17Da8+gLDRhOGPXRi/n8fij+Nw7jYUyyX/8yRc30no+zSIuR+nRH5pAeNHYYxe0CFwaRzj5ychO4fhvyvyTE4hXuhdPl79u3Y4PnbCvrO0vTfGgxBGHVMwfu7oqJw6Ukhh6vNJbDriWrttdkQHPbJIfDOI3t4+9B32wrjH3LpOqeX7TQ9C55sPDSNnUog2Gg+4AbmQQ+ZuFEF1DPJtswieiSCjs8LxmQeeL1xwvF/aiG5gDMEDcQwf8iOpna75Vr/eeJ6E/0gQfTfiGK/4FUBzpXHT64c/kiFdcGH0Whq5iptyhXtBBOeHYH1XW6B62wjHjSmE57UDlHOInRHtoMjQxHdeeG+WQ5NGDJ/xITUxhuhDrT3JxeC9lYUVUUydEe3Mw9Ji/YFxhF6MYehMrDTutlC4J8rgswiG/r3Kh0iKT7nODSH6kavY9pU2KxfTNBo2YaiyPXvPhcmJBbiP+BEvt30iXfGvRhHfYa+rr0vq8EZ1QfxmDDBZzJi9nSwF6GUJ4agMU81NOcOLKKa/S6OgjQ2tHqf76AJ8RyvroGhv/z2EyMGRlfa8eJzDGHsRwviBBpWxo2tEp96sPO1MF3n6Qj26+iMsHvvveS0/6rV7f5n6K4wXWfRz+BAiIiIiIiJqR+lYXklcdCv29wyK+jHDe07FF1vU3qulrbsNxXWN+zxKKLOkvadKKD6xXH2venIoocfaKk0spacUZ/EYjIr9y1ml+giySmgiJP6fV1IXXYpF3b/BJNYLKQvPtFVqZOMBxbXbWNy/4T274gkvKJVHWmvxP55SusR2nRdTTdddvOpS7KfnxJE08Syv5PMVn/5jUZk5CMV8PqUtaGVJyT5YFJ8vbWPp/pRig0/k6ktaEtvSXpYtZWYU1yczVfm3GHYqBlgU9xfi34n2e82GHQrarfc4pDhWmYaOtt/E4mWbKHuD4vlvRcobHMvSs/L7opwOtK6nS/FxkT8GxfljVluiUut8xTabpHfxTqKmTreQ9Ck4qNb3xhavuhX3xUTzOqiSQorrYEBJVZ0fWSUVSymLy/VzSZn7UpxzX861ODfyyuxJm2IyaOfGlzPKbCbfYn3NM5EvA2Lb2xxKIL6gRI6JvJW09yrlxXr7XMpMVTtSaal0PlS8nRflYIZLifyuLaiQOO9UPOfHFfd+kygrte0xKpaPA0qiwbrL57woU9MhnzIrji9x3qH4wrPKnEhjpfydQEX7pLY7CSWwz61MReeUhcpt/5FV5s5rbZS63f21beTq5O9MraRJLYcJ0Ub+ob1ZZUlZiPq0Yy2154E7lWkRbaloj6rb59LkS2qrNPMspUwdKh2D2var+VUpG/YVz5/8z1Na29s6/fn7IcVTTtM2i+I637pOt75GdO9NyNNutc1TtW1ZPr6V9i4xsXLMVW1PsT2reK9iap420a5MiLZHmyMiIiIiIiJqZoP6P/Elk9ZMAelvvYht82J8n0Fb1kB5WIULXni1B87B4ETk5xAcnfSsey4heTMI33E/Yurv4/fNYDG2tr19pRtjmC644P3YVNczV7o2gg+cQUgTCSinWz+aM3dtCL0/9CIw0OLo8imEvurD9Coe9Fnc/sOxtsfRUCEJ//k83Ocqen4+CWPoHQljFcdSeBhH5JIf3m/iyMGN2fwU7A06gBapPYWPS3BetEH6IYR0saOjhPgJCcbztlIZFdNbgLU8r8rGEfgmBqPI07hIS9s+xnf92HDBiOyPzlX1MM3d8sP3mw2+LywNel4XkLnmhet4HHgrj+SvRvh+jmP8/RZHJdId/H4Jg5/ZYOhmqBd1qJXPBzHyfek88Px3CYG9Fft5FMXYpTxcp1wwNctzoTRm+yQmzwUR18aMsJxLIX6yPCwMEa0bchz+73owfow9sImIiIiIiKg1BrDXkjoEyc0szAfsLQNt1dRxsofgy9rhnXDD0u0Yww+DGD5TwOhFT/efbUaWEPs+Dt0BF2ytIqO5JMLzgP1QowDoivTXVnj1Qcx+0mIs6EISsbQR9oHuQ7G5G2MI6MTU6oZBN55E4b/WC/eXtemSET87ivRAAJ5/dljAcgHyRn3HY3F35ZdpjPxsReAzc8v8r5dDUpTv0j5n6/IVpB9GMDxvxNhxNxzvdbeXbqljqIcuTiP0lgfxCXW4IRnS7RCSGwfh7KZePApj5NAsjCe88BwwMXhNtG5IiH8bx6ZDLhhu+5HeM97ZDVsiIiIiIiL6n8YANhEREb16hRjGdg1iEnb4LoUwvvfV3hQjIiIiIiKivwYGsImIiIiIiIiIiIhoXfp/2r9EREREREREREREROsKA9hEREREREREREREtC4xgE1ERERERERERERE6xDw/wFOY3ZMMMdZPwAAAABJRU5ErkJggg==" /> | ||
29 | </p> | ||
30 | <p>既要看文件内容,又要能浏览不同的文件夹。这个功能如果直接用程序或 nginx 实现似乎有些新手不友好。没事,python3 | ||
31 | 为我们提供了这个功能,脚本为<code>/usr/lib/python3.x/http/server.py</code>。使用时执行以下命令即可:</p> | ||
32 | <pre><code>python3 -m http.server</code></pre> | ||
33 | <p>但 python 提供的脚本有些不尽人意:</p> | ||
34 | <ul> | ||
35 | <li>遇到当前路径有<code>index.html</code>就展示网页,而不是展示当前路径下的文件</li> | ||
36 | <li>无法回退到上层文件夹</li> | ||
37 | <li>无法查看文件详细信息</li> | ||
38 | <li>浏览普通文件时,响应头没有指定文件编码,导致文件显示乱码</li> | ||
39 | <li>无法方便地上传文件</li> | ||
40 | </ul> | ||
41 | <p>处于以上种种原因,我对该程序做了一点点修改。修改后的脚本我选择放在<code>/usr/lib/python3.x/http/myserver.py</code>(和原有<code>server.py</code>放在一起)。代码全文我放在了<a | ||
42 | href="https://file.qin-juan-ge-zhu.top/useful/myserver.py">这里</a>。在这里仅对修改的部分加以说明。</p> | ||
43 | <p>首先,为了完成以下功能,需要引入几个新的模块:</p> | ||
44 | <pre><code>import cgi | ||
45 | import pwd | ||
46 | import grp | ||
47 | import time | ||
48 | import stat | ||
49 | import math</code></pre> | ||
50 | <h1 id="遇到-index.html-时">遇到 index.html 时</h1> | ||
51 | <p>在<code>http.server</code>(源码路径<code>/usr/lib/python3.x/http/server.py</code>)第 710 | ||
52 | 行(<code>def send_head</code>函数)中有这样一段:</p> | ||
53 | <pre><code>for index in "index.html", "index.htm": | ||
54 | index = os.path.join(path, index) | ||
55 | if os.path.isfile(index): | ||
56 | path = index | ||
57 | break</code></pre> | ||
58 | <p>可以看到,该段代码的作用就是当请求的路径是一个文件夹且该文件夹下有<code>index.html</code>或<code>index.htm</code>,则将该文件作为响应内容返回。这一点对于一般的网页服务器来说是不错的,但咱们需要的是浏览服务器文件,而不是展示网页根目录,所以不需要这个功能,该段代码删除即可。 | ||
59 | </p> | ||
60 | <h1 id="浏览文件出现乱码">浏览文件出现乱码</h1> | ||
61 | <p>你可能会问,上边看到的 html 模板不是已经明文规定编码是<code>utf-8</code>了吗,,怎么还会乱码?没错,html 是说明编码了,但我们除了浏览以 html | ||
62 | 形式展示的目录连接之外,还是要看文件内容的,文件里或多或少都会有点中文不是吗?对于文件而言,编码必须由 http 的响应头指出,否则客户端就会根据文件内容猜测其编码然后展示出来,就成了乱码。</p> | ||
63 | <pre><code># http.server, line 763 | ||
64 | # also in the function 'send_head' | ||
65 | # this line and its context are about http response header | ||
66 | self.send_header("Content-type", ctype) | ||
67 | # change it into the below | ||
68 | self.send_header("Content-type", ctype + "; charset=utf-8")</code></pre> | ||
69 | <h1 id="展示所有文件和文件夹">展示所有文件和文件夹</h1> | ||
70 | <p>在<code>server.py</code>第 772 | ||
71 | 行,有一个<code>list_directory</code>函数,是用来展示当前路径下有哪些文件或文件夹的,但是这有个缺陷,就是只能点进下一级文件夹,但无法返回上一级。为此,我们需要做一些修改:</p> | ||
72 | <pre><code>def list_directory(self, path): | ||
73 | try: | ||
74 | list = os.listdir(path) | ||
75 | except OSError: | ||
76 | self.send_error( | ||
77 | HTTPStatus.NOT_FOUND, | ||
78 | "No permission to list directory") | ||
79 | return None | ||
80 | # 添加这一行,使得可以返回上一级和维持本级 | ||
81 | # 以使展示更贴近于Linux的展示 | ||
82 | list.extend([".",".."]) | ||
83 | # 排序方式原来是完全按照字母顺序,不甚方便 | ||
84 | # 修改为文件夹排在文件之前,各自按照字母排序 | ||
85 | # list.sort(key=lambda a: .lower()) | ||
86 | list.sort(key=lambda a: (not os.path.isdir(os.path.join(path,a)),a.lower()))</code></pre> | ||
87 | <p>可能你已经注意到了,主要的展示目录的界面就是这个函数底下的 html 模板。下面我们会经常修改这个模板的。</p> | ||
88 | <h1 id="文件详细信息展示">文件详细信息展示</h1> | ||
89 | <p>有时候我们需要的不仅仅是文件本身,还需要关注文件的详细信息,如用户权限、文件大小、修改日期之类的。这些信息在 Linux | ||
90 | 系统中通常使用命令<code>ls -l</code>或其别名<code>ll</code>来查看。我想要模仿这个命令的输出格式,做一些微调:</p> | ||
91 | <ul> | ||
92 | <li>第一列是文件名,是一个超链接,这个不必说</li> | ||
93 | <li>第二列是目录类型和其权限位</li> | ||
94 | <li>第三列是目录的硬链接数目,文件是 1,目录则是其下的文件和文件夹总数(包括<code>.</code>和<code>..</code>)</li> | ||
95 | <li>第四列、第五列分别是文件的所有者和所属组</li> | ||
96 | <li>第六列文件大小,按照人可读的方式展示(也就是使用适当的单位)</li> | ||
97 | <li>第七、第八列是创建时间和修改时间</li> | ||
98 | </ul> | ||
99 | <p>为了实现以上目的,我们不能继续使用无序列表来展示信息,而是应当改为表格;同时需要注意的是:</p> | ||
100 | <ul> | ||
101 | <li>既然要展示权限位,必然需要使用等宽字体。这里我选择整个 html 均使用等宽字体</li> | ||
102 | <li>为了美观,目录超链接的样式我做了一些修改,主要是去除了其下划线、设置无论是否访问过都显示为同一个颜色</li> | ||
103 | <li>还做了其他一些小的样式修改</li> | ||
104 | </ul> | ||
105 | <pre><code>enc = sys.getfilesystemencoding() | ||
106 | title = f'Directory listing for {displaypath}' | ||
107 | r.append('<!DOCTYPE HTML>') | ||
108 | r.append('<html lang="en">') | ||
109 | r.append('<head>') | ||
110 | r.append(f'<meta charset="{enc}">') | ||
111 | r.append(f'<title>{title}</title>') | ||
112 | r.append('table{border-collapse:separate;}td,th{padding:0 13px;}.size{text-align:right;}body{font-family:"Courier New",monospace;}h1{font-size:30px;margin-bottom:0;}a{text-decoration:none;}a:link{color:#0000EE;}a:visited{color:#0000EE;}a:hover{color:#0000EE;}a:active{color:#0000EE;}</style>') | ||
113 | r.append('</head><body>') | ||
114 | r.append(f'<h1>{title}</h1>') | ||
115 | r.append('<hr>') | ||
116 | r.append('<table><tr><th>Name</th><th>Permissions</th><th>Hard Links</th><th>Owner</th><th>Group</th><th>Size</th><th>Creation Time</th><th>Last Modified</th></tr>') | ||
117 | for name in list: | ||
118 | fullname = os.path.join(path, name) | ||
119 | displayname = linkname = name | ||
120 | # Append / for directories or @ for symbolic links | ||
121 | if os.path.isdir(fullname): | ||
122 | displayname = name + "/" | ||
123 | linkname = name + "/" | ||
124 | if os.path.islink(fullname): | ||
125 | displayname = name + "@" | ||
126 | # Note: a link to a directory displays with @ and links with / | ||
127 | |||
128 | # Add detailed information for each file/directory | ||
129 | stat_info = os.stat(fullname) | ||
130 | mode = stat.filemode(stat_info.st_mode) | ||
131 | hard_links = stat_info.st_nlink | ||
132 | owner = pwd.getpwuid(stat_info.st_uid).pw_name | ||
133 | group = grp.getgrgid(stat_info.st_gid).gr_name | ||
134 | size_bytes = stat_info.st_size | ||
135 | # 文件大小需要可读 | ||
136 | if size_bytes == 0: | ||
137 | size = '0B' | ||
138 | size_name = (' B', 'KB', 'MB', 'GB') | ||
139 | i = int(math.floor(math.log(size_bytes, 1024))) | ||
140 | p = math.pow(1024, i) | ||
141 | s = size_bytes / p | ||
142 | size = '%.2f %s' % (s, size_name[i]) | ||
143 | creation_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(stat_info.st_ctime)) | ||
144 | last_modified = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(stat_info.st_mtime)) | ||
145 | |||
146 | r.append('<tr><td><a href="%s">%s</a></td><td>%s</td><td>%d</td><td>%s</td><td>%s</td><td class="size">%s</td><td>%s</td><td>%s</td></tr>' | ||
147 | % (urllib.parse.quote(linkname, errors='surrogatepass'), | ||
148 | html.escape(displayname, quote=False), | ||
149 | mode, hard_links, owner, group, size, creation_time, last_modified)) | ||
150 | r.append('</table>\n</body>\n') | ||
151 | r.append(''' | ||
152 | <script> | ||
153 | onload = () => { | ||
154 | document.getElementById('file').addEventListener('change', function() { | ||
155 | var files = this.files; | ||
156 | var fileNames = ''; | ||
157 | for (var i = 0; i < files.length; i++) { | ||
158 | fileNames += files[i].name + '\\n'; | ||
159 | } | ||
160 | confirm('Are you sure you want to upload these files?\\n' + fileNames); | ||
161 | }); | ||
162 | } | ||
163 | </script> | ||
164 | ''') | ||
165 | r.append('</html>\n') | ||
166 | encoded = '\n'.join(r).encode(enc, 'surrogateescape') | ||
167 | f = io.BytesIO() | ||
168 | f.write(encoded) | ||
169 | f.seek(0) | ||
170 | self.send_response(HTTPStatus.OK) | ||
171 | self.send_header("Content-type", "text/html; charset=%s" % enc) | ||
172 | self.send_header("Content-Length", str(len(encoded))) | ||
173 | self.end_headers() | ||
174 | return f</code></pre> | ||
175 | <p>到了这一步,整体的布局美观了不少,可以称得上是赏心悦目了。</p> | ||
176 | <h1 id="文件上传">文件上传</h1> | ||
177 | <p>其实轮起来,文件上传这个功能我本是不需要的,我所有设备都能通过<code>scp</code>将文件上传到服务器上。这一切,都是被微信逼的。</p> | ||
178 | <p>前两天,东方直心前辈想要用微信给我发他最新修改的《毛泽东大传》,一连几次打包发我,我都没收到,只能解释为被微信截胡了。没办法,我又不能教老人用什么太繁杂的方法,因而一连几天搞这个文件上传功能,最终在黄四郎同志和 | ||
179 | gpt、copilot 的帮助下,完成了这个功能。</p> | ||
180 | <p>首先,我们需要一个按钮来供使用者上传文件。为了整体页面协调,我选择将上传表单与 h1 放在同一行,都在分割线上方,表单靠右显示;且由于 h1 | ||
181 | 与表单大小不一,表单太靠上不好看,于是设置二者对齐方式为基线对齐,并取消了 h1 与表单的内外留白。</p> | ||
182 | <p>涉及的 html 模板修改情况如下:</p> | ||
183 | <pre><code>title = f'Directory listing for {displaypath}' | ||
184 | r.append('<!DOCTYPE HTML>') | ||
185 | r.append('<html lang="en">') | ||
186 | r.append('<head>') | ||
187 | r.append(f'<meta charset="{enc}">') | ||
188 | r.append(f'<title>{title}</title>') | ||
189 | r.append('<style>input[type="file"],input[type="submit"] {font-size:1em;position:relative;top:100%;}table{border-collapse:separate;}td,th{padding:0 13px;}.size{text-align:right;}body{font-family:"Courier New",monospace;}form{padding:0;margin:0;}h1{font-size:30px;margin-bottom:0;}a{text-decoration:none;}a:link{color:#0000EE;}a:visited{color:#0000EE;}a:hover{color:#0000EE;}a:active{color:#0000EE;}</style>') | ||
190 | r.append('</head><body>') | ||
191 | r.append('<div style="display:flex;justify-content:space-between;align-items:baseline;">') | ||
192 | r.append(f'<h1>{title}</h1>') | ||
193 | r.append('<form action="" method="post" enctype="multipart/form-data">') | ||
194 | r.append('<input type="file" name="file" id="file" multiple>') | ||
195 | r.append('<input type="submit" value="Upload">') | ||
196 | r.append('</form></div>') | ||
197 | r.append('<hr>')</code></pre> | ||
198 | <p>修改的内容主要是 css 样式和添加了上传表单。</p> | ||
199 | <p>接下来,我们需要在<code>do_POST</code>函数中处理上传的文件。这里我使用了<code>cgi</code>模块,该模块可以帮助我们处理上传的文件。在<code>do_POST</code>函数中,我们需要添加以下代码: | ||
200 | </p> | ||
201 | <pre><code># 注意是class SimpleHTTPRequestHandler的do_POST函数 | ||
202 | # 不要搞错了 | ||
203 | def do_POST(self): | ||
204 | # 获取请求路径 | ||
205 | path=self.translate_path(self.path) | ||
206 | form = cgi.FieldStorage( | ||
207 | fp=self.rfile, | ||
208 | headers=self.headers, | ||
209 | environ={'REQUEST_METHOD': 'POST', | ||
210 | 'CONTENT_TYPE': self.headers['Content-Type'], | ||
211 | }) | ||
212 | |||
213 | files=form['file'] | ||
214 | uploaded_filenames = [] | ||
215 | # 只上传了一个文件和上传了多个文件,是需要分别处理的 | ||
216 | if isinstance(files, list): | ||
217 | for uploaded_file in form['file']: | ||
218 | filename = os.path.join(os.getcwd(), path,uploaded_file.filename) | ||
219 | with open(filename, 'wb') as f: | ||
220 | f.write(uploaded_file.file.read()) | ||
221 | uploaded_filenames.append(uploaded_file.filename) | ||
222 | else: | ||
223 | filename = os.path.join(os.getcwd(), path,files.filename) | ||
224 | with open(filename, 'wb') as f: | ||
225 | f.write(files.file.read()) | ||
226 | uploaded_filenames.append(files.filename) | ||
227 | |||
228 | self.send_response(200) | ||
229 | self.send_header('Content-type', 'text/html') | ||
230 | self.end_headers() | ||
231 | # Format the string with the filenames | ||
232 | html_string = ''' | ||
233 | <!DOCTYPE html> | ||
234 | <html> | ||
235 | <head> | ||
236 | <title>File Upload</title> | ||
237 | <script> | ||
238 | window.onload = function() { | ||
239 | // Display a popup notification | ||
240 | alert("Files uploaded successfully: %s"); | ||
241 | |||
242 | // Refresh the current page with a GET request | ||
243 | window.location.reload(true); | ||
244 | }; | ||
245 | </script> | ||
246 | </head> | ||
247 | <body> | ||
248 | </body> | ||
249 | </html> | ||
250 | ''' % '\n'.join(uploaded_filenames) | ||
251 | |||
252 | # Convert the string to bytes and write it to the response | ||
253 | enc='utf-8' | ||
254 | self.wfile.write(html_string.encode(enc, 'surrogateescape'))</code></pre> | ||
255 | <h1 id="后续">后续</h1> | ||
256 | <p>到了这一步,可以说基础功能完全符合我们的需求了。后续有时间有想法的话,可以加上这么一些功能:</p> | ||
257 | <ul> | ||
258 | <li>自动查看文件类型,将如果属于特定类型的代码,就不采用源文件传回而是使用 html 传回,并使用本网站已有的高亮与一键复制办法,为代码文件进行高亮</li> | ||
259 | <li>对于 html 文件,应当提供查看源码和查看显示效果两种展示方式,供用户选择</li> | ||
260 | <li>能不能在前端就实现文件修改呢……</li> | ||
261 | </ul> | ||
262 | <h1 id="结束">结束</h1> | ||
263 | <p>在经历以上的修改之后,原来的<code>http.server</code>改造成为了一个更加适合免登录浏览服务器文件的工具。再次说明,我修改后的文件<a | ||
264 | href="https://file.qin-juan-ge-zhu.top/useful/myserver.py">在这里</a>。如果你想要使用,可以将其放在<code>/usr/lib/python3.x/http/myserver.py</code>,然后使用以下命令启动: | ||
265 | </p> | ||
266 | <pre><code>python -m http.myserver > py_menu.log 2>&1 &</code></pre> | ||
267 | <p>这条命令会让这个进程在后台运行,并且将运行时的日志和报错信息输出到日志文件中,以备查看和随时确认是否有人在通过这个服务攻击你的服务器(服务连续运行三天,查看日志,你一定会被如此多数量的陌生 ip 访问吓到的)。 | ||
268 | </p> | ||
269 | <p>这个服务默认运行在 8000 端口,你可以按照文件最后的<code>main</code>函数里的参数来修改运行端口。到了这一步,你也可以像为其他网络服务配置 https 一样,使用你的网络服务软件(如 | ||
270 | nginx、apache 之类)为之配置域名和 https 服务了,多好~</p> | ||
271 | <p class="time">2023.1.3晚</p> | ||
272 | <script src="https://www.qin-juan-ge-zhu.top/common/js/comment.js"></script> | ||
273 | </div> | ||
274 | </div> | ||
275 | </body> | ||
276 | |||
277 | </html> \ No newline at end of file | ||
diff --git a/code/linux/httpmyserver.md b/code/linux/httpmyserver.md new file mode 100644 index 0000000..2f9f621 --- /dev/null +++ b/code/linux/httpmyserver.md | |||
@@ -0,0 +1,291 @@ | |||
1 | <!-- python实现服务器文件浏览 --> | ||
2 | |||
3 | 有了服务器,我们自然会有这样的需求:**把一些内容传到服务器上,方便其他人访问或自己在其他设备(如手机)上,通过浏览器直接访问**。我们需要它能完成以下功能: | ||
4 | |||
5 | - 能让我们自己点进(或退出)层层文件夹,展示当前文件夹下的所有文件/文件夹 | ||
6 | - 点击文件,能够看到文件内容 | ||
7 | |||
8 |  | ||
9 | |||
10 | 点击进入文件`nginx.txt`,我们要求看到文件的内容: | ||
11 | |||
12 |  | ||
13 | |||
14 | 既要看文件内容,又要能浏览不同的文件夹。这个功能如果直接用程序或 nginx 实现似乎有些新手不友好。没事,python3 为我们提供了这个功能,脚本为`/usr/lib/python3.x/http/server.py`。使用时执行以下命令即可: | ||
15 | |||
16 | ```bash | ||
17 | python3 -m http.server | ||
18 | ``` | ||
19 | |||
20 | 但 python 提供的脚本有些不尽人意: | ||
21 | |||
22 | - 遇到当前路径有`index.html`就展示网页,而不是展示当前路径下的文件 | ||
23 | - 无法回退到上层文件夹 | ||
24 | - 无法查看文件详细信息 | ||
25 | - 浏览普通文件时,响应头没有指定文件编码,导致文件显示乱码 | ||
26 | - 无法方便地上传文件 | ||
27 | |||
28 | 处于以上种种原因,我对该程序做了一点点修改。修改后的脚本我选择放在`/usr/lib/python3.x/http/myserver.py`(和原有`server.py`放在一起)。代码全文我放在了[这里](https://file.qin-juan-ge-zhu.top/useful/myserver.py)。在这里仅对修改的部分加以说明。 | ||
29 | |||
30 | 首先,为了完成以下功能,需要引入几个新的模块: | ||
31 | |||
32 | ```python | ||
33 | import cgi | ||
34 | import pwd | ||
35 | import grp | ||
36 | import time | ||
37 | import stat | ||
38 | import math | ||
39 | ``` | ||
40 | |||
41 | # 遇到 index.html 时 | ||
42 | |||
43 | 在`http.server`(源码路径`/usr/lib/python3.x/http/server.py`)第 710 行(`def send_head`函数)中有这样一段: | ||
44 | |||
45 | ```python | ||
46 | for index in "index.html", "index.htm": | ||
47 | index = os.path.join(path, index) | ||
48 | if os.path.isfile(index): | ||
49 | path = index | ||
50 | break | ||
51 | ``` | ||
52 | |||
53 | 可以看到,该段代码的作用就是当请求的路径是一个文件夹且该文件夹下有`index.html`或`index.htm`,则将该文件作为响应内容返回。这一点对于一般的网页服务器来说是不错的,但咱们需要的是浏览服务器文件,而不是展示网页根目录,所以不需要这个功能,该段代码删除即可。 | ||
54 | |||
55 | # 浏览文件出现乱码 | ||
56 | |||
57 | 你可能会问,上边看到的 html 模板不是已经明文规定编码是`utf-8`了吗,,怎么还会乱码?没错,html 是说明编码了,但我们除了浏览以 html 形式展示的目录连接之外,还是要看文件内容的,文件里或多或少都会有点中文不是吗?对于文件而言,编码必须由 http 的响应头指出,否则客户端就会根据文件内容猜测其编码然后展示出来,就成了乱码。 | ||
58 | |||
59 | ```python | ||
60 | # http.server, line 763 | ||
61 | # also in the function 'send_head' | ||
62 | # this line and its context are about http response header | ||
63 | self.send_header("Content-type", ctype) | ||
64 | # change it into the below | ||
65 | self.send_header("Content-type", ctype + "; charset=utf-8") | ||
66 | ``` | ||
67 | |||
68 | # 展示所有文件和文件夹 | ||
69 | |||
70 | 在`server.py`第 772 行,有一个`list_directory`函数,是用来展示当前路径下有哪些文件或文件夹的,但是这有个缺陷,就是只能点进下一级文件夹,但无法返回上一级。为此,我们需要做一些修改: | ||
71 | |||
72 | ```python | ||
73 | def list_directory(self, path): | ||
74 | try: | ||
75 | list = os.listdir(path) | ||
76 | except OSError: | ||
77 | self.send_error( | ||
78 | HTTPStatus.NOT_FOUND, | ||
79 | "No permission to list directory") | ||
80 | return None | ||
81 | # 添加这一行,使得可以返回上一级和维持本级 | ||
82 | # 以使展示更贴近于Linux的展示 | ||
83 | list.extend([".",".."]) | ||
84 | # 排序方式原来是完全按照字母顺序,不甚方便 | ||
85 | # 修改为文件夹排在文件之前,各自按照字母排序 | ||
86 | # list.sort(key=lambda a: .lower()) | ||
87 | list.sort(key=lambda a: (not os.path.isdir(os.path.join(path,a)),a.lower())) | ||
88 | ``` | ||
89 | |||
90 | 可能你已经注意到了,主要的展示目录的界面就是这个函数底下的 html 模板。下面我们会经常修改这个模板的。 | ||
91 | |||
92 | # 文件详细信息展示 | ||
93 | |||
94 | 有时候我们需要的不仅仅是文件本身,还需要关注文件的详细信息,如用户权限、文件大小、修改日期之类的。这些信息在 Linux 系统中通常使用命令`ls -l`或其别名`ll`来查看。我想要模仿这个命令的输出格式,做一些微调: | ||
95 | |||
96 | - 第一列是文件名,是一个超链接,这个不必说 | ||
97 | - 第二列是目录类型和其权限位 | ||
98 | - 第三列是目录的硬链接数目,文件是 1,目录则是其下的文件和文件夹总数(包括`.`和`..`) | ||
99 | - 第四列、第五列分别是文件的所有者和所属组 | ||
100 | - 第六列文件大小,按照人可读的方式展示(也就是使用适当的单位) | ||
101 | - 第七、第八列是创建时间和修改时间 | ||
102 | |||
103 | 为了实现以上目的,我们不能继续使用无序列表来展示信息,而是应当改为表格;同时需要注意的是: | ||
104 | |||
105 | - 既然要展示权限位,必然需要使用等宽字体。这里我选择整个 html 均使用等宽字体 | ||
106 | - 为了美观,目录超链接的样式我做了一些修改,主要是去除了其下划线、设置无论是否访问过都显示为同一个颜色 | ||
107 | - 还做了其他一些小的样式修改 | ||
108 | |||
109 | ```python | ||
110 | enc = sys.getfilesystemencoding() | ||
111 | title = f'Directory listing for {displaypath}' | ||
112 | r.append('<!DOCTYPE HTML>') | ||
113 | r.append('<html lang="en">') | ||
114 | r.append('<head>') | ||
115 | r.append(f'<meta charset="{enc}">') | ||
116 | r.append(f'<title>{title}</title>') | ||
117 | r.append('table{border-collapse:separate;}td,th{padding:0 13px;}.size{text-align:right;}body{font-family:"Courier New",monospace;}h1{font-size:30px;margin-bottom:0;}a{text-decoration:none;}a:link{color:#0000EE;}a:visited{color:#0000EE;}a:hover{color:#0000EE;}a:active{color:#0000EE;}</style>') | ||
118 | r.append('</head><body>') | ||
119 | r.append(f'<h1>{title}</h1>') | ||
120 | r.append('<hr>') | ||
121 | r.append('<table><tr><th>Name</th><th>Permissions</th><th>Hard Links</th><th>Owner</th><th>Group</th><th>Size</th><th>Creation Time</th><th>Last Modified</th></tr>') | ||
122 | for name in list: | ||
123 | fullname = os.path.join(path, name) | ||
124 | displayname = linkname = name | ||
125 | # Append / for directories or @ for symbolic links | ||
126 | if os.path.isdir(fullname): | ||
127 | displayname = name + "/" | ||
128 | linkname = name + "/" | ||
129 | if os.path.islink(fullname): | ||
130 | displayname = name + "@" | ||
131 | # Note: a link to a directory displays with @ and links with / | ||
132 | |||
133 | # Add detailed information for each file/directory | ||
134 | stat_info = os.stat(fullname) | ||
135 | mode = stat.filemode(stat_info.st_mode) | ||
136 | hard_links = stat_info.st_nlink | ||
137 | owner = pwd.getpwuid(stat_info.st_uid).pw_name | ||
138 | group = grp.getgrgid(stat_info.st_gid).gr_name | ||
139 | size_bytes = stat_info.st_size | ||
140 | # 文件大小需要可读 | ||
141 | if size_bytes == 0: | ||
142 | size = '0B' | ||
143 | size_name = (' B', 'KB', 'MB', 'GB') | ||
144 | i = int(math.floor(math.log(size_bytes, 1024))) | ||
145 | p = math.pow(1024, i) | ||
146 | s = size_bytes / p | ||
147 | size = '%.2f %s' % (s, size_name[i]) | ||
148 | creation_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(stat_info.st_ctime)) | ||
149 | last_modified = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(stat_info.st_mtime)) | ||
150 | |||
151 | r.append('<tr><td><a href="%s">%s</a></td><td>%s</td><td>%d</td><td>%s</td><td>%s</td><td class="size">%s</td><td>%s</td><td>%s</td></tr>' | ||
152 | % (urllib.parse.quote(linkname, errors='surrogatepass'), | ||
153 | html.escape(displayname, quote=False), | ||
154 | mode, hard_links, owner, group, size, creation_time, last_modified)) | ||
155 | r.append('</table>\n</body>\n') | ||
156 | r.append(''' | ||
157 | <script> | ||
158 | onload = () => { | ||
159 | document.getElementById('file').addEventListener('change', function() { | ||
160 | var files = this.files; | ||
161 | var fileNames = ''; | ||
162 | for (var i = 0; i < files.length; i++) { | ||
163 | fileNames += files[i].name + '\\n'; | ||
164 | } | ||
165 | confirm('Are you sure you want to upload these files?\\n' + fileNames); | ||
166 | }); | ||
167 | } | ||
168 | </script> | ||
169 | ''') | ||
170 | r.append('</html>\n') | ||
171 | encoded = '\n'.join(r).encode(enc, 'surrogateescape') | ||
172 | f = io.BytesIO() | ||
173 | f.write(encoded) | ||
174 | f.seek(0) | ||
175 | self.send_response(HTTPStatus.OK) | ||
176 | self.send_header("Content-type", "text/html; charset=%s" % enc) | ||
177 | self.send_header("Content-Length", str(len(encoded))) | ||
178 | self.end_headers() | ||
179 | return f | ||
180 | ``` | ||
181 | |||
182 | 到了这一步,整体的布局美观了不少,可以称得上是赏心悦目了。 | ||
183 | |||
184 | # 文件上传 | ||
185 | |||
186 | 其实轮起来,文件上传这个功能我本是不需要的,我所有设备都能通过`scp`将文件上传到服务器上。这一切,都是被微信逼的。 | ||
187 | |||
188 | 前两天,东方直心前辈想要用微信给我发他最新修改的《毛泽东大传》,一连几次打包发我,我都没收到,只能解释为被微信截胡了。没办法,我又不能教老人用什么太繁杂的方法,因而一连几天搞这个文件上传功能,最终在黄四郎同志和 gpt、copilot 的帮助下,完成了这个功能。 | ||
189 | |||
190 | 首先,我们需要一个按钮来供使用者上传文件。为了整体页面协调,我选择将上传表单与 h1 放在同一行,都在分割线上方,表单靠右显示;且由于 h1 与表单大小不一,表单太靠上不好看,于是设置二者对齐方式为基线对齐,并取消了 h1 与表单的内外留白。 | ||
191 | |||
192 | 涉及的 html 模板修改情况如下: | ||
193 | |||
194 | ```python | ||
195 | title = f'Directory listing for {displaypath}' | ||
196 | r.append('<!DOCTYPE HTML>') | ||
197 | r.append('<html lang="en">') | ||
198 | r.append('<head>') | ||
199 | r.append(f'<meta charset="{enc}">') | ||
200 | r.append(f'<title>{title}</title>') | ||
201 | r.append('<style>input[type="file"],input[type="submit"] {font-size:1em;position:relative;top:100%;}table{border-collapse:separate;}td,th{padding:0 13px;}.size{text-align:right;}body{font-family:"Courier New",monospace;}form{padding:0;margin:0;}h1{font-size:30px;margin-bottom:0;}a{text-decoration:none;}a:link{color:#0000EE;}a:visited{color:#0000EE;}a:hover{color:#0000EE;}a:active{color:#0000EE;}</style>') | ||
202 | r.append('</head><body>') | ||
203 | r.append('<div style="display:flex;justify-content:space-between;align-items:baseline;">') | ||
204 | r.append(f'<h1>{title}</h1>') | ||
205 | r.append('<form action="" method="post" enctype="multipart/form-data">') | ||
206 | r.append('<input type="file" name="file" id="file" multiple>') | ||
207 | r.append('<input type="submit" value="Upload">') | ||
208 | r.append('</form></div>') | ||
209 | r.append('<hr>') | ||
210 | ``` | ||
211 | |||
212 | 修改的内容主要是 css 样式和添加了上传表单。 | ||
213 | |||
214 | 接下来,我们需要在`do_POST`函数中处理上传的文件。这里我使用了`cgi`模块,该模块可以帮助我们处理上传的文件。在`do_POST`函数中,我们需要添加以下代码: | ||
215 | |||
216 | ```python | ||
217 | # 注意是class SimpleHTTPRequestHandler的do_POST函数 | ||
218 | # 不要搞错了 | ||
219 | def do_POST(self): | ||
220 | # 获取请求路径 | ||
221 | path=self.translate_path(self.path) | ||
222 | form = cgi.FieldStorage( | ||
223 | fp=self.rfile, | ||
224 | headers=self.headers, | ||
225 | environ={'REQUEST_METHOD': 'POST', | ||
226 | 'CONTENT_TYPE': self.headers['Content-Type'], | ||
227 | }) | ||
228 | |||
229 | files=form['file'] | ||
230 | uploaded_filenames = [] | ||
231 | # 只上传了一个文件和上传了多个文件,是需要分别处理的 | ||
232 | if isinstance(files, list): | ||
233 | for uploaded_file in form['file']: | ||
234 | filename = os.path.join(os.getcwd(), path,uploaded_file.filename) | ||
235 | with open(filename, 'wb') as f: | ||
236 | f.write(uploaded_file.file.read()) | ||
237 | uploaded_filenames.append(uploaded_file.filename) | ||
238 | else: | ||
239 | filename = os.path.join(os.getcwd(), path,files.filename) | ||
240 | with open(filename, 'wb') as f: | ||
241 | f.write(files.file.read()) | ||
242 | uploaded_filenames.append(files.filename) | ||
243 | |||
244 | self.send_response(200) | ||
245 | self.send_header('Content-type', 'text/html') | ||
246 | self.end_headers() | ||
247 | # Format the string with the filenames | ||
248 | html_string = ''' | ||
249 | <!DOCTYPE html> | ||
250 | <html> | ||
251 | <head> | ||
252 | <title>File Upload</title> | ||
253 | <script> | ||
254 | window.onload = function() { | ||
255 | // Display a popup notification | ||
256 | alert("Files uploaded successfully: %s"); | ||
257 | |||
258 | // Refresh the current page with a GET request | ||
259 | window.location.reload(true); | ||
260 | }; | ||
261 | </script> | ||
262 | </head> | ||
263 | <body> | ||
264 | </body> | ||
265 | </html> | ||
266 | ''' % '\n'.join(uploaded_filenames) | ||
267 | |||
268 | # Convert the string to bytes and write it to the response | ||
269 | enc='utf-8' | ||
270 | self.wfile.write(html_string.encode(enc, 'surrogateescape')) | ||
271 | ``` | ||
272 | |||
273 | # 后续 | ||
274 | |||
275 | 到了这一步,可以说基础功能完全符合我们的需求了。后续有时间有想法的话,可以加上这么一些功能: | ||
276 | |||
277 | - 自动查看文件类型,将如果属于特定类型的代码,就不采用源文件传回而是使用 html 传回,并使用本网站已有的高亮与一键复制办法,为代码文件进行高亮 | ||
278 | - 对于 html 文件,应当提供查看源码和查看显示效果两种展示方式,供用户选择 | ||
279 | - 能不能在前端就实现文件修改呢…… | ||
280 | |||
281 | # 结束 | ||
282 | |||
283 | 在经历以上的修改之后,原来的`http.server`改造成为了一个更加适合免登录浏览服务器文件的工具。再次说明,我修改后的文件[在这里](https://file.qin-juan-ge-zhu.top/useful/myserver.py)。如果你想要使用,可以将其放在`/usr/lib/python3.x/http/myserver.py`,然后使用以下命令启动: | ||
284 | |||
285 | ```bash | ||
286 | python -m http.myserver > py_menu.log 2>&1 & | ||
287 | ``` | ||
288 | |||
289 | 这条命令会让这个进程在后台运行,并且将运行时的日志和报错信息输出到日志文件中,以备查看和随时确认是否有人在通过这个服务攻击你的服务器(服务连续运行三天,查看日志,你一定会被如此多数量的陌生 ip 访问吓到的)。 | ||
290 | |||
291 | 这个服务默认运行在 8000 端口,你可以按照文件最后的`main`函数里的参数来修改运行端口。到了这一步,你也可以像为其他网络服务配置 https 一样,使用你的网络服务软件(如 nginx、apache 之类)为之配置域名和 https 服务了,多好~ | ||
diff --git a/code/linux/vim.html b/code/linux/vim.html index 22f070f..fc1f145 100644 --- a/code/linux/vim.html +++ b/code/linux/vim.html | |||
@@ -3,8 +3,9 @@ | |||
3 | 3 | ||
4 | <head> | 4 | <head> |
5 | <meta charset="utf-8" /> | 5 | <meta charset="utf-8" /> |
6 | <meta name="generator" content="pandoc" /> | ||
6 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> | 7 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> |
7 | <title>vim学习与配置</title> | 8 | <title>vim学习与我的配置</title> |
8 | <link rel="stylesheet" href="https://www.qin-juan-ge-zhu.top/common/CSS/pandoc.css"> | 9 | <link rel="stylesheet" href="https://www.qin-juan-ge-zhu.top/common/CSS/pandoc.css"> |
9 | <script type="text/javascript" src="https://www.qin-juan-ge-zhu.top/common/script4code.js"></script> | 10 | <script type="text/javascript" src="https://www.qin-juan-ge-zhu.top/common/script4code.js"></script> |
10 | </head> | 11 | </head> |
@@ -18,388 +19,45 @@ | |||
18 | 时代码上下反复跳转,令你烦闷否?别人写的编辑器设置种种不便,是否想过有一个自己私人订制的编辑器?如果你有以上苦恼,那么 vim 将是你的绝佳选择。</p> | 19 | 时代码上下反复跳转,令你烦闷否?别人写的编辑器设置种种不便,是否想过有一个自己私人订制的编辑器?如果你有以上苦恼,那么 vim 将是你的绝佳选择。</p> |
19 | <p>vim 是一个文本编辑器,素有“编辑器之神”的美名,同时它也是 Linux 尤其是服务器环境下编辑文件的主要方法。</p> | 20 | <p>vim 是一个文本编辑器,素有“编辑器之神”的美名,同时它也是 Linux 尤其是服务器环境下编辑文件的主要方法。</p> |
20 | <p>vim 的主要特点是分模式编辑:</p> | 21 | <p>vim 的主要特点是分模式编辑:</p> |
21 | <div class="table-div"> | 22 | <table> |
22 | <table> | 23 | <thead> |
23 | <thead> | 24 | <tr class="header"> |
24 | <tr class="header"> | 25 | <th>模式</th> |
25 | <th>模式</th> | 26 | <th>说明</th> |
26 | <th>说明</th> | 27 | <th>功能</th> |
27 | <th>功能</th> | 28 | </tr> |
28 | </tr> | 29 | </thead> |
29 | </thead> | 30 | <tbody> |
30 | <tbody> | 31 | <tr class="odd"> |
31 | <tr class="odd"> | 32 | <td>Normal</td> |
32 | <td>Normal</td> | 33 | <td>正常</td> |
33 | <td>正常</td> | 34 | <td>光标移动、阅读文件</td> |
34 | <td>光标移动、阅读文件</td> | 35 | </tr> |
35 | </tr> | 36 | <tr class="even"> |
36 | <tr class="even"> | 37 | <td>Insert</td> |
37 | <td>Insert</td> | 38 | <td>插入</td> |
38 | <td>插入</td> | 39 | <td>在当前光标位置插入内容,编辑文件</td> |
39 | <td>在当前光标位置插入内容,编辑文件</td> | 40 | </tr> |
40 | </tr> | 41 | <tr class="odd"> |
41 | <tr class="odd"> | 42 | <td>Visual</td> |
42 | <td>Visual</td> | 43 | <td>视觉/选择</td> |
43 | <td>视觉/选择</td> | 44 | <td>选中、复制粘贴</td> |
44 | <td>选中、复制粘贴</td> | 45 | </tr> |
45 | </tr> | 46 | <tr class="even"> |
46 | <tr class="even"> | 47 | <td>Replace</td> |
47 | <td>Replace</td> | 48 | <td>替换</td> |
48 | <td>替换</td> | 49 | <td>替换当前光标下字符</td> |
49 | <td>替换当前光标下字符</td> | 50 | </tr> |
50 | </tr> | 51 | </tbody> |
51 | </tbody> | 52 | </table> |
52 | </table> | ||
53 | </div> | ||
54 | <p>其关系如下:</p> | 53 | <p>其关系如下:</p> |
55 | <!-- 楚河汉界 --> | 54 | <pre><code>graph LR |
56 | <div class="md-diagram-panel md-fences-adv-panel" style="text-align: center;"><svg id="mermaidChart0" | 55 | N(Normal)--->I(Insert) |
57 | width="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" | 56 | N--->V(Visual) |
58 | style="max-width: 262.82501220703125px;display: inline;" | 57 | N--->R(Replace) |
59 | viewBox="-8 -7.999998092651367 262.82501220703125 237.79998779296875" | 58 | I-->N |
60 | role="graphics-document document" aria-roledescription="flowchart-v2"> | 59 | V-->N |
61 | <style> | 60 | R-->N</code></pre> |
62 | #mermaidChart0 { | ||
63 | font-family: sans-serif; | ||
64 | font-size: 16px; | ||
65 | fill: #333; | ||
66 | } | ||
67 | |||
68 | #mermaidChart0 .error-icon { | ||
69 | fill: #552222; | ||
70 | } | ||
71 | |||
72 | #mermaidChart0 .error-text { | ||
73 | fill: #552222; | ||
74 | stroke: #552222; | ||
75 | } | ||
76 | |||
77 | #mermaidChart0 .edge-thickness-normal { | ||
78 | stroke-width: 2px; | ||
79 | } | ||
80 | |||
81 | #mermaidChart0 .edge-thickness-thick { | ||
82 | stroke-width: 3.5px; | ||
83 | } | ||
84 | |||
85 | #mermaidChart0 .edge-pattern-solid { | ||
86 | stroke-dasharray: 0; | ||
87 | } | ||
88 | |||
89 | #mermaidChart0 .edge-pattern-dashed { | ||
90 | stroke-dasharray: 3; | ||
91 | } | ||
92 | |||
93 | #mermaidChart0 .edge-pattern-dotted { | ||
94 | stroke-dasharray: 2; | ||
95 | } | ||
96 | |||
97 | #mermaidChart0 .marker { | ||
98 | fill: #333333; | ||
99 | stroke: #333333; | ||
100 | } | ||
101 | |||
102 | #mermaidChart0 .marker.cross { | ||
103 | stroke: #333333; | ||
104 | } | ||
105 | |||
106 | #mermaidChart0 svg { | ||
107 | font-family: sans-serif; | ||
108 | font-size: 16px; | ||
109 | } | ||
110 | |||
111 | #mermaidChart0 .label { | ||
112 | font-family: sans-serif; | ||
113 | color: #333; | ||
114 | } | ||
115 | |||
116 | #mermaidChart0 .cluster-label text { | ||
117 | fill: #333; | ||
118 | } | ||
119 | |||
120 | #mermaidChart0 .cluster-label span, | ||
121 | #mermaidChart0 p { | ||
122 | color: #333; | ||
123 | } | ||
124 | |||
125 | #mermaidChart0 .label text, | ||
126 | #mermaidChart0 span, | ||
127 | #mermaidChart0 p { | ||
128 | fill: #333; | ||
129 | color: #333; | ||
130 | } | ||
131 | |||
132 | #mermaidChart0 .node rect, | ||
133 | #mermaidChart0 .node circle, | ||
134 | #mermaidChart0 .node ellipse, | ||
135 | #mermaidChart0 .node polygon, | ||
136 | #mermaidChart0 .node path { | ||
137 | fill: #ECECFF; | ||
138 | stroke: #9370DB; | ||
139 | stroke-width: 1px; | ||
140 | } | ||
141 | |||
142 | #mermaidChart0 .flowchart-label text { | ||
143 | text-anchor: middle; | ||
144 | } | ||
145 | |||
146 | #mermaidChart0 .node .label { | ||
147 | text-align: center; | ||
148 | } | ||
149 | |||
150 | #mermaidChart0 .node.clickable { | ||
151 | cursor: pointer; | ||
152 | } | ||
153 | |||
154 | #mermaidChart0 .arrowheadPath { | ||
155 | fill: #333333; | ||
156 | } | ||
157 | |||
158 | #mermaidChart0 .edgePath .path { | ||
159 | stroke: #333333; | ||
160 | stroke-width: 2.0px; | ||
161 | } | ||
162 | |||
163 | #mermaidChart0 .flowchart-link { | ||
164 | stroke: #333333; | ||
165 | fill: none; | ||
166 | } | ||
167 | |||
168 | #mermaidChart0 .edgeLabel { | ||
169 | background-color: #e8e8e8; | ||
170 | text-align: center; | ||
171 | } | ||
172 | |||
173 | #mermaidChart0 .edgeLabel rect { | ||
174 | opacity: 0.5; | ||
175 | background-color: #e8e8e8; | ||
176 | fill: #e8e8e8; | ||
177 | } | ||
178 | |||
179 | #mermaidChart0 .cluster rect { | ||
180 | fill: #ffffde; | ||
181 | stroke: #aaaa33; | ||
182 | stroke-width: 1px; | ||
183 | } | ||
184 | |||
185 | #mermaidChart0 .cluster text { | ||
186 | fill: #333; | ||
187 | } | ||
188 | |||
189 | #mermaidChart0 .cluster span, | ||
190 | #mermaidChart0 p { | ||
191 | color: #333; | ||
192 | } | ||
193 | |||
194 | #mermaidChart0 div.mermaidTooltip { | ||
195 | position: absolute; | ||
196 | text-align: center; | ||
197 | max-width: 200px; | ||
198 | padding: 2px; | ||
199 | font-family: sans-serif; | ||
200 | font-size: 12px; | ||
201 | background: hsl(80, 100%, 96.2745098039%); | ||
202 | border: 1px solid #aaaa33; | ||
203 | border-radius: 2px; | ||
204 | pointer-events: none; | ||
205 | z-index: 100; | ||
206 | } | ||
207 | |||
208 | #mermaidChart0 .flowchartTitleText { | ||
209 | text-anchor: middle; | ||
210 | font-size: 18px; | ||
211 | fill: #333; | ||
212 | } | ||
213 | |||
214 | #mermaidChart0 :root { | ||
215 | --mermaid-alt-font-family: sans-serif; | ||
216 | } | ||
217 | </style> | ||
218 | <g> | ||
219 | <marker id="flowchart-pointEnd" class="marker flowchart" viewBox="0 0 12 20" refX="10" refY="5" | ||
220 | markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto"> | ||
221 | <path d="M 0 0 L 10 5 L 0 10 z" class="arrowMarkerPath" | ||
222 | style="stroke-width: 1; stroke-dasharray: 1, 0;"></path> | ||
223 | </marker> | ||
224 | <marker id="flowchart-pointStart" class="marker flowchart" viewBox="0 0 10 10" refX="0" refY="5" | ||
225 | markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto"> | ||
226 | <path d="M 0 5 L 10 10 L 10 0 z" class="arrowMarkerPath" | ||
227 | style="stroke-width: 1; stroke-dasharray: 1, 0;"></path> | ||
228 | </marker> | ||
229 | <marker id="flowchart-circleEnd" class="marker flowchart" viewBox="0 0 10 10" refX="11" refY="5" | ||
230 | markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"> | ||
231 | <circle cx="5" cy="5" r="5" class="arrowMarkerPath" | ||
232 | style="stroke-width: 1; stroke-dasharray: 1, 0;"></circle> | ||
233 | </marker> | ||
234 | <marker id="flowchart-circleStart" class="marker flowchart" viewBox="0 0 10 10" refX="-1" | ||
235 | refY="5" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"> | ||
236 | <circle cx="5" cy="5" r="5" class="arrowMarkerPath" | ||
237 | style="stroke-width: 1; stroke-dasharray: 1, 0;"></circle> | ||
238 | </marker> | ||
239 | <marker id="flowchart-crossEnd" class="marker cross flowchart" viewBox="0 0 11 11" refX="12" | ||
240 | refY="5.2" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"> | ||
241 | <path d="M 1,1 l 9,9 M 10,1 l -9,9" class="arrowMarkerPath" | ||
242 | style="stroke-width: 2; stroke-dasharray: 1, 0;"></path> | ||
243 | </marker> | ||
244 | <marker id="flowchart-crossStart" class="marker cross flowchart" viewBox="0 0 11 11" refX="-1" | ||
245 | refY="5.2" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"> | ||
246 | <path d="M 1,1 l 9,9 M 10,1 l -9,9" class="arrowMarkerPath" | ||
247 | style="stroke-width: 2; stroke-dasharray: 1, 0;"></path> | ||
248 | </marker> | ||
249 | <g class="root"> | ||
250 | <g class="clusters"></g> | ||
251 | <g class="edgePaths"> | ||
252 | <path | ||
253 | d="M48.526970990449726,90.5999984741211L97.36250305175781,10.299999237060547L122.36250305175781,10.299999237060547L147.3625030517578,10.299999237060547L180.28125381469727,15.589745202208903" | ||
254 | id="L-N-I-0" | ||
255 | class=" edge-thickness-normal edge-pattern-solid flowchart-link LS-N LE-I" | ||
256 | style="fill:none;" marker-end="url(#flowchart-pointEnd)"></path> | ||
257 | <path | ||
258 | d="M71.36480354119537,90.5999984741211L97.36250305175781,75.5999984741211L122.36250305175781,75.5999984741211L147.3625030517578,75.5999984741211L179.36875343322754,93.75519542413791" | ||
259 | id="L-N-V-0" | ||
260 | class=" edge-thickness-normal edge-pattern-solid flowchart-link LS-N LE-V" | ||
261 | style="fill:none;" marker-end="url(#flowchart-pointEnd)"></path> | ||
262 | <path | ||
263 | d="M58.64019142520192,131.1999969482422L97.36250305175781,166.1999969482422L122.36250305175781,166.1999969482422L147.3625030517578,166.1999969482422L173.806377885162,181.1999969482422" | ||
264 | id="L-N-R-0" | ||
265 | class=" edge-thickness-normal edge-pattern-solid flowchart-link LS-N LE-R" | ||
266 | style="fill:none;" marker-end="url(#flowchart-pointEnd)"></path> | ||
267 | <path | ||
268 | d="M180.28125381469727,36.92719562072298L147.3625030517578,55.599998474121094L122.36250305175781,55.599998474121094L97.36250305175781,55.599998474121094L58.64019142520192,90.5999984741211" | ||
269 | id="L-I-N-0" | ||
270 | class=" edge-thickness-normal edge-pattern-solid flowchart-link LS-I LE-N" | ||
271 | style="fill:none;" marker-end="url(#flowchart-pointEnd)"></path> | ||
272 | <path | ||
273 | d="M179.36875343322754,128.04479999822536L147.3625030517578,146.1999969482422L122.36250305175781,146.1999969482422L97.36250305175781,146.1999969482422L71.36480354119537,131.1999969482422" | ||
274 | id="L-V-N-0" | ||
275 | class=" edge-thickness-normal edge-pattern-solid flowchart-link LS-V LE-N" | ||
276 | style="fill:none;" marker-end="url(#flowchart-pointEnd)"></path> | ||
277 | <path | ||
278 | d="M172.3625030517578,207.48272195515207L147.3625030517578,211.49999618530273L122.36250305175781,211.49999618530273L97.36250305175781,211.49999618530273L48.526970990449726,131.1999969482422" | ||
279 | id="L-R-N-0" | ||
280 | class=" edge-thickness-normal edge-pattern-solid flowchart-link LS-R LE-N" | ||
281 | style="fill:none;" marker-end="url(#flowchart-pointEnd)"></path> | ||
282 | </g> | ||
283 | <g class="edgeLabels"> | ||
284 | <g class="edgeLabel"> | ||
285 | <g class="label" transform="translate(0, 0)"> | ||
286 | <foreignObject width="0" height="0"> | ||
287 | <div xmlns="http://www.w3.org/1999/xhtml" | ||
288 | style="display: inline-block; white-space: nowrap;"><span | ||
289 | class="edgeLabel"></span></div> | ||
290 | </foreignObject> | ||
291 | </g> | ||
292 | </g> | ||
293 | <g class="edgeLabel"> | ||
294 | <g class="label" transform="translate(0, 0)"> | ||
295 | <foreignObject width="0" height="0"> | ||
296 | <div xmlns="http://www.w3.org/1999/xhtml" | ||
297 | style="display: inline-block; white-space: nowrap;"><span | ||
298 | class="edgeLabel"></span></div> | ||
299 | </foreignObject> | ||
300 | </g> | ||
301 | </g> | ||
302 | <g class="edgeLabel"> | ||
303 | <g class="label" transform="translate(0, 0)"> | ||
304 | <foreignObject width="0" height="0"> | ||
305 | <div xmlns="http://www.w3.org/1999/xhtml" | ||
306 | style="display: inline-block; white-space: nowrap;"><span | ||
307 | class="edgeLabel"></span></div> | ||
308 | </foreignObject> | ||
309 | </g> | ||
310 | </g> | ||
311 | <g class="edgeLabel"> | ||
312 | <g class="label" transform="translate(0, 0)"> | ||
313 | <foreignObject width="0" height="0"> | ||
314 | <div xmlns="http://www.w3.org/1999/xhtml" | ||
315 | style="display: inline-block; white-space: nowrap;"><span | ||
316 | class="edgeLabel"></span></div> | ||
317 | </foreignObject> | ||
318 | </g> | ||
319 | </g> | ||
320 | <g class="edgeLabel"> | ||
321 | <g class="label" transform="translate(0, 0)"> | ||
322 | <foreignObject width="0" height="0"> | ||
323 | <div xmlns="http://www.w3.org/1999/xhtml" | ||
324 | style="display: inline-block; white-space: nowrap;"><span | ||
325 | class="edgeLabel"></span></div> | ||
326 | </foreignObject> | ||
327 | </g> | ||
328 | </g> | ||
329 | <g class="edgeLabel"> | ||
330 | <g class="label" transform="translate(0, 0)"> | ||
331 | <foreignObject width="0" height="0"> | ||
332 | <div xmlns="http://www.w3.org/1999/xhtml" | ||
333 | style="display: inline-block; white-space: nowrap;"><span | ||
334 | class="edgeLabel"></span></div> | ||
335 | </foreignObject> | ||
336 | </g> | ||
337 | </g> | ||
338 | </g> | ||
339 | <g class="nodes"> | ||
340 | <g class="node default default flowchart-label" id="flowchart-N-24" | ||
341 | transform="translate(36.181251525878906, 110.89999771118164)"> | ||
342 | <rect class="basic label-container" style="" rx="5" ry="5" x="-36.18124961853027" | ||
343 | y="-20.300000190734863" width="72.36249923706055" height="40.60000038146973"> | ||
344 | </rect> | ||
345 | <g class="label" style="" | ||
346 | transform="translate(-28.681249618530273, -12.800000190734863)"> | ||
347 | <rect></rect> | ||
348 | <foreignObject width="57.36249923706055" height="25.600000381469727"> | ||
349 | <div xmlns="http://www.w3.org/1999/xhtml" | ||
350 | style="display: inline-block; white-space: nowrap;"><span | ||
351 | class="nodeLabel">Normal</span></div> | ||
352 | </foreignObject> | ||
353 | </g> | ||
354 | </g> | ||
355 | <g class="node default default flowchart-label" id="flowchart-I-25" | ||
356 | transform="translate(209.59375381469727, 20.299999237060547)"> | ||
357 | <rect class="basic label-container" style="" rx="5" ry="5" x="-29.3125" | ||
358 | y="-20.300000190734863" width="58.625" height="40.60000038146973"></rect> | ||
359 | <g class="label" style="" transform="translate(-21.8125, -12.800000190734863)"> | ||
360 | <rect></rect> | ||
361 | <foreignObject width="43.625" height="25.600000381469727"> | ||
362 | <div xmlns="http://www.w3.org/1999/xhtml" | ||
363 | style="display: inline-block; white-space: nowrap;"><span | ||
364 | class="nodeLabel">Insert</span></div> | ||
365 | </foreignObject> | ||
366 | </g> | ||
367 | </g> | ||
368 | <g class="node default default flowchart-label" id="flowchart-V-27" | ||
369 | transform="translate(209.59375381469727, 110.89999771118164)"> | ||
370 | <rect class="basic label-container" style="" rx="5" ry="5" x="-30.225000381469727" | ||
371 | y="-20.300000190734863" width="60.45000076293945" height="40.60000038146973"> | ||
372 | </rect> | ||
373 | <g class="label" style="" | ||
374 | transform="translate(-22.725000381469727, -12.800000190734863)"> | ||
375 | <rect></rect> | ||
376 | <foreignObject width="45.45000076293945" height="25.600000381469727"> | ||
377 | <div xmlns="http://www.w3.org/1999/xhtml" | ||
378 | style="display: inline-block; white-space: nowrap;"><span | ||
379 | class="nodeLabel">Visual</span></div> | ||
380 | </foreignObject> | ||
381 | </g> | ||
382 | </g> | ||
383 | <g class="node default default flowchart-label" id="flowchart-R-29" | ||
384 | transform="translate(209.59375381469727, 201.49999618530273)"> | ||
385 | <rect class="basic label-container" style="" rx="5" ry="5" x="-37.23125076293945" | ||
386 | y="-20.300000190734863" width="74.4625015258789" height="40.60000038146973"> | ||
387 | </rect> | ||
388 | <g class="label" style="" | ||
389 | transform="translate(-29.731250762939453, -12.800000190734863)"> | ||
390 | <rect></rect> | ||
391 | <foreignObject width="59.462501525878906" height="25.600000381469727"> | ||
392 | <div xmlns="http://www.w3.org/1999/xhtml" | ||
393 | style="display: inline-block; white-space: nowrap;"><span | ||
394 | class="nodeLabel">Replace</span></div> | ||
395 | </foreignObject> | ||
396 | </g> | ||
397 | </g> | ||
398 | </g> | ||
399 | </g> | ||
400 | </g> | ||
401 | </svg></div> | ||
402 | <!-- 楚河汉界 --> | ||
403 | <h1 id="我的-vim-学习路线">我的 vim 学习路线</h1> | 61 | <h1 id="我的-vim-学习路线">我的 vim 学习路线</h1> |
404 | <p>不幸的是 Vim 的学习曲线确实相当陡峭,最开始你会觉得非常不适应,但一旦熬过了初始阶段,你会爱上 Vim。以我而言,现在离开了 vim 的模式几乎已经快不会写材料了,前几天交作业要求 | 62 | <p>不幸的是 Vim 的学习曲线确实相当陡峭,最开始你会觉得非常不适应,但一旦熬过了初始阶段,你会爱上 Vim。以我而言,现在离开了 vim 的模式几乎已经快不会写材料了,前几天交作业要求 |
405 | word,我保存文件居然不是<kbd>Ctrl+s</kbd>,而是顺手来了个<kbd>:wq</kbd>。</p> | 63 | word,我保存文件居然不是<kbd>Ctrl+s</kbd>,而是顺手来了个<kbd>:wq</kbd>。</p> |
@@ -437,8 +95,7 @@ | |||
437 | <li>不论何种 Linux 发行版,使用的 vim 版本都略微比发行时间旧一些以保证稳定性;但有时追求新功能的话需要最新版,甚至网上找不到你需要的版本的安装包。</li> | 95 | <li>不论何种 Linux 发行版,使用的 vim 版本都略微比发行时间旧一些以保证稳定性;但有时追求新功能的话需要最新版,甚至网上找不到你需要的版本的安装包。</li> |
438 | </ul> | 96 | </ul> |
439 | <p>因而,我们有时会需要自己手动编译安装 vim。即以我而言,为了在 vim 上使用 GitHub Copilot 插件,根据插件文档要求,我不得不手动编译 vim。下面是我的编译过程。当前系统为 | 97 | <p>因而,我们有时会需要自己手动编译安装 vim。即以我而言,为了在 vim 上使用 GitHub Copilot 插件,根据插件文档要求,我不得不手动编译 vim。下面是我的编译过程。当前系统为 |
440 | Ubuntu22.04 | 98 | Ubuntu22.04 LTS。编译过程中主要参考以下几篇文章,在此一并致谢:</p> |
441 | LTS。编译过程中主要参考以下几篇文章,在此一并致谢:</p> | ||
442 | <ul> | 99 | <ul> |
443 | <li><a href="https://richrose.dev/posts/linux/vim/vim-compile/">Compiling Vim</a></li> | 100 | <li><a href="https://richrose.dev/posts/linux/vim/vim-compile/">Compiling Vim</a></li> |
444 | <li><a href="https://blog.csdn.net/MHSMIE/article/details/112005119">vim 使用原码升级到最新版本</a></li> | 101 | <li><a href="https://blog.csdn.net/MHSMIE/article/details/112005119">vim 使用原码升级到最新版本</a></li> |
@@ -446,11 +103,11 @@ | |||
446 | </ul> | 103 | </ul> |
447 | <h2 id="清理干净">清理干净</h2> | 104 | <h2 id="清理干净">清理干净</h2> |
448 | <p>下载的第一步当然是卸载当前系统具有的 vim 了。除此之外,由于 Python2 过于老旧,我选择不支持 Python2 仅支持 Python3 的 vim,因此也将 Python2 卸载。</p> | 105 | <p>下载的第一步当然是卸载当前系统具有的 vim 了。除此之外,由于 Python2 过于老旧,我选择不支持 Python2 仅支持 Python3 的 vim,因此也将 Python2 卸载。</p> |
449 | <pre><code class="language-bash">sudo apt autoremove vim rvim gvim vim-runtime | 106 | <pre><code>sudo apt autoremove vim rvim gvim vim-runtime |
450 | sudo apt autoremove python2*</code></pre> | 107 | sudo apt autoremove python2*</code></pre> |
451 | <h2 id="做好准备">做好准备</h2> | 108 | <h2 id="做好准备">做好准备</h2> |
452 | <p>为了编译能够支持 python3/rust/perl/lua 等语言的 vim,我们需要安装一些包。</p> | 109 | <p>为了编译能够支持 python3/rust/perl/lua 等语言的 vim,我们需要安装一些包。</p> |
453 | <pre><code class="language-bash">sudo apt install -y git \ | 110 | <pre><code>sudo apt install -y git \ |
454 | libatk1.0-dev \ | 111 | libatk1.0-dev \ |
455 | libcairo2-dev \ | 112 | libcairo2-dev \ |
456 | #libgtk2.0-dev \ | 113 | #libgtk2.0-dev \ |
@@ -466,12 +123,11 @@ sudo apt autoremove python2*</code></pre> | |||
466 | <p>由于我的编译在服务器上运行,主要运行环境为命令行,不需要 gtk2 等图形界面的支持,因而将安装 gtk 的那一行注释掉了。在编译带有 gtk2.0 的 vim 时似乎会遇到问题:vim | 123 | <p>由于我的编译在服务器上运行,主要运行环境为命令行,不需要 gtk2 等图形界面的支持,因而将安装 gtk 的那一行注释掉了。在编译带有 gtk2.0 的 vim 时似乎会遇到问题:vim |
467 | 源码截至目前版本(v9.0.1854)采用的 gtk 代码中的<code>struct _GTimeVal</code>已经被弃用,gcc | 124 | 源码截至目前版本(v9.0.1854)采用的 gtk 代码中的<code>struct _GTimeVal</code>已经被弃用,gcc |
468 | 要求改用<code>struct _GDateTime</code>,因此编译时会报错,而且陷入死循环,编译不会终止,只能<kbd>Ctrl+c</kbd>杀死进程。我尚不知道如何解决。这也是我放弃支持 | 125 | 要求改用<code>struct _GDateTime</code>,因此编译时会报错,而且陷入死循环,编译不会终止,只能<kbd>Ctrl+c</kbd>杀死进程。我尚不知道如何解决。这也是我放弃支持 |
469 | gtk | 126 | gtk 的原因之一。</p> |
470 | 的原因之一。</p> | ||
471 | <h2 id="下载源码">下载源码</h2> | 127 | <h2 id="下载源码">下载源码</h2> |
472 | <p>vim 源码可以通过其<a href="https://github.com/vim/vim">GitHub 仓库</a>下载,也可以在其<a | 128 | <p>vim 源码可以通过其<a href="https://github.com/vim/vim">GitHub 仓库</a>下载,也可以在其<a |
473 | href="https://www.vim.org/download.php">官网</a>下载。我选择了前者。</p> | 129 | href="https://www.vim.org/download.php">官网</a>下载。我选择了前者。</p> |
474 | <pre><code class="language-bash">git clone https://github.com/vim/vim | 130 | <pre><code>git clone https://github.com/vim/vim |
475 | 131 | ||
476 | # 后续处理过程都在源码目录下的src目录内进行,因而切换过去 | 132 | # 后续处理过程都在源码目录下的src目录内进行,因而切换过去 |
477 | cd vim/src | 133 | cd vim/src |
@@ -483,7 +139,7 @@ sudo make distclean</code></pre> | |||
483 | <p>vim | 139 | <p>vim |
484 | 的编译过程中,需要先运行<code>configure</code>脚本,该脚本会检查当前系统的环境,并以参数形式接收你需要哪些功能。可以通过<code>./configure --help</code>查看所有可选参数及其功能说明。我选择的参数如下: | 140 | 的编译过程中,需要先运行<code>configure</code>脚本,该脚本会检查当前系统的环境,并以参数形式接收你需要哪些功能。可以通过<code>./configure --help</code>查看所有可选参数及其功能说明。我选择的参数如下: |
485 | </p> | 141 | </p> |
486 | <pre><code class="language-bash">sudo ./configure\ | 142 | <pre><code>sudo ./configure\ |
487 | --with-features=huge \ | 143 | --with-features=huge \ |
488 | --enable-multibyte \ | 144 | --enable-multibyte \ |
489 | --enable-rubyinterp=dynamic \ | 145 | --enable-rubyinterp=dynamic \ |
@@ -523,22 +179,22 @@ sudo make distclean</code></pre> | |||
523 | </p> | 179 | </p> |
524 | <h3 id="编译安装">编译安装</h3> | 180 | <h3 id="编译安装">编译安装</h3> |
525 | <p>编译安装过程简单到无以复加,就几句话的事。</p> | 181 | <p>编译安装过程简单到无以复加,就几句话的事。</p> |
526 | <pre><code class="language-bash"># 编译 | 182 | <pre><code># 编译 |
527 | sudo make | 183 | sudo make |
528 | # 安装 | 184 | # 安装 |
529 | sudo make install</code></pre> | 185 | sudo make install</code></pre> |
530 | <p>安装过程中可能会出现报错,如部分文件(<code>ex</code>/<code>view</code>等)已经存在,删掉该文件再重新运行命令安装便是。</p> | 186 | <p>安装过程中可能会出现报错,如部分文件(<code>ex</code>/<code>view</code>等)已经存在,删掉该文件再重新运行命令安装便是。</p> |
531 | <p>安装完成后,可以在命令行中运行<code>vim --version</code>查看 vim 的版本信息,确认是否支持你需要的功能。</p> | 187 | <p>安装完成后,可以在命令行中运行<code>vim --version</code>查看 vim 的版本信息,确认是否支持你需要的功能。</p> |
188 | <p>最后,将我的<a href="https://file.qin-juan-ge-zhu.top/compile_vim.sh">编译安装脚本</a>奉上,供参考。</p> | ||
532 | <h1 id="我的-vim-配置">我的 vim 配置</h1> | 189 | <h1 id="我的-vim-配置">我的 vim 配置</h1> |
533 | <p>网上一般的教程都说 vim 的默认配置文件为<code>~/.vimrc</code>。这当然是不错的,但是有一个巨大的问题:家目录是随着用户而不同的,这会导致我们以当前普通用户打开 vim 编辑文件与以 | 190 | <p>网上一般的教程都说 vim 的默认配置文件为<code>~/.vimrc</code>。这当然是不错的,但是有一个巨大的问题:家目录是随着用户而不同的,这会导致我们以当前普通用户打开 vim 编辑文件与以 |
534 | root | 191 | root 用户使用 vim 的观感完全不一致,就很烦。</p> |
535 | 用户使用 vim 的观感完全不一致,就很烦。</p> | ||
536 | <p>通过查看<kbd>vim –version</kbd>的输出,可以发现,vim 的配置文件有几层,其中“系统 vimrc | 192 | <p>通过查看<kbd>vim –version</kbd>的输出,可以发现,vim 的配置文件有几层,其中“系统 vimrc |
537 | 文件”被放置在<code>$VIM/vimrc</code>,而<code>$VIM</code>为<code>/etc/vim</code>。因此,我们可以将 vim | 193 | 文件”被放置在<code>$VIM/vimrc</code>,而<code>$VIM</code>为<code>/etc/vim</code>。因此,我们可以将 vim |
538 | 的配置文件放置在<code>/etc/vim</code>下,这样不论是普通用户还是 root | 194 | 的配置文件放置在<code>/etc/vim</code>下,这样不论是普通用户还是 root |
539 | 用户,都会使用这份文件,保证观感一致。另外,由于该文件位置较远,我选择在<code>~/useful</code>下创建软链接,方便使用。</p> | 195 | 用户,都会使用这份文件,保证观感一致。另外,由于该文件位置较远,我选择在<code>~/useful</code>下创建软链接,方便使用。</p> |
540 | <p>除此之外,出于同样的目的(保证当前用户与 root 用户观感一致),建议将插件也指定一个专门的绝对路径。我放在了<code>/home/player/useful/bundle</code>。</p> | 196 | <p>除此之外,出于同样的目的(保证当前用户与 root 用户观感一致),建议将插件也指定一个专门的绝对路径。我放在了<code>/home/player/useful/bundle</code>。</p> |
541 | <pre><code class="language-bash"># 创建软链接 | 197 | <pre><code># 创建软链接 |
542 | # 我习惯把有用的文件放在~/useful下 | 198 | # 我习惯把有用的文件放在~/useful下 |
543 | mkdir useful | 199 | mkdir useful |
544 | cd useful | 200 | cd useful |
@@ -549,377 +205,24 @@ sudo ln -s /etc/vim /home/player/useful/vim | |||
549 | # 插件存放位置 | 205 | # 插件存放位置 |
550 | mkdir bundle</code></pre> | 206 | mkdir bundle</code></pre> |
551 | <h2 id="设置">设置</h2> | 207 | <h2 id="设置">设置</h2> |
552 | <p>下文所有设置的目录均为<code>~/useful/vim</code>,也即<code>/etc/vim</code>。由于内容过多,我在目录下创建了<code>vimrcs</code>文件夹,将不同内容分别以专门文件管理,vimrc | 208 | <p>这里原本记录着我的旧版 vim 配置,但随着<a href="https://www.qin-juan-ge-zhu.top/code/linux/httpmyserver.html">http |
553 | 文件调用这些文件。因此,下边只有<code>vimrc</code>在<code>/etc/vim</code>下;其他文件均在<code>/etc/vim/vimrcs</code>下,以<code>./vimrcs/<文件名></code>表示。插件放置在<code>~/useful/bundle</code>。 | 209 | 浏览服务器文件</a>的完成,再保留旧版然后每隔三四个月更新一次,对于我这种没事就折腾的人来说说,就显得不那么必要了。因此,这里只简单说一下。</p> |
554 | </p> | 210 | <p>配置的整体结构如下:</p> |
555 | <h3 id="vimrc">./vimrc</h3> | 211 | <pre><code>/etc/vim |
556 | <pre><code class="hljs language-vim">" Vundle插件管理及插件内容 | 212 | ├── vimrc # vim配置文件,负责引入不同的配置模块 |
557 | if filereadable(expand("/etc/vim/vimrcs/plugs.vim")) | 213 | ├── vimrc_origin # 原有配置脚本备份 |
558 | source /etc/vim/vimrcs/plugs.vim | 214 | ├── vimrcs # 我的配置文件夹,里边是不同的配置模块 |
559 | endif | 215 | │ ├── autocmd.vim |
560 | 216 | │ ├── codecmd.vim | |
561 | " 自行设置 | 217 | │ ├── keybind.vim |
562 | if filereadable(expand("/etc/vim/vimrcs/myset.vim")) | 218 | │ ├── match.vim |
563 | source /etc/vim/vimrcs/myset.vim | 219 | │ ├── myset.vim |
564 | endif | 220 | │ ├── plugs.vim |
565 | 221 | │ └── statusline.vim | |
566 | " 符号自动匹配 | 222 | ├── vimrc.tiny # 原有脚本,无用 |
567 | if filereadable(expand("/etc/vim/vimrcs/match.vim")) | 223 | └── vimscript.vim # 原有脚本,无用</code></pre> |
568 | source /etc/vim/vimrcs/match.vim | 224 | <p>我直接把我服务器上的配置文件<a href="https://file.qin-juan-ge-zhu.top/useful/vim/">放在这里</a>,以供查看。</p> |
569 | endif | 225 | <p class="time">2023.7.5<br>2023.9.6<br>2024.1.3</p> |
570 | |||
571 | " 不知道是什么 | ||
572 | if filereadable(expand("/etc/vim/vimrcs/fuck.vim")) | ||
573 | source /etc/vim/vimrcs/fuck.vim | ||
574 | endif | ||
575 | |||
576 | " 自己设的快捷键 | ||
577 | if filereadable(expand("/etc/vim/vimrcs/keybind.vim")) | ||
578 | source /etc/vim/vimrcs/keybind.vim | ||
579 | endif | ||
580 | |||
581 | " 自动命令 | ||
582 | if filereadable(expand("/etc/vim/vimrcs/autocmd.vim")) | ||
583 | source /etc/vim/vimrcs/autocmd.vim | ||
584 | endif</code></pre> | ||
585 | <h3 id="vimrcsplugs.vim">./vimrcs/plugs.vim</h3> | ||
586 | <pre><code class="hljs language-vim">" Vundle插件管理器配置 | ||
587 | set nocompatible "去除VIM一致性,必须 | ||
588 | filetype off "必须 | ||
589 | |||
590 | "设置包括vundle和初始化相关的运行时路径 | ||
591 | set rtp+=/home/player/useful/bundle/Vundle.vim | ||
592 | call vundle#begin('/home/player/useful/bundle') | ||
593 | |||
594 | Plugin 'VundleVim/Vundle.vim' "启用vundle管理插件,必须 | ||
595 | Plugin 'Valloric/YouCompleteMe' "代码补全插件 | ||
596 | Plugin 'preservim/nerdtree' "文件目录树插件 | ||
597 | Plugin 'Xuyuanp/nerdtree-git-plugin' "nerdtree git支持 | ||
598 | Plugin 'skywind3000/vim-terminal-help' "vim-terminal-help插件 | ||
599 | Plugin 'scrooloose/syntastic' "语法检查插件 | ||
600 | Plugin 'Lokaltog/powerline',{'rtp':'powerline/bindings/vim/'} "状态栏信息插件 | ||
601 | Plugin 'ianva/vim-youdao-translater' "有道翻译插件 | ||
602 | Plugin 'github/copilot.vim' "GitHub Copilot插件 | ||
603 | |||
604 | "在此增加其他插件,安装的插件需要放在vundle#begin和vundle#end之间 | ||
605 | "安装github上的插件格式为 Plugin '用户名/插件仓库名' | ||
606 | |||
607 | call vundle#end() | ||
608 | |||
609 | filetype plugin indent on "加载vim自带和插件相应的语法和文件类型相关脚本,必须 | ||
610 | |||
611 | " YouCompleteMe | ||
612 | let g:ycm_global_ycm_extra_conf='/home/player/useful/bundle/YouCompleteMe/.ycm_extra_conf.py' | ||
613 | let g:ycm_key_invoke_completion = '<C-c>' | ||
614 | let g:ycm_semantic_triggers = { | ||
615 | \ 'c,cpp,python,java,go,erlang,perl': ['re!\w{2}'], | ||
616 | \ 'cs,lua,javascript': ['re!\w{2}'], | ||
617 | \ } | ||
618 | highlight PMenu ctermfg=34 ctermbg=21 guifg=darkred guibg=darkblue | ||
619 | highlight PMenuSel ctermfg=21 ctermbg=34 guifg=darkblue guibg=darkred | ||
620 | let g:ycm_autoclose_preview_window_after_completion=1 "窗口在完成操作后消失 | ||
621 | map <leader>g :YcmCompleter GoToDefinitionElseDeclaration<CR> "找到当前内容定义位置的快捷方式 | ||
622 | |||
623 | "NERDTree | ||
624 | autocmd vimenter * NERDTree "进入vim自动打开nerdtree | ||
625 | autocmd bufenter * if(winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif "当nerdtree为剩余唯一窗口时自动关闭 | ||
626 | map <F2> :NERDTreeToggle<CR> "F2键开关文件目录树,注意shift+i切换是否显示隐藏文件 | ||
627 | let g:NERDTreeDirArrowExpandable = '+' | ||
628 | let g:NERDTreeDirArrowCollapsible = '-' "修改树的显示图标 | ||
629 | "let g:NERDTreeWinPos='left' "窗口位置 | ||
630 | let g:NERDTreeSize=10"窗口尺寸 | ||
631 | let g:NERDTreeShowLineNumbers=1 "窗口是否显示行号 | ||
632 | "let g:NERDTreeHidden=1 "似乎是隐藏文件的旧命令?没看到作用 | ||
633 | let NERDTreeShowHidden=1 " 显示隐藏文件 | ||
634 | let NERDTreeIgnore = ['\.pyc$', '\.swp', '\.swo', '\.vscode', '__pycache__'] " 过滤: 所有指定文件和文件夹不显示 | ||
635 | autocmd BufWinEnter * if getcmdwintype() == '' | silent NERDTreeMirror | endif " 在每个标签页打开相同的文件树 | ||
636 | let g:NERDtreeNodeDelimiter = "\u00a0" | ||
637 | |||
638 | |||
639 | "nerdtree-git-plugin | ||
640 | let g:NERDTreeGitStatusIndicatorMapCustom = { | ||
641 | \ 'Dirty' :'Dir', | ||
642 | \ 'Modified' :'M', | ||
643 | \ 'Staged' :'S', | ||
644 | \ 'Untracked' :'U', | ||
645 | \ 'Renamed' :'R', | ||
646 | \ 'Unmerged' :'UM', | ||
647 | \ 'Deleted' :'X', | ||
648 | \ 'Ignored' :'Ig', | ||
649 | \ 'Clean' :'Cl', | ||
650 | \ 'Unknown' :'?', | ||
651 | \ } | ||
652 | let g:NERDTreeGitStatusShowIgnored = 1 " a heavy feature may cost much more time. default: 0 | ||
653 | let g:NERDTreeGitStatusUntrackedFilesMode = 'all' " a heavy feature too. default: normal | ||
654 | "let g:NERDTreeGitStatusGitBinPath = '/your/file/path' " default: git (auto find in path) | ||
655 | |||
656 | "vim-terminal-help | ||
657 | set termwinsize=10*106 | ||
658 | |||
659 | "syntastic | ||
660 | "以下内容是syntastic插件的一般配置,由于YouCompleteMe插件对该插件支持过于优秀,一般不再需要配置,故废弃 | ||
661 | "set statusline+=%#warningmsg# | ||
662 | "set statusline+=%{syntasticstatuslineflag()} | ||
663 | "set statusline+=%* | ||
664 | " | ||
665 | "let g:syntastic_always_populate_loc_list = 1 | ||
666 | "let g:syntastic_auto_loc_list = 1 | ||
667 | "let g:syntastic_check_on_open = 1 | ||
668 | "let g:syntastic_check_on_wq = 0 | ||
669 | ""设置error和warning的标志 | ||
670 | "let g:syntastic_enable_signs = 1 | ||
671 | ""let g:syntastic_error_symbol='?' | ||
672 | "let g:syntastic_warning_symbol='?' | ||
673 | ""no-unused-args 忽略不使用的参数 | ||
674 | ""no-redefined 忽略重定义 | ||
675 | ""no-max-line-length 忽略每行最长的检测 | ||
676 | ""ignore 542 551 忽略if条件的body为空(如...elseif ret == nil then end,then和end中间没有语句);忽略空语句(如;),如果用了;则成对出现该语法检测warning | ||
677 | ""有语法错误的一行左侧栏会有s&gt;标识,光标移动到改行,vim下发会给出提示。修改正确后保存,则该's&gt;'会消失。 | ||
678 | "let g:syntastic_lua_checkers = ["/usr/bin/luac5.3.5", "luacheck"] | ||
679 | "let g:syntastic_lua_luacheck_args = "--codes --no-max-comment-line-length --ignore 542 551" | ||
680 | " | ||
681 | ""c | ||
682 | ""let g:syntastic_c_compiler =['gcc', 'clang', 'make'] | ||
683 | ""let g:syntastic_c_compiler_options ='-wpedantic -g' | ||
684 | "let g:syntastic_c_compiler_options ='-std=gnu99' | ||
685 | "let g:syntastic_c_include_dirs=['/usr/include/'] | ||
686 | "let g:syntastic_c_config_file='.syntastic_c_config_file' | ||
687 | " | ||
688 | ""cpp | ||
689 | "let g:syntastic_cpp_include_dirs = ['/usr/include/'] | ||
690 | "let g:syntastic_cpp_remove_include_errors = 1 | ||
691 | "let g:syntastic_cpp_check_header = 1 | ||
692 | "let g:syntastic_cpp_compiler = 'clang++' | ||
693 | "let g:syntastic_cpp_compiler_options = '-std=c++11 -stdlib=libstdc++' | ||
694 | "" syntastic end | ||
695 | let g:syntastic_python_checkers=['pylint'] | ||
696 | let g:syntastic_python_pylint_args=['--disable=C0111,R0903,C0301'] | ||
697 | |||
698 | |||
699 | " powerline | ||
700 | let laststatus=2 | ||
701 | let g:airlinr_powerline_fonts=1 "使用官方打过补丁的字体 | ||
702 | let g:Powerline_symbols='fancy' | ||
703 | |||
704 | "vim-youdao-translater | ||
705 | vnoremap <silent> <C-t> :<C-u>Ydv<CR> | ||
706 | nnoremap <silent> <C-t> :<C-u>Ydc<CR> | ||
707 | noremap <leader>yd: <C-u>Yde<CR></code></pre> | ||
708 | <h3 id="vimrcsmyset.vim">./vimrcs/myset.vim</h3> | ||
709 | <pre><code class="hljs language-vim">set nocp "设置兼容 | ||
710 | set expandtab "设置tab | ||
711 | set shiftwidth=4 "设置tab的间隔 | ||
712 | set tabstop=4 "四个空格代表一个tab | ||
713 | set sts=4 | ||
714 | set showmatch "在输入括号时光标会短暂地跳到与之相匹配的括号处 | ||
715 | set autoindent "设置自动缩进 | ||
716 | " set smartindent "设置智能缩进 | ||
717 | set nowrap "设置自动换行 | ||
718 | set tw=500 | ||
719 | set lbr | ||
720 | set foldmethod=indent "设置按缩进折叠代码 | ||
721 | set foldlevel=99 "折叠层级 | ||
722 | nnoremap <space> za "空格代替za进行展开和折叠 | ||
723 | "===set guifont=Monospace "设置字体大小 | ||
724 | set guifont=:b:h16 | ||
725 | set encoding=utf-8 "设置编码为utf-8 | ||
726 | set fileencoding=utf-8 | ||
727 | set fileencodings=ucs-bom,utf-8,GB18030,cp936,big5,euc-jp,euc-kr,latin1 | ||
728 | set helplang=cn "帮助中文支持 | ||
729 | "colorscheme evening "设置主体颜色 | ||
730 | set mouse=a " 设置鼠标 | ||
731 | |||
732 | "自动补全配置 | ||
733 | autocmd FileType python set omnifunc=pythoncomplete#Complete | ||
734 | autocmd FileType javascript set omnifunc=javascriptcomplete#CompleteJS | ||
735 | autocmd FileType html set omnifunc=htmlcomplete#CompleteTags | ||
736 | autocmd FileType css set omnifunc=csscomplete#CompleteCSS | ||
737 | autocmd FileType xml set omnifunc=xmlcomplete#CompleteTags | ||
738 | autocmd FileType php set omnifunc=phpcomplete#CompletePHP | ||
739 | autocmd FileType c set omnifunc=ccomplete#Complete | ||
740 | |||
741 | "进行Taglist的设置 | ||
742 | map <F3> :TlistToggle<CR> | ||
743 | "map <F3> :silent! Tlist<CR> "按下F3就可以呼出了 | ||
744 | "let Tlist_Ctags_Cmd='/usr/bin/ctags' "因为我们放在环境变量里,所以可以直接执行 | ||
745 | let Tlist_Use_Right_Window=1 "让窗口显示在右边,0的话就是显示在左边 | ||
746 | "let Tlist_Show_One_File=1 "让taglist可以同时展示多个文件的函数列表 | ||
747 | "let Tlist_File_Fold_Auto_Close=1 "非当前文件,函数列表折叠隐藏 | ||
748 | "let Tlist_Exit_OnlyWindow=1 "当taglist是最后一个分割窗口时,自动推出vim | ||
749 | "let Tlist_Process_File_Always=0 "是否一直处理tags.1:处理;0:不处理 | ||
750 | "let Tlist_Inc_Winwidth=0 "不是一直实时更新tags,因为没有必要 | ||
751 | |||
752 | set rnu "设置相对行号 | ||
753 | set nu "设置绝对行号 | ||
754 | " Set cursor shape and color | ||
755 | if &term =~ "xterm" | ||
756 | " INSERT mode | ||
757 | let &t_SI = "\<Esc>[6 q" . "\<Esc>]12;blue\x7" | ||
758 | " REPLACE mode | ||
759 | let &t_SR = "\<Esc>[3 q" . "\<Esc>]12;black\x7" | ||
760 | " NORMAL mode | ||
761 | let &t_EI = "\<Esc>[2 q" . "\<Esc>]12;green\x7" | ||
762 | endif | ||
763 | " 1 -> blinking block 闪烁的方块 | ||
764 | " 2 -> solid block 不闪烁的方块 | ||
765 | " 3 -> blinking underscore 闪烁的下划线 | ||
766 | " 4 -> solid underscore 不闪烁的下划线 | ||
767 | " 5 -> blinking vertical bar 闪烁的竖线 | ||
768 | " 6 -> solid vertical bar 不闪烁的竖线 | ||
769 | |||
770 | syntax on | ||
771 | set cul | ||
772 | set cuc | ||
773 | hi CursorLine cterm=NONE ctermbg=darkred ctermfg=white guibg=darkred guifg=white | ||
774 | ""set lines=35 columns=118 | ||
775 | colorscheme zaibatsu "设置颜色主题 | ||
776 | set wrap "设置自动折行</code></pre> | ||
777 | <h3 id="vimrcsmatch.vim">./vimrcs/match.vim</h3> | ||
778 | <pre><code class="hljs language-vim">"各类符号自动匹配 | ||
779 | :inoremap ( ()<ESC>i | ||
780 | :inoremap ) <c-r>=ClosePair(')')<CR> | ||
781 | :inoremap { {}<ESC>i | ||
782 | :inoremap } <c-r>=ClosePair('}')<CR> | ||
783 | :inoremap [ []<ESC>i | ||
784 | :inoremap ] <c-r>=ClosePair(']')<CR> | ||
785 | |||
786 | function ClosePair(char) | ||
787 | if getline('.')[col('.') - 1] == a:char | ||
788 | return "<Right>" | ||
789 | else | ||
790 | return a:char | ||
791 | endif | ||
792 | endfunction</code></pre> | ||
793 | <h3 id="vimrcsfuck.vim">./vimrcs/fuck.vim</h3> | ||
794 | <pre><code class="hljs language-vim">" 键盘映射设置区域 | ||
795 | |||
796 | " 对应使用函数的配置 | ||
797 | set guitablabel=%{ShortTabLabel()} | ||
798 | function ShortTabLabel () | ||
799 | let bufnrlist = tabpagebuflist (v:lnum) | ||
800 | let label = bufname (bufnrlist[tabpagewinnr (v:lnum) -1]) | ||
801 | let filename = fnamemodify (label, ':t') | ||
802 | return filename | ||
803 | endfunction | ||
804 | |||
805 | set tabline=%!MyTabLine() | ||
806 | function MyTabLine() | ||
807 | let s = '' | ||
808 | for i in range(tabpagenr('$')) | ||
809 | " 选择高亮 | ||
810 | if i + 1 == tabpagenr() | ||
811 | let s .= '%#TabLineSel#' | ||
812 | else | ||
813 | let s .= '%#TabLine#' | ||
814 | endif | ||
815 | " 设置标签页号 (用于鼠标点击) | ||
816 | let s .= '%' . (i + 1) . 'T' | ||
817 | " MyTabLabel() 提供完整路径标签 MyShortTabLabel 提供文件名标签 | ||
818 | let s .= ' %{MyShortTabLabel(' . (i + 1) . ')} ' | ||
819 | endfor | ||
820 | " 最后一个标签页之后用 TabLineFill 填充并复位标签页号 | ||
821 | let s .= '%#TabLineFill#%T' | ||
822 | " 右对齐用于关闭当前标签页的标签 | ||
823 | if tabpagenr('$') > 1 | ||
824 | let s .= '%=%#TabLine#%999Xclose' | ||
825 | endif | ||
826 | return s | ||
827 | endfunction | ||
828 | " 文件名标签 | ||
829 | function MyShortTabLabel(n) | ||
830 | let buflist = tabpagebuflist(a:n) | ||
831 | let label = bufname (buflist[tabpagewinnr (a:n) -1]) | ||
832 | let filename = fnamemodify (label, ':t') | ||
833 | return filename | ||
834 | endfunction | ||
835 | "完整路径标签 | ||
836 | function MyTabLabel(n) | ||
837 | let buflist = tabpagebuflist(a:n) | ||
838 | let winnr = tabpagewinnr(a:n) | ||
839 | return bufname(buflist[winnr - 1]) | ||
840 | endfunction | ||
841 | " vim 标签样式 | ||
842 | " TabLineFill tab pages line, where there are no labels | ||
843 | hi TabLineFill term=none | ||
844 | hi TabLineFill ctermfg=DarkGrey | ||
845 | hi TabLineFill guifg=#777777 | ||
846 | " TabLineSel tab pages line, active tab page label | ||
847 | hi TabLineSel term=inverse | ||
848 | hi TabLineSel cterm=none ctermfg=yellow ctermbg=Black | ||
849 | hi TabLineSel gui=none guifg=yellow guibg=Black | ||
850 | |||
851 | " Develop editing options | ||
852 | au FileType vim setl expandtab | ||
853 | au FileType vim setl shiftwidth=2 | ||
854 | au FileType vim setl tabstop=2 | ||
855 | |||
856 | " 显示状态栏(默认值为 1,无法显示状态栏) | ||
857 | set laststatus=2 | ||
858 | " Format the statusline | ||
859 | " set statusline= %f %m %r %h %w CWD: %r%{CurDir()}E5%h Line: %l/%L:%c | ||
860 | |||
861 | function! CurDir() | ||
862 | let curdir = substitute(getcwd(), '/Users/amir/', "~/", "g") | ||
863 | return curdir | ||
864 | endfunction</code></pre> | ||
865 | <h3 id="vimrcskeybind.vim">./vimrcs/keybind.vim</h3> | ||
866 | <pre><code class="hljs language-vim">map - dd | ||
867 | map up 20k | ||
868 | map ne 20j | ||
869 | map end G | ||
870 | map ta $ | ||
871 | "map <C-l> <C-w-l> | ||
872 | nmap <C-tab> :tabn<CR> | ||
873 | nmap <tab> :tabp<CR> | ||
874 | "nmap <alt-tab> :tabnew<CR> | ||
875 | map <space>= <buffer><esc>:vertical resize +5<cr> | ||
876 | map <space>- <esc>:vertical resize -5<cr> | ||
877 | |||
878 | nn <M-1> 1gt | ||
879 | nn <M-2> 2gt | ||
880 | nn <M-3> 3gt | ||
881 | nn <M-4> 4gt | ||
882 | nn <M-5> 5gt | ||
883 | nn <M-6> 6gt | ||
884 | nn <M-7> 7gt | ||
885 | nn <M-8> 8gt | ||
886 | nn <M-9> 9gt | ||
887 | nn <M-0> :tablast<CR> | ||
888 | |||
889 | "光标在页面间切换 | ||
890 | nnoremap <space>h <C-w><C-h> | ||
891 | nnoremap <space>j <C-w><C-j> | ||
892 | nnoremap <space>k <C-w><C-k> | ||
893 | nnoremap <space>l <C-w><C-l> | ||
894 | |||
895 | "复制粘贴 | ||
896 | "vnoremap <C-y> "+y | ||
897 | "nnoremap <C-p> "+p | ||
898 | |||
899 | " 其他开发配置 | ||
900 | " Python | ||
901 | au BufNewFile,BufRead *.py | ||
902 | \ set tabstop=4 | | ||
903 | \ set shiftwidth=4 | | ||
904 | \ set textwidth=79 | | ||
905 | \ set expandtab | | ||
906 | \ set autoindent | | ||
907 | \ set fileformat=unix |</code></pre> | ||
908 | <h3 id="vimrcsautocmd.vim">./vimrcs/autocmd.vim</h3> | ||
909 | <pre><code class="hljs language-vim">autocmd BufReadPost,BufWritePre *.html,*.c,*.cpp normal gg=G | ||
910 | autocmd Filetype html,markdown setlocal nowrap | ||
911 | "autocmd Filetype c,cpp map <buffer><C-p> I//<esc> | ||
912 | autocmd Filetype c,cpp map <buffer><C-d> 0xx<esc>ta | ||
913 | "autocmd Filetype c,cpp vmap <buffer><C-p> <C-v>I//<esc> | ||
914 | "autocmd Filetype python map <buffer><C-p> I# <esc> | ||
915 | autocmd Filetype python map <buffer><C-d> 0xx<esc>ta | ||
916 | "autocmd Filetype python vmap <buffer><C-p> <C-v>I# <esc> | ||
917 | "autocmd Filetype c,cpp vmap <buffer><C-d> <C-v>0xx | ||
918 | "说明:本文件上文所有<Ctrl-p>的设置,原是用来为c,cpp,python文件设置注释的 | ||
919 | "但是注释可以通过<Ctrl-v>进入块选模式而后<Ctrl-i>进入插入模式 | ||
920 | "在前边输入注释符号,保存,则选中的行均被注释 | ||
921 | "甚为方便,因此这许多键一起弃用。</code></pre> | ||
922 | <p class="time">2023.7.5<br>2023.9.6改</p> | ||
923 | <script src="https://www.qin-juan-ge-zhu.top/common/js/comment.js"></script> | 226 | <script src="https://www.qin-juan-ge-zhu.top/common/js/comment.js"></script> |
924 | </div> | 227 | </div> |
925 | </div> | 228 | </div> |
diff --git a/code/linux/vim.md b/code/linux/vim.md index 51b9263..ec32d67 100644 --- a/code/linux/vim.md +++ b/code/linux/vim.md | |||
@@ -159,6 +159,8 @@ sudo make install | |||
159 | 159 | ||
160 | 安装完成后,可以在命令行中运行`vim --version`查看 vim 的版本信息,确认是否支持你需要的功能。 | 160 | 安装完成后,可以在命令行中运行`vim --version`查看 vim 的版本信息,确认是否支持你需要的功能。 |
161 | 161 | ||
162 | 最后,将我的[编译安装脚本](https://file.qin-juan-ge-zhu.top/compile_vim.sh)奉上,供参考。 | ||
163 | |||
162 | # 我的 vim 配置 | 164 | # 我的 vim 配置 |
163 | 165 | ||
164 | 网上一般的教程都说 vim 的默认配置文件为`~/.vimrc`。这当然是不错的,但是有一个巨大的问题:家目录是随着用户而不同的,这会导致我们以当前普通用户打开 vim 编辑文件与以 root 用户使用 vim 的观感完全不一致,就很烦。 | 166 | 网上一般的教程都说 vim 的默认配置文件为`~/.vimrc`。这当然是不错的,但是有一个巨大的问题:家目录是随着用户而不同的,这会导致我们以当前普通用户打开 vim 编辑文件与以 root 用户使用 vim 的观感完全不一致,就很烦。 |
@@ -182,397 +184,24 @@ mkdir bundle | |||
182 | 184 | ||
183 | ## 设置 | 185 | ## 设置 |
184 | 186 | ||
185 | 下文所有设置的目录均为`~/useful/vim`,也即`/etc/vim`。由于内容过多,我在目录下创建了`vimrcs`文件夹,将不同内容分别以专门文件管理,vimrc 文件调用这些文件。因此,下边只有`vimrc`在`/etc/vim`下;其他文件均在`/etc/vim/vimrcs`下,以`./vimrcs/<文件名>`表示。插件放置在`~/useful/bundle`。 | 187 | 这里原本记录着我的旧版 vim 配置,但随着[http 浏览服务器文件](https://www.qin-juan-ge-zhu.top/code/linux/httpmyserver.html)的完成,再保留旧版然后每隔三四个月更新一次,对于我这种没事就折腾的人来说说,就显得不那么必要了。因此,这里只简单说一下。 |
186 | 188 | ||
187 | ### ./vimrc | 189 | 配置的整体结构如下: |
188 | 190 | ||
189 | ```vim | 191 | ```plaintext |
190 | " Vundle插件管理及插件内容 | 192 | /etc/vim |
191 | if filereadable(expand("/etc/vim/vimrcs/plugs.vim")) | 193 | ├── vimrc # vim配置文件,负责引入不同的配置模块 |
192 | source /etc/vim/vimrcs/plugs.vim | 194 | ├── vimrc_origin # 原有配置脚本备份 |
193 | endif | 195 | ├── vimrcs # 我的配置文件夹,里边是不同的配置模块 |
194 | 196 | │ ├── autocmd.vim | |
195 | " 自行设置 | 197 | │ ├── codecmd.vim |
196 | if filereadable(expand("/etc/vim/vimrcs/myset.vim")) | 198 | │ ├── keybind.vim |
197 | source /etc/vim/vimrcs/myset.vim | 199 | │ ├── match.vim |
198 | endif | 200 | │ ├── myset.vim |
199 | 201 | │ ├── plugs.vim | |
200 | " 符号自动匹配 | 202 | │ └── statusline.vim |
201 | if filereadable(expand("/etc/vim/vimrcs/match.vim")) | 203 | ├── vimrc.tiny # 原有脚本,无用 |
202 | source /etc/vim/vimrcs/match.vim | 204 | └── vimscript.vim # 原有脚本,无用 |
203 | endif | ||
204 | |||
205 | " 不知道是什么 | ||
206 | if filereadable(expand("/etc/vim/vimrcs/fuck.vim")) | ||
207 | source /etc/vim/vimrcs/fuck.vim | ||
208 | endif | ||
209 | |||
210 | " 自己设的快捷键 | ||
211 | if filereadable(expand("/etc/vim/vimrcs/keybind.vim")) | ||
212 | source /etc/vim/vimrcs/keybind.vim | ||
213 | endif | ||
214 | |||
215 | " 自动命令 | ||
216 | if filereadable(expand("/etc/vim/vimrcs/autocmd.vim")) | ||
217 | source /etc/vim/vimrcs/autocmd.vim | ||
218 | endif | ||
219 | ``` | ||
220 | |||
221 | ### ./vimrcs/plugs.vim | ||
222 | |||
223 | ```vim" Vundle插件管理器配置 | ||
224 | set nocompatible "去除VIM一致性,必须 | ||
225 | filetype off "必须 | ||
226 | |||
227 | "设置包括vundle和初始化相关的运行时路径 | ||
228 | set rtp+=/home/player/useful/bundle/Vundle.vim | ||
229 | call vundle#begin('/home/player/useful/bundle') | ||
230 | |||
231 | Plugin 'VundleVim/Vundle.vim' "启用vundle管理插件,必须 | ||
232 | Plugin 'Valloric/YouCompleteMe' "代码补全插件 | ||
233 | Plugin 'preservim/nerdtree' "文件目录树插件 | ||
234 | Plugin 'Xuyuanp/nerdtree-git-plugin' "nerdtree git支持 | ||
235 | Plugin 'skywind3000/vim-terminal-help' "vim-terminal-help插件 | ||
236 | Plugin 'scrooloose/syntastic' "语法检查插件 | ||
237 | Plugin 'Lokaltog/powerline',{'rtp':'powerline/bindings/vim/'} "状态栏信息插件 | ||
238 | Plugin 'ianva/vim-youdao-translater' "有道翻译插件 | ||
239 | Plugin 'github/copilot.vim' "GitHub Copilot插件 | ||
240 | |||
241 | "在此增加其他插件,安装的插件需要放在vundle#begin和vundle#end之间 | ||
242 | "安装github上的插件格式为 Plugin '用户名/插件仓库名' | ||
243 | |||
244 | call vundle#end() | ||
245 | |||
246 | filetype plugin indent on "加载vim自带和插件相应的语法和文件类型相关脚本,必须 | ||
247 | |||
248 | " YouCompleteMe | ||
249 | let g:ycm_global_ycm_extra_conf='/home/player/useful/bundle/YouCompleteMe/.ycm_extra_conf.py' | ||
250 | let g:ycm_key_invoke_completion = '<C-c>' | ||
251 | let g:ycm_semantic_triggers = { | ||
252 | \ 'c,cpp,python,java,go,erlang,perl': ['re!\w{2}'], | ||
253 | \ 'cs,lua,javascript': ['re!\w{2}'], | ||
254 | \ } | ||
255 | highlight PMenu ctermfg=34 ctermbg=21 guifg=darkred guibg=darkblue | ||
256 | highlight PMenuSel ctermfg=21 ctermbg=34 guifg=darkblue guibg=darkred | ||
257 | let g:ycm_autoclose_preview_window_after_completion=1 "窗口在完成操作后消失 | ||
258 | map <leader>g :YcmCompleter GoToDefinitionElseDeclaration<CR> "找到当前内容定义位置的快捷方式 | ||
259 | |||
260 | "NERDTree | ||
261 | autocmd vimenter * NERDTree "进入vim自动打开nerdtree | ||
262 | autocmd bufenter * if(winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif "当nerdtree为剩余唯一窗口时自动关闭 | ||
263 | map <F2> :NERDTreeToggle<CR> "F2键开关文件目录树,注意shift+i切换是否显示隐藏文件 | ||
264 | let g:NERDTreeDirArrowExpandable = '+' | ||
265 | let g:NERDTreeDirArrowCollapsible = '-' "修改树的显示图标 | ||
266 | "let g:NERDTreeWinPos='left' "窗口位置 | ||
267 | let g:NERDTreeSize=10"窗口尺寸 | ||
268 | let g:NERDTreeShowLineNumbers=1 "窗口是否显示行号 | ||
269 | "let g:NERDTreeHidden=1 "似乎是隐藏文件的旧命令?没看到作用 | ||
270 | let NERDTreeShowHidden=1 " 显示隐藏文件 | ||
271 | let NERDTreeIgnore = ['\.pyc$', '\.swp', '\.swo', '\.vscode', '__pycache__'] " 过滤: 所有指定文件和文件夹不显示 | ||
272 | autocmd BufWinEnter * if getcmdwintype() == '' | silent NERDTreeMirror | endif " 在每个标签页打开相同的文件树 | ||
273 | let g:NERDtreeNodeDelimiter = "\u00a0" | ||
274 | |||
275 | |||
276 | "nerdtree-git-plugin | ||
277 | let g:NERDTreeGitStatusIndicatorMapCustom = { | ||
278 | \ 'Dirty' :'Dir', | ||
279 | \ 'Modified' :'M', | ||
280 | \ 'Staged' :'S', | ||
281 | \ 'Untracked' :'U', | ||
282 | \ 'Renamed' :'R', | ||
283 | \ 'Unmerged' :'UM', | ||
284 | \ 'Deleted' :'X', | ||
285 | \ 'Ignored' :'Ig', | ||
286 | \ 'Clean' :'Cl', | ||
287 | \ 'Unknown' :'?', | ||
288 | \ } | ||
289 | let g:NERDTreeGitStatusShowIgnored = 1 " a heavy feature may cost much more time. default: 0 | ||
290 | let g:NERDTreeGitStatusUntrackedFilesMode = 'all' " a heavy feature too. default: normal | ||
291 | "let g:NERDTreeGitStatusGitBinPath = '/your/file/path' " default: git (auto find in path) | ||
292 | |||
293 | "vim-terminal-help | ||
294 | set termwinsize=10*106 | ||
295 | |||
296 | "syntastic | ||
297 | "以下内容是syntastic插件的一般配置,由于YouCompleteMe插件对该插件支持过于优秀,一般不再需要配置,故废弃 | ||
298 | "set statusline+=%#warningmsg# | ||
299 | "set statusline+=%{syntasticstatuslineflag()} | ||
300 | "set statusline+=%* | ||
301 | " | ||
302 | "let g:syntastic_always_populate_loc_list = 1 | ||
303 | "let g:syntastic_auto_loc_list = 1 | ||
304 | "let g:syntastic_check_on_open = 1 | ||
305 | "let g:syntastic_check_on_wq = 0 | ||
306 | ""设置error和warning的标志 | ||
307 | "let g:syntastic_enable_signs = 1 | ||
308 | ""let g:syntastic_error_symbol='?' | ||
309 | "let g:syntastic_warning_symbol='?' | ||
310 | ""no-unused-args 忽略不使用的参数 | ||
311 | ""no-redefined 忽略重定义 | ||
312 | ""no-max-line-length 忽略每行最长的检测 | ||
313 | ""ignore 542 551 忽略if条件的body为空(如...elseif ret == nil then end,then和end中间没有语句);忽略空语句(如;),如果用了;则成对出现该语法检测warning | ||
314 | ""有语法错误的一行左侧栏会有s>标识,光标移动到改行,vim下发会给出提示。修改正确后保存,则该's>'会消失。 | ||
315 | "let g:syntastic_lua_checkers = ["/usr/bin/luac5.3.5", "luacheck"] | ||
316 | "let g:syntastic_lua_luacheck_args = "--codes --no-max-comment-line-length --ignore 542 551" | ||
317 | " | ||
318 | ""c | ||
319 | ""let g:syntastic_c_compiler =['gcc', 'clang', 'make'] | ||
320 | ""let g:syntastic_c_compiler_options ='-wpedantic -g' | ||
321 | "let g:syntastic_c_compiler_options ='-std=gnu99' | ||
322 | "let g:syntastic_c_include_dirs=['/usr/include/'] | ||
323 | "let g:syntastic_c_config_file='.syntastic_c_config_file' | ||
324 | " | ||
325 | ""cpp | ||
326 | "let g:syntastic_cpp_include_dirs = ['/usr/include/'] | ||
327 | "let g:syntastic_cpp_remove_include_errors = 1 | ||
328 | "let g:syntastic_cpp_check_header = 1 | ||
329 | "let g:syntastic_cpp_compiler = 'clang++' | ||
330 | "let g:syntastic_cpp_compiler_options = '-std=c++11 -stdlib=libstdc++' | ||
331 | "" syntastic end | ||
332 | let g:syntastic_python_checkers=['pylint'] | ||
333 | let g:syntastic_python_pylint_args=['--disable=C0111,R0903,C0301'] | ||
334 | |||
335 | |||
336 | " powerline | ||
337 | let laststatus=2 | ||
338 | let g:airlinr_powerline_fonts=1 "使用官方打过补丁的字体 | ||
339 | let g:Powerline_symbols='fancy' | ||
340 | |||
341 | "vim-youdao-translater | ||
342 | vnoremap <silent> <C-t> :<C-u>Ydv<CR> | ||
343 | nnoremap <silent> <C-t> :<C-u>Ydc<CR> | ||
344 | noremap <leader>yd: <C-u>Yde<CR> | ||
345 | ``` | 205 | ``` |
346 | 206 | ||
347 | ### ./vimrcs/myset.vim | 207 | 我直接把我服务器上的配置文件[放在这里](https://file.qin-juan-ge-zhu.top/useful/vim/),以供查看。 |
348 | |||
349 | ```vim | ||
350 | set nocp "设置兼容 | ||
351 | set expandtab "设置tab | ||
352 | set shiftwidth=4 "设置tab的间隔 | ||
353 | set tabstop=4 "四个空格代表一个tab | ||
354 | set sts=4 | ||
355 | set showmatch "在输入括号时光标会短暂地跳到与之相匹配的括号处 | ||
356 | set autoindent "设置自动缩进 | ||
357 | " set smartindent "设置智能缩进 | ||
358 | set nowrap "设置自动换行 | ||
359 | set tw=500 | ||
360 | set lbr | ||
361 | set foldmethod=indent "设置按缩进折叠代码 | ||
362 | set foldlevel=99 "折叠层级 | ||
363 | nnoremap <space> za "空格代替za进行展开和折叠 | ||
364 | "===set guifont=Monospace "设置字体大小 | ||
365 | set guifont=:b:h16 | ||
366 | set encoding=utf-8 "设置编码为utf-8 | ||
367 | set fileencoding=utf-8 | ||
368 | set fileencodings=ucs-bom,utf-8,GB18030,cp936,big5,euc-jp,euc-kr,latin1 | ||
369 | set helplang=cn "帮助中文支持 | ||
370 | "colorscheme evening "设置主体颜色 | ||
371 | set mouse=a " 设置鼠标 | ||
372 | |||
373 | "自动补全配置 | ||
374 | autocmd FileType python set omnifunc=pythoncomplete#Complete | ||
375 | autocmd FileType javascript set omnifunc=javascriptcomplete#CompleteJS | ||
376 | autocmd FileType html set omnifunc=htmlcomplete#CompleteTags | ||
377 | autocmd FileType css set omnifunc=csscomplete#CompleteCSS | ||
378 | autocmd FileType xml set omnifunc=xmlcomplete#CompleteTags | ||
379 | autocmd FileType php set omnifunc=phpcomplete#CompletePHP | ||
380 | autocmd FileType c set omnifunc=ccomplete#Complete | ||
381 | |||
382 | "进行Taglist的设置 | ||
383 | map <F3> :TlistToggle<CR> | ||
384 | "map <F3> :silent! Tlist<CR> "按下F3就可以呼出了 | ||
385 | "let Tlist_Ctags_Cmd='/usr/bin/ctags' "因为我们放在环境变量里,所以可以直接执行 | ||
386 | let Tlist_Use_Right_Window=1 "让窗口显示在右边,0的话就是显示在左边 | ||
387 | "let Tlist_Show_One_File=1 "让taglist可以同时展示多个文件的函数列表 | ||
388 | "let Tlist_File_Fold_Auto_Close=1 "非当前文件,函数列表折叠隐藏 | ||
389 | "let Tlist_Exit_OnlyWindow=1 "当taglist是最后一个分割窗口时,自动推出vim | ||
390 | "let Tlist_Process_File_Always=0 "是否一直处理tags.1:处理;0:不处理 | ||
391 | "let Tlist_Inc_Winwidth=0 "不是一直实时更新tags,因为没有必要 | ||
392 | |||
393 | set rnu "设置相对行号 | ||
394 | set nu "设置绝对行号 | ||
395 | " Set cursor shape and color | ||
396 | if &term =~ "xterm" | ||
397 | " INSERT mode | ||
398 | let &t_SI = "\<Esc>[6 q" . "\<Esc>]12;blue\x7" | ||
399 | " REPLACE mode | ||
400 | let &t_SR = "\<Esc>[3 q" . "\<Esc>]12;black\x7" | ||
401 | " NORMAL mode | ||
402 | let &t_EI = "\<Esc>[2 q" . "\<Esc>]12;green\x7" | ||
403 | endif | ||
404 | " 1 -> blinking block 闪烁的方块 | ||
405 | " 2 -> solid block 不闪烁的方块 | ||
406 | " 3 -> blinking underscore 闪烁的下划线 | ||
407 | " 4 -> solid underscore 不闪烁的下划线 | ||
408 | " 5 -> blinking vertical bar 闪烁的竖线 | ||
409 | " 6 -> solid vertical bar 不闪烁的竖线 | ||
410 | |||
411 | syntax on | ||
412 | set cul | ||
413 | set cuc | ||
414 | hi CursorLine cterm=NONE ctermbg=darkred ctermfg=white guibg=darkred guifg=white | ||
415 | ""set lines=35 columns=118 | ||
416 | colorscheme zaibatsu "设置颜色主题 | ||
417 | set wrap "设置自动折行 | ||
418 | ``` | ||
419 | |||
420 | ### ./vimrcs/match.vim | ||
421 | |||
422 | ```vim | ||
423 | "各类符号自动匹配 | ||
424 | :inoremap ( ()<ESC>i | ||
425 | :inoremap ) <c-r>=ClosePair(')')<CR> | ||
426 | :inoremap { {}<ESC>i | ||
427 | :inoremap } <c-r>=ClosePair('}')<CR> | ||
428 | :inoremap [ []<ESC>i | ||
429 | :inoremap ] <c-r>=ClosePair(']')<CR> | ||
430 | |||
431 | function ClosePair(char) | ||
432 | if getline('.')[col('.') - 1] == a:char | ||
433 | return "<Right>" | ||
434 | else | ||
435 | return a:char | ||
436 | endif | ||
437 | endfunction | ||
438 | ``` | ||
439 | |||
440 | ### ./vimrcs/fuck.vim | ||
441 | |||
442 | ```vim | ||
443 | " 键盘映射设置区域 | ||
444 | |||
445 | " 对应使用函数的配置 | ||
446 | set guitablabel=%{ShortTabLabel()} | ||
447 | function ShortTabLabel () | ||
448 | let bufnrlist = tabpagebuflist (v:lnum) | ||
449 | let label = bufname (bufnrlist[tabpagewinnr (v:lnum) -1]) | ||
450 | let filename = fnamemodify (label, ':t') | ||
451 | return filename | ||
452 | endfunction | ||
453 | |||
454 | set tabline=%!MyTabLine() | ||
455 | function MyTabLine() | ||
456 | let s = '' | ||
457 | for i in range(tabpagenr('$')) | ||
458 | " 选择高亮 | ||
459 | if i + 1 == tabpagenr() | ||
460 | let s .= '%#TabLineSel#' | ||
461 | else | ||
462 | let s .= '%#TabLine#' | ||
463 | endif | ||
464 | " 设置标签页号 (用于鼠标点击) | ||
465 | let s .= '%' . (i + 1) . 'T' | ||
466 | " MyTabLabel() 提供完整路径标签 MyShortTabLabel 提供文件名标签 | ||
467 | let s .= ' %{MyShortTabLabel(' . (i + 1) . ')} ' | ||
468 | endfor | ||
469 | " 最后一个标签页之后用 TabLineFill 填充并复位标签页号 | ||
470 | let s .= '%#TabLineFill#%T' | ||
471 | " 右对齐用于关闭当前标签页的标签 | ||
472 | if tabpagenr('$') > 1 | ||
473 | let s .= '%=%#TabLine#%999Xclose' | ||
474 | endif | ||
475 | return s | ||
476 | endfunction | ||
477 | " 文件名标签 | ||
478 | function MyShortTabLabel(n) | ||
479 | let buflist = tabpagebuflist(a:n) | ||
480 | let label = bufname (buflist[tabpagewinnr (a:n) -1]) | ||
481 | let filename = fnamemodify (label, ':t') | ||
482 | return filename | ||
483 | endfunction | ||
484 | "完整路径标签 | ||
485 | function MyTabLabel(n) | ||
486 | let buflist = tabpagebuflist(a:n) | ||
487 | let winnr = tabpagewinnr(a:n) | ||
488 | return bufname(buflist[winnr - 1]) | ||
489 | endfunction | ||
490 | " vim 标签样式 | ||
491 | " TabLineFill tab pages line, where there are no labels | ||
492 | hi TabLineFill term=none | ||
493 | hi TabLineFill ctermfg=DarkGrey | ||
494 | hi TabLineFill guifg=#777777 | ||
495 | " TabLineSel tab pages line, active tab page label | ||
496 | hi TabLineSel term=inverse | ||
497 | hi TabLineSel cterm=none ctermfg=yellow ctermbg=Black | ||
498 | hi TabLineSel gui=none guifg=yellow guibg=Black | ||
499 | |||
500 | " Develop editing options | ||
501 | au FileType vim setl expandtab | ||
502 | au FileType vim setl shiftwidth=2 | ||
503 | au FileType vim setl tabstop=2 | ||
504 | |||
505 | " 显示状态栏(默认值为 1,无法显示状态栏) | ||
506 | set laststatus=2 | ||
507 | " Format the statusline | ||
508 | " set statusline= %f %m %r %h %w CWD: %r%{CurDir()}E5%h Line: %l/%L:%c | ||
509 | |||
510 | function! CurDir() | ||
511 | let curdir = substitute(getcwd(), '/Users/amir/', "~/", "g") | ||
512 | return curdir | ||
513 | endfunction | ||
514 | ``` | ||
515 | |||
516 | ### ./vimrcs/keybind.vim | ||
517 | |||
518 | ```vim | ||
519 | map - dd | ||
520 | map up 20k | ||
521 | map ne 20j | ||
522 | map end G | ||
523 | map ta $ | ||
524 | "map <C-l> <C-w-l> | ||
525 | nmap <C-tab> :tabn<CR> | ||
526 | nmap <tab> :tabp<CR> | ||
527 | "nmap <alt-tab> :tabnew<CR> | ||
528 | map <space>= <buffer><esc>:vertical resize +5<cr> | ||
529 | map <space>- <esc>:vertical resize -5<cr> | ||
530 | |||
531 | nn <M-1> 1gt | ||
532 | nn <M-2> 2gt | ||
533 | nn <M-3> 3gt | ||
534 | nn <M-4> 4gt | ||
535 | nn <M-5> 5gt | ||
536 | nn <M-6> 6gt | ||
537 | nn <M-7> 7gt | ||
538 | nn <M-8> 8gt | ||
539 | nn <M-9> 9gt | ||
540 | nn <M-0> :tablast<CR> | ||
541 | |||
542 | "光标在页面间切换 | ||
543 | nnoremap <space>h <C-w><C-h> | ||
544 | nnoremap <space>j <C-w><C-j> | ||
545 | nnoremap <space>k <C-w><C-k> | ||
546 | nnoremap <space>l <C-w><C-l> | ||
547 | |||
548 | "复制粘贴 | ||
549 | "vnoremap <C-y> "+y | ||
550 | "nnoremap <C-p> "+p | ||
551 | |||
552 | " 其他开发配置 | ||
553 | " Python | ||
554 | au BufNewFile,BufRead *.py | ||
555 | \ set tabstop=4 | | ||
556 | \ set shiftwidth=4 | | ||
557 | \ set textwidth=79 | | ||
558 | \ set expandtab | | ||
559 | \ set autoindent | | ||
560 | \ set fileformat=unix | | ||
561 | ``` | ||
562 | |||
563 | ### ./vimrcs/autocmd.vim | ||
564 | |||
565 | ```vim | ||
566 | autocmd BufReadPost,BufWritePre *.html,*.c,*.cpp normal gg=G | ||
567 | autocmd Filetype html,markdown setlocal nowrap | ||
568 | "autocmd Filetype c,cpp map <buffer><C-p> I//<esc> | ||
569 | autocmd Filetype c,cpp map <buffer><C-d> 0xx<esc>ta | ||
570 | "autocmd Filetype c,cpp vmap <buffer><C-p> <C-v>I//<esc> | ||
571 | "autocmd Filetype python map <buffer><C-p> I# <esc> | ||
572 | autocmd Filetype python map <buffer><C-d> 0xx<esc>ta | ||
573 | "autocmd Filetype python vmap <buffer><C-p> <C-v>I# <esc> | ||
574 | "autocmd Filetype c,cpp vmap <buffer><C-d> <C-v>0xx | ||
575 | "说明:本文件上文所有<Ctrl-p>的设置,原是用来为c,cpp,python文件设置注释的 | ||
576 | "但是注释可以通过<Ctrl-v>进入块选模式而后<Ctrl-i>进入插入模式,在前边输入注释符号,保存,则选中的行均被注释 | ||
577 | "甚为方便,因此这许多键一起弃用。 | ||
578 | ``` | ||
diff --git a/code/stdc++.html b/code/stdc++.html deleted file mode 100644 index 1706db0..0000000 --- a/code/stdc++.html +++ /dev/null | |||
@@ -1,892 +0,0 @@ | |||
1 | <!doctype html> | ||
2 | <html> | ||
3 | |||
4 | <head> | ||
5 | <meta charset='UTF-8'> | ||
6 | <meta name='viewport' content='width=device-width initial-scale=1'> | ||
7 | <title>C++九千能头文件</title> | ||
8 | <link rel="stylesheet" href="https://www.qin-juan-ge-zhu.top/common/CSS/github.css"> | ||
9 | <script type="text/javascript" src="https://www.qin-juan-ge-zhu.top/common/script4code.js"></script> | ||
10 | </head> | ||
11 | |||
12 | <body class='typora-export os-windows'> | ||
13 | <div class='typora-export-content'> | ||
14 | <div id='write' class=''> | ||
15 | <pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" | ||
16 | lang="cpp" | ||
17 | style="break-inside: unset;"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="cpp"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 9.51875px; left: 53px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 45px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre> | ||
18 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt"> | ||
19 | <div>120</div> | ||
20 | </div> | ||
21 | </div> | ||
22 | <div class="CodeMirror-measure"></div> | ||
23 | <div style="position: relative; z-index: 1;"></div> | ||
24 | <div class="CodeMirror-code" role="presentation" style=""> | ||
25 | <div class="CodeMirror-activeline" style="position: relative;"> | ||
26 | <div class="CodeMirror-activeline-background CodeMirror-linebackground"></div> | ||
27 | <div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" | ||
28 | style="left: -45px; width: 45px;"></div> | ||
29 | <div class="CodeMirror-gutter-wrapper CodeMirror-activeline-gutter" style="left: -45px;"> | ||
30 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" | ||
31 | style="left: 0px; width: 36px;">1</div> | ||
32 | </div> | ||
33 | <pre class=" CodeMirror-line " | ||
34 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// C++ includes used for precompiling -*- C++ -*-</span></span></pre> | ||
35 | </div> | ||
36 | <div style="position: relative;"> | ||
37 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
38 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">2</div> | ||
39 | </div> | ||
40 | <pre class=" CodeMirror-line " | ||
41 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"> </span></pre> | ||
42 | </div> | ||
43 | <div style="position: relative;"> | ||
44 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
45 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">3</div> | ||
46 | </div> | ||
47 | <pre class=" CodeMirror-line " | ||
48 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// Copyright (C) 2003-2013 Free Software Foundation, Inc.</span></span></pre> | ||
49 | </div> | ||
50 | <div style="position: relative;"> | ||
51 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
52 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">4</div> | ||
53 | </div> | ||
54 | <pre class=" CodeMirror-line " | ||
55 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">//</span></span></pre> | ||
56 | </div> | ||
57 | <div style="position: relative;"> | ||
58 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
59 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">5</div> | ||
60 | </div> | ||
61 | <pre class=" CodeMirror-line " | ||
62 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// This file is part of the GNU ISO C++ Library. This library is free</span></span></pre> | ||
63 | </div> | ||
64 | <div style="position: relative;"> | ||
65 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
66 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">6</div> | ||
67 | </div> | ||
68 | <pre class=" CodeMirror-line " | ||
69 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// software; you can redistribute it and/or modify it under the</span></span></pre> | ||
70 | </div> | ||
71 | <div style="position: relative;"> | ||
72 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
73 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">7</div> | ||
74 | </div> | ||
75 | <pre class=" CodeMirror-line " | ||
76 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// terms of the GNU General Public License as published by the</span></span></pre> | ||
77 | </div> | ||
78 | <div style="position: relative;"> | ||
79 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
80 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">8</div> | ||
81 | </div> | ||
82 | <pre class=" CodeMirror-line " | ||
83 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// Free Software Foundation; either version 3, or (at your option)</span></span></pre> | ||
84 | </div> | ||
85 | <div style="position: relative;"> | ||
86 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
87 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">9</div> | ||
88 | </div> | ||
89 | <pre class=" CodeMirror-line " | ||
90 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// any later version.</span></span></pre> | ||
91 | </div> | ||
92 | <div style="position: relative;"> | ||
93 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
94 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" | ||
95 | style="left: 0px; width: 36px;">10</div> | ||
96 | </div> | ||
97 | <pre class=" CodeMirror-line " | ||
98 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"> </span></pre> | ||
99 | </div> | ||
100 | <div style="position: relative;"> | ||
101 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
102 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">11</div> | ||
103 | </div> | ||
104 | <pre class=" CodeMirror-line " | ||
105 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// This library is distributed in the hope that it will be useful,</span></span></pre> | ||
106 | </div> | ||
107 | <div style="position: relative;"> | ||
108 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
109 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">12</div> | ||
110 | </div> | ||
111 | <pre class=" CodeMirror-line " | ||
112 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// but WITHOUT ANY WARRANTY; without even the implied warranty of</span></span></pre> | ||
113 | </div> | ||
114 | <div style="position: relative;"> | ||
115 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
116 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">13</div> | ||
117 | </div> | ||
118 | <pre class=" CodeMirror-line " | ||
119 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span></span></pre> | ||
120 | </div> | ||
121 | <div style="position: relative;"> | ||
122 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
123 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">14</div> | ||
124 | </div> | ||
125 | <pre class=" CodeMirror-line " | ||
126 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// GNU General Public License for more details.</span></span></pre> | ||
127 | </div> | ||
128 | <div style="position: relative;"> | ||
129 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
130 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">15</div> | ||
131 | </div> | ||
132 | <pre class=" CodeMirror-line " | ||
133 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"> </span></pre> | ||
134 | </div> | ||
135 | <div style="position: relative;"> | ||
136 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
137 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">16</div> | ||
138 | </div> | ||
139 | <pre class=" CodeMirror-line " | ||
140 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// Under Section 7 of GPL version 3, you are granted additional</span></span></pre> | ||
141 | </div> | ||
142 | <div style="position: relative;"> | ||
143 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
144 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">17</div> | ||
145 | </div> | ||
146 | <pre class=" CodeMirror-line " | ||
147 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// permissions described in the GCC Runtime Library Exception, version</span></span></pre> | ||
148 | </div> | ||
149 | <div style="position: relative;"> | ||
150 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
151 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">18</div> | ||
152 | </div> | ||
153 | <pre class=" CodeMirror-line " | ||
154 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// 3.1, as published by the Free Software Foundation.</span></span></pre> | ||
155 | </div> | ||
156 | <div style="position: relative;"> | ||
157 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
158 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">19</div> | ||
159 | </div> | ||
160 | <pre class=" CodeMirror-line " | ||
161 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"> </span></pre> | ||
162 | </div> | ||
163 | <div style="position: relative;"> | ||
164 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
165 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" | ||
166 | style="left: 0px; width: 36px;">20</div> | ||
167 | </div> | ||
168 | <pre class=" CodeMirror-line " | ||
169 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// You should have received a copy of the GNU General Public License and</span></span></pre> | ||
170 | </div> | ||
171 | <div style="position: relative;"> | ||
172 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
173 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">21</div> | ||
174 | </div> | ||
175 | <pre class=" CodeMirror-line " | ||
176 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// a copy of the GCC Runtime Library Exception along with this program;</span></span></pre> | ||
177 | </div> | ||
178 | <div style="position: relative;"> | ||
179 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
180 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">22</div> | ||
181 | </div> | ||
182 | <pre class=" CodeMirror-line " | ||
183 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see</span></span></pre> | ||
184 | </div> | ||
185 | <div style="position: relative;"> | ||
186 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
187 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">23</div> | ||
188 | </div> | ||
189 | <pre class=" CodeMirror-line " | ||
190 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// <Licenses - GNU Project - Free Software Foundation>.</span></span></pre> | ||
191 | </div> | ||
192 | <div style="position: relative;"> | ||
193 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
194 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">24</div> | ||
195 | </div> | ||
196 | <pre class=" CodeMirror-line " | ||
197 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"> </span></pre> | ||
198 | </div> | ||
199 | <div style="position: relative;"> | ||
200 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
201 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">25</div> | ||
202 | </div> | ||
203 | <pre class=" CodeMirror-line " | ||
204 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">/** @file stdc++.h</span></span></pre> | ||
205 | </div> | ||
206 | <div style="position: relative;"> | ||
207 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
208 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">26</div> | ||
209 | </div> | ||
210 | <pre class=" CodeMirror-line " | ||
211 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-comment">* This is an implementation file for a precompiled header.</span></span></pre> | ||
212 | </div> | ||
213 | <div style="position: relative;"> | ||
214 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
215 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">27</div> | ||
216 | </div> | ||
217 | <pre class=" CodeMirror-line " | ||
218 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-comment">*/</span></span></pre> | ||
219 | </div> | ||
220 | <div style="position: relative;"> | ||
221 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
222 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">28</div> | ||
223 | </div> | ||
224 | <pre class=" CodeMirror-line " | ||
225 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"> </span></pre> | ||
226 | </div> | ||
227 | <div style="position: relative;"> | ||
228 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
229 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">29</div> | ||
230 | </div> | ||
231 | <pre class=" CodeMirror-line " | ||
232 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// 17.4.1.2 Headers</span></span></pre> | ||
233 | </div> | ||
234 | <div style="position: relative;"> | ||
235 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
236 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" | ||
237 | style="left: 0px; width: 36px;">30</div> | ||
238 | </div> | ||
239 | <pre class=" CodeMirror-line " | ||
240 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"> </span></pre> | ||
241 | </div> | ||
242 | <div style="position: relative;"> | ||
243 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
244 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">31</div> | ||
245 | </div> | ||
246 | <pre class=" CodeMirror-line " | ||
247 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// C</span></span></pre> | ||
248 | </div> | ||
249 | <div style="position: relative;"> | ||
250 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
251 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">32</div> | ||
252 | </div> | ||
253 | <pre class=" CodeMirror-line " | ||
254 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#ifndef _GLIBCXX_NO_ASSERT</span></span></pre> | ||
255 | </div> | ||
256 | <div style="position: relative;"> | ||
257 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
258 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">33</div> | ||
259 | </div> | ||
260 | <pre class=" CodeMirror-line " | ||
261 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <cassert></span></span></pre> | ||
262 | </div> | ||
263 | <div style="position: relative;"> | ||
264 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
265 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">34</div> | ||
266 | </div> | ||
267 | <pre class=" CodeMirror-line " | ||
268 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#endif</span></span></pre> | ||
269 | </div> | ||
270 | <div style="position: relative;"> | ||
271 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
272 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">35</div> | ||
273 | </div> | ||
274 | <pre class=" CodeMirror-line " | ||
275 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <cctype></span></span></pre> | ||
276 | </div> | ||
277 | <div style="position: relative;"> | ||
278 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
279 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">36</div> | ||
280 | </div> | ||
281 | <pre class=" CodeMirror-line " | ||
282 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <cerrno></span></span></pre> | ||
283 | </div> | ||
284 | <div style="position: relative;"> | ||
285 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
286 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">37</div> | ||
287 | </div> | ||
288 | <pre class=" CodeMirror-line " | ||
289 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <cfloat></span></span></pre> | ||
290 | </div> | ||
291 | <div style="position: relative;"> | ||
292 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
293 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">38</div> | ||
294 | </div> | ||
295 | <pre class=" CodeMirror-line " | ||
296 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <ciso646></span></span></pre> | ||
297 | </div> | ||
298 | <div style="position: relative;"> | ||
299 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
300 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">39</div> | ||
301 | </div> | ||
302 | <pre class=" CodeMirror-line " | ||
303 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <climits></span></span></pre> | ||
304 | </div> | ||
305 | <div style="position: relative;"> | ||
306 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
307 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" | ||
308 | style="left: 0px; width: 36px;">40</div> | ||
309 | </div> | ||
310 | <pre class=" CodeMirror-line " | ||
311 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <clocale></span></span></pre> | ||
312 | </div> | ||
313 | <div style="position: relative;"> | ||
314 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
315 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">41</div> | ||
316 | </div> | ||
317 | <pre class=" CodeMirror-line " | ||
318 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <cmath></span></span></pre> | ||
319 | </div> | ||
320 | <div style="position: relative;"> | ||
321 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
322 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">42</div> | ||
323 | </div> | ||
324 | <pre class=" CodeMirror-line " | ||
325 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <csetjmp></span></span></pre> | ||
326 | </div> | ||
327 | <div style="position: relative;"> | ||
328 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
329 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">43</div> | ||
330 | </div> | ||
331 | <pre class=" CodeMirror-line " | ||
332 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <csignal></span></span></pre> | ||
333 | </div> | ||
334 | <div style="position: relative;"> | ||
335 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
336 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">44</div> | ||
337 | </div> | ||
338 | <pre class=" CodeMirror-line " | ||
339 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <cstdarg></span></span></pre> | ||
340 | </div> | ||
341 | <div style="position: relative;"> | ||
342 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
343 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">45</div> | ||
344 | </div> | ||
345 | <pre class=" CodeMirror-line " | ||
346 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <cstddef></span></span></pre> | ||
347 | </div> | ||
348 | <div style="position: relative;"> | ||
349 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
350 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">46</div> | ||
351 | </div> | ||
352 | <pre class=" CodeMirror-line " | ||
353 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <cstdio></span></span></pre> | ||
354 | </div> | ||
355 | <div style="position: relative;"> | ||
356 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
357 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">47</div> | ||
358 | </div> | ||
359 | <pre class=" CodeMirror-line " | ||
360 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <cstdlib></span></span></pre> | ||
361 | </div> | ||
362 | <div style="position: relative;"> | ||
363 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
364 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">48</div> | ||
365 | </div> | ||
366 | <pre class=" CodeMirror-line " | ||
367 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <cstring></span></span></pre> | ||
368 | </div> | ||
369 | <div style="position: relative;"> | ||
370 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
371 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">49</div> | ||
372 | </div> | ||
373 | <pre class=" CodeMirror-line " | ||
374 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <ctime></span></span></pre> | ||
375 | </div> | ||
376 | <div style="position: relative;"> | ||
377 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
378 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" | ||
379 | style="left: 0px; width: 36px;">50</div> | ||
380 | </div> | ||
381 | <pre class=" CodeMirror-line " | ||
382 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"> </span></pre> | ||
383 | </div> | ||
384 | <div style="position: relative;"> | ||
385 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
386 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">51</div> | ||
387 | </div> | ||
388 | <pre class=" CodeMirror-line " | ||
389 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#if __cplusplus >= 201103L</span></span></pre> | ||
390 | </div> | ||
391 | <div style="position: relative;"> | ||
392 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
393 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">52</div> | ||
394 | </div> | ||
395 | <pre class=" CodeMirror-line " | ||
396 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <ccomplex></span></span></pre> | ||
397 | </div> | ||
398 | <div style="position: relative;"> | ||
399 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
400 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">53</div> | ||
401 | </div> | ||
402 | <pre class=" CodeMirror-line " | ||
403 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <cfenv></span></span></pre> | ||
404 | </div> | ||
405 | <div style="position: relative;"> | ||
406 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
407 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">54</div> | ||
408 | </div> | ||
409 | <pre class=" CodeMirror-line " | ||
410 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <cinttypes></span></span></pre> | ||
411 | </div> | ||
412 | <div style="position: relative;"> | ||
413 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
414 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">55</div> | ||
415 | </div> | ||
416 | <pre class=" CodeMirror-line " | ||
417 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <cstdalign></span></span></pre> | ||
418 | </div> | ||
419 | <div style="position: relative;"> | ||
420 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
421 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">56</div> | ||
422 | </div> | ||
423 | <pre class=" CodeMirror-line " | ||
424 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <cstdbool></span></span></pre> | ||
425 | </div> | ||
426 | <div style="position: relative;"> | ||
427 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
428 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">57</div> | ||
429 | </div> | ||
430 | <pre class=" CodeMirror-line " | ||
431 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <cstdint></span></span></pre> | ||
432 | </div> | ||
433 | <div style="position: relative;"> | ||
434 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
435 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">58</div> | ||
436 | </div> | ||
437 | <pre class=" CodeMirror-line " | ||
438 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <ctgmath></span></span></pre> | ||
439 | </div> | ||
440 | <div style="position: relative;"> | ||
441 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
442 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">59</div> | ||
443 | </div> | ||
444 | <pre class=" CodeMirror-line " | ||
445 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <cwchar></span></span></pre> | ||
446 | </div> | ||
447 | <div style="position: relative;"> | ||
448 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
449 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" | ||
450 | style="left: 0px; width: 36px;">60</div> | ||
451 | </div> | ||
452 | <pre class=" CodeMirror-line " | ||
453 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <cwctype></span></span></pre> | ||
454 | </div> | ||
455 | <div style="position: relative;"> | ||
456 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
457 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">61</div> | ||
458 | </div> | ||
459 | <pre class=" CodeMirror-line " | ||
460 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#endif</span></span></pre> | ||
461 | </div> | ||
462 | <div style="position: relative;"> | ||
463 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
464 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">62</div> | ||
465 | </div> | ||
466 | <pre class=" CodeMirror-line " | ||
467 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"> </span></pre> | ||
468 | </div> | ||
469 | <div style="position: relative;"> | ||
470 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
471 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">63</div> | ||
472 | </div> | ||
473 | <pre class=" CodeMirror-line " | ||
474 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">// C++</span></span></pre> | ||
475 | </div> | ||
476 | <div style="position: relative;"> | ||
477 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
478 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">64</div> | ||
479 | </div> | ||
480 | <pre class=" CodeMirror-line " | ||
481 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <algorithm></span></span></pre> | ||
482 | </div> | ||
483 | <div style="position: relative;"> | ||
484 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
485 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">65</div> | ||
486 | </div> | ||
487 | <pre class=" CodeMirror-line " | ||
488 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <bitset></span></span></pre> | ||
489 | </div> | ||
490 | <div style="position: relative;"> | ||
491 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
492 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">66</div> | ||
493 | </div> | ||
494 | <pre class=" CodeMirror-line " | ||
495 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <complex></span></span></pre> | ||
496 | </div> | ||
497 | <div style="position: relative;"> | ||
498 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
499 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">67</div> | ||
500 | </div> | ||
501 | <pre class=" CodeMirror-line " | ||
502 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <deque></span></span></pre> | ||
503 | </div> | ||
504 | <div style="position: relative;"> | ||
505 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
506 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">68</div> | ||
507 | </div> | ||
508 | <pre class=" CodeMirror-line " | ||
509 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <exception></span></span></pre> | ||
510 | </div> | ||
511 | <div style="position: relative;"> | ||
512 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
513 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">69</div> | ||
514 | </div> | ||
515 | <pre class=" CodeMirror-line " | ||
516 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <fstream></span></span></pre> | ||
517 | </div> | ||
518 | <div style="position: relative;"> | ||
519 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
520 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" | ||
521 | style="left: 0px; width: 36px;">70</div> | ||
522 | </div> | ||
523 | <pre class=" CodeMirror-line " | ||
524 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <functional></span></span></pre> | ||
525 | </div> | ||
526 | <div style="position: relative;"> | ||
527 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
528 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">71</div> | ||
529 | </div> | ||
530 | <pre class=" CodeMirror-line " | ||
531 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <iomanip></span></span></pre> | ||
532 | </div> | ||
533 | <div style="position: relative;"> | ||
534 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
535 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">72</div> | ||
536 | </div> | ||
537 | <pre class=" CodeMirror-line " | ||
538 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <ios></span></span></pre> | ||
539 | </div> | ||
540 | <div style="position: relative;"> | ||
541 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
542 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">73</div> | ||
543 | </div> | ||
544 | <pre class=" CodeMirror-line " | ||
545 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <iosfwd></span></span></pre> | ||
546 | </div> | ||
547 | <div style="position: relative;"> | ||
548 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
549 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">74</div> | ||
550 | </div> | ||
551 | <pre class=" CodeMirror-line " | ||
552 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <iostream></span></span></pre> | ||
553 | </div> | ||
554 | <div style="position: relative;"> | ||
555 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
556 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">75</div> | ||
557 | </div> | ||
558 | <pre class=" CodeMirror-line " | ||
559 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <istream></span></span></pre> | ||
560 | </div> | ||
561 | <div style="position: relative;"> | ||
562 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
563 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">76</div> | ||
564 | </div> | ||
565 | <pre class=" CodeMirror-line " | ||
566 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <iterator></span></span></pre> | ||
567 | </div> | ||
568 | <div style="position: relative;"> | ||
569 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
570 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">77</div> | ||
571 | </div> | ||
572 | <pre class=" CodeMirror-line " | ||
573 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <limits></span></span></pre> | ||
574 | </div> | ||
575 | <div style="position: relative;"> | ||
576 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
577 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">78</div> | ||
578 | </div> | ||
579 | <pre class=" CodeMirror-line " | ||
580 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <list></span></span></pre> | ||
581 | </div> | ||
582 | <div style="position: relative;"> | ||
583 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
584 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">79</div> | ||
585 | </div> | ||
586 | <pre class=" CodeMirror-line " | ||
587 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <locale></span></span></pre> | ||
588 | </div> | ||
589 | <div style="position: relative;"> | ||
590 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
591 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" | ||
592 | style="left: 0px; width: 36px;">80</div> | ||
593 | </div> | ||
594 | <pre class=" CodeMirror-line " | ||
595 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <map></span></span></pre> | ||
596 | </div> | ||
597 | <div style="position: relative;"> | ||
598 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
599 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">81</div> | ||
600 | </div> | ||
601 | <pre class=" CodeMirror-line " | ||
602 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <memory></span></span></pre> | ||
603 | </div> | ||
604 | <div style="position: relative;"> | ||
605 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
606 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">82</div> | ||
607 | </div> | ||
608 | <pre class=" CodeMirror-line " | ||
609 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <new></span></span></pre> | ||
610 | </div> | ||
611 | <div style="position: relative;"> | ||
612 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
613 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">83</div> | ||
614 | </div> | ||
615 | <pre class=" CodeMirror-line " | ||
616 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <numeric></span></span></pre> | ||
617 | </div> | ||
618 | <div style="position: relative;"> | ||
619 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
620 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">84</div> | ||
621 | </div> | ||
622 | <pre class=" CodeMirror-line " | ||
623 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <ostream></span></span></pre> | ||
624 | </div> | ||
625 | <div style="position: relative;"> | ||
626 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
627 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">85</div> | ||
628 | </div> | ||
629 | <pre class=" CodeMirror-line " | ||
630 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <queue></span></span></pre> | ||
631 | </div> | ||
632 | <div style="position: relative;"> | ||
633 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
634 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">86</div> | ||
635 | </div> | ||
636 | <pre class=" CodeMirror-line " | ||
637 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <set></span></span></pre> | ||
638 | </div> | ||
639 | <div style="position: relative;"> | ||
640 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
641 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">87</div> | ||
642 | </div> | ||
643 | <pre class=" CodeMirror-line " | ||
644 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <sstream></span></span></pre> | ||
645 | </div> | ||
646 | <div style="position: relative;"> | ||
647 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
648 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">88</div> | ||
649 | </div> | ||
650 | <pre class=" CodeMirror-line " | ||
651 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <stack></span></span></pre> | ||
652 | </div> | ||
653 | <div style="position: relative;"> | ||
654 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
655 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">89</div> | ||
656 | </div> | ||
657 | <pre class=" CodeMirror-line " | ||
658 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <stdexcept></span></span></pre> | ||
659 | </div> | ||
660 | <div style="position: relative;"> | ||
661 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
662 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" | ||
663 | style="left: 0px; width: 36px;">90</div> | ||
664 | </div> | ||
665 | <pre class=" CodeMirror-line " | ||
666 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <streambuf></span></span></pre> | ||
667 | </div> | ||
668 | <div style="position: relative;"> | ||
669 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
670 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">91</div> | ||
671 | </div> | ||
672 | <pre class=" CodeMirror-line " | ||
673 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <string></span></span></pre> | ||
674 | </div> | ||
675 | <div style="position: relative;"> | ||
676 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
677 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">92</div> | ||
678 | </div> | ||
679 | <pre class=" CodeMirror-line " | ||
680 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <thread></span></span></pre> | ||
681 | </div> | ||
682 | <div style="position: relative;"> | ||
683 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
684 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">93</div> | ||
685 | </div> | ||
686 | <pre class=" CodeMirror-line " | ||
687 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <typeinfo></span></span></pre> | ||
688 | </div> | ||
689 | <div style="position: relative;"> | ||
690 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
691 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">94</div> | ||
692 | </div> | ||
693 | <pre class=" CodeMirror-line " | ||
694 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <unistd.h></span></span></pre> | ||
695 | </div> | ||
696 | <div style="position: relative;"> | ||
697 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
698 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">95</div> | ||
699 | </div> | ||
700 | <pre class=" CodeMirror-line " | ||
701 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <utility></span></span></pre> | ||
702 | </div> | ||
703 | <div style="position: relative;"> | ||
704 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
705 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">96</div> | ||
706 | </div> | ||
707 | <pre class=" CodeMirror-line " | ||
708 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <valarray></span></span></pre> | ||
709 | </div> | ||
710 | <div style="position: relative;"> | ||
711 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
712 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">97</div> | ||
713 | </div> | ||
714 | <pre class=" CodeMirror-line " | ||
715 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <vector></span></span></pre> | ||
716 | </div> | ||
717 | <div style="position: relative;"> | ||
718 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
719 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">98</div> | ||
720 | </div> | ||
721 | <pre class=" CodeMirror-line " | ||
722 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"> </span></pre> | ||
723 | </div> | ||
724 | <div style="position: relative;"> | ||
725 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
726 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">99</div> | ||
727 | </div> | ||
728 | <pre class=" CodeMirror-line " | ||
729 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#if __cplusplus >= 201103L</span></span></pre> | ||
730 | </div> | ||
731 | <div style="position: relative;"> | ||
732 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
733 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" | ||
734 | style="left: 0px; width: 36px;">100</div> | ||
735 | </div> | ||
736 | <pre class=" CodeMirror-line " | ||
737 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <array></span></span></pre> | ||
738 | </div> | ||
739 | <div style="position: relative;"> | ||
740 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
741 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">101</div> | ||
742 | </div> | ||
743 | <pre class=" CodeMirror-line " | ||
744 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <atomic></span></span></pre> | ||
745 | </div> | ||
746 | <div style="position: relative;"> | ||
747 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
748 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">102</div> | ||
749 | </div> | ||
750 | <pre class=" CodeMirror-line " | ||
751 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <chrono></span></span></pre> | ||
752 | </div> | ||
753 | <div style="position: relative;"> | ||
754 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
755 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">103</div> | ||
756 | </div> | ||
757 | <pre class=" CodeMirror-line " | ||
758 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <condition_variable></span></span></pre> | ||
759 | </div> | ||
760 | <div style="position: relative;"> | ||
761 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
762 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">104</div> | ||
763 | </div> | ||
764 | <pre class=" CodeMirror-line " | ||
765 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <forward_list></span></span></pre> | ||
766 | </div> | ||
767 | <div style="position: relative;"> | ||
768 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
769 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">105</div> | ||
770 | </div> | ||
771 | <pre class=" CodeMirror-line " | ||
772 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <future></span></span></pre> | ||
773 | </div> | ||
774 | <div style="position: relative;"> | ||
775 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
776 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">106</div> | ||
777 | </div> | ||
778 | <pre class=" CodeMirror-line " | ||
779 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <initializer_list></span></span></pre> | ||
780 | </div> | ||
781 | <div style="position: relative;"> | ||
782 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
783 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">107</div> | ||
784 | </div> | ||
785 | <pre class=" CodeMirror-line " | ||
786 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <mutex></span></span></pre> | ||
787 | </div> | ||
788 | <div style="position: relative;"> | ||
789 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
790 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">108</div> | ||
791 | </div> | ||
792 | <pre class=" CodeMirror-line " | ||
793 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <random></span></span></pre> | ||
794 | </div> | ||
795 | <div style="position: relative;"> | ||
796 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
797 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">109</div> | ||
798 | </div> | ||
799 | <pre class=" CodeMirror-line " | ||
800 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <ratio></span></span></pre> | ||
801 | </div> | ||
802 | <div style="position: relative;"> | ||
803 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
804 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" | ||
805 | style="left: 0px; width: 36px;">110</div> | ||
806 | </div> | ||
807 | <pre class=" CodeMirror-line " | ||
808 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <regex></span></span></pre> | ||
809 | </div> | ||
810 | <div style="position: relative;"> | ||
811 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
812 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">111</div> | ||
813 | </div> | ||
814 | <pre class=" CodeMirror-line " | ||
815 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <scoped_allocator></span></span></pre> | ||
816 | </div> | ||
817 | <div style="position: relative;"> | ||
818 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
819 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">112</div> | ||
820 | </div> | ||
821 | <pre class=" CodeMirror-line " | ||
822 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <system_error></span></span></pre> | ||
823 | </div> | ||
824 | <div style="position: relative;"> | ||
825 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
826 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">113</div> | ||
827 | </div> | ||
828 | <pre class=" CodeMirror-line " | ||
829 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <thread></span></span></pre> | ||
830 | </div> | ||
831 | <div style="position: relative;"> | ||
832 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
833 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">114</div> | ||
834 | </div> | ||
835 | <pre class=" CodeMirror-line " | ||
836 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <tuple></span></span></pre> | ||
837 | </div> | ||
838 | <div style="position: relative;"> | ||
839 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
840 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">115</div> | ||
841 | </div> | ||
842 | <pre class=" CodeMirror-line " | ||
843 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <typeindex></span></span></pre> | ||
844 | </div> | ||
845 | <div style="position: relative;"> | ||
846 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
847 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">116</div> | ||
848 | </div> | ||
849 | <pre class=" CodeMirror-line " | ||
850 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <type_traits></span></span></pre> | ||
851 | </div> | ||
852 | <div style="position: relative;"> | ||
853 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
854 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">117</div> | ||
855 | </div> | ||
856 | <pre class=" CodeMirror-line " | ||
857 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <unordered_map></span></span></pre> | ||
858 | </div> | ||
859 | <div style="position: relative;"> | ||
860 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
861 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 36px;">118</div> | ||
862 | </div> | ||
863 | <pre class=" CodeMirror-line " | ||
864 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#include <unordered_set></span></span></pre> | ||
865 | </div> | ||
866 | <div class="" style="position: relative;"> | ||
867 | <div class="CodeMirror-gutter-wrapper" style="left: -45px;"> | ||
868 | <div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" | ||
869 | style="left: 0px; width: 36px;">119</div> | ||
870 | </div> | ||
871 | <pre class=" CodeMirror-line " | ||
872 | role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-meta">#endif</span></span></pre> | ||
873 | </div> | ||
874 | </div> | ||
875 | </div> | ||
876 | </div> | ||
877 | </div> | ||
878 | </div> | ||
879 | <div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 2741px;"></div> | ||
880 | <div class="CodeMirror-gutters" style="height: 2741px;"> | ||
881 | <div class="CodeMirror-gutter CodeMirror-linenumbers" style="width: 44px;"></div> | ||
882 | </div> | ||
883 | </div> | ||
884 | </div> | ||
885 | </pre> | ||
886 | <p> </p> | ||
887 | <script src="https://www.qin-juan-ge-zhu.top/common/js/comment.js"></script> | ||
888 | </div> | ||
889 | </div> | ||
890 | </body> | ||
891 | |||
892 | </html> \ No newline at end of file | ||
diff --git a/common/CSS/MySet.css b/common/CSS/MySet.css index 19068b1..e152141 100644 --- a/common/CSS/MySet.css +++ b/common/CSS/MySet.css | |||
@@ -1,4 +1,7 @@ | |||
1 | /* 以下部分为自行开发 */ | 1 | /* 以下部分为自行开发 */ |
2 | .wall{ | ||
3 | width:100%; | ||
4 | } | ||
2 | 5 | ||
3 | a { | 6 | a { |
4 | text-decoration: none !important; | 7 | text-decoration: none !important; |
diff --git a/common/CSS/huang.css b/common/CSS/huang.css index 1142414..393d818 100644 --- a/common/CSS/huang.css +++ b/common/CSS/huang.css | |||
@@ -118,6 +118,8 @@ h3 { | |||
118 | 118 | ||
119 | .background { | 119 | .background { |
120 | background: linear-gradient(#4a96cd, #7cb6dd, #4a96cd); | 120 | background: linear-gradient(#4a96cd, #7cb6dd, #4a96cd); |
121 | /* 设置为彩虹色 */ | ||
122 | /* background: linear-gradient(45deg, #ff0000, #ff7f00, #ffff00, #00ff00, #0000ff, #4b0082, #8f00ff); */ | ||
121 | width: 100%; | 123 | width: 100%; |
122 | padding: 0; | 124 | padding: 0; |
123 | margin: 0; | 125 | margin: 0; |
diff --git a/common/script4works.html b/common/script4works.html index fb52f9b..7e74c30 100644 --- a/common/script4works.html +++ b/common/script4works.html | |||
@@ -114,7 +114,6 @@ | |||
114 | 114 | ||
115 | <div class="child" id="child1" style="display:none"> | 115 | <div class="child" id="child1" style="display:none"> |
116 | <a href="https://www.qin-juan-ge-zhu.top/works/index.html">-勤倦阁记</a> | 116 | <a href="https://www.qin-juan-ge-zhu.top/works/index.html">-勤倦阁记</a> |
117 | <a href="https://www.qin-juan-ge-zhu.top/works/book.html">-诗文总集</a> | ||
118 | <a href="https://www.qin-juan-ge-zhu.top/works/poetry.html">-诗词选</a> | 117 | <a href="https://www.qin-juan-ge-zhu.top/works/poetry.html">-诗词选</a> |
119 | <a onclick="clickit('grandson11')">-文章随笔</a> | 118 | <a onclick="clickit('grandson11')">-文章随笔</a> |
120 | <div class="grandson" id="grandson11" style="display:none"> | 119 | <div class="grandson" id="grandson11" style="display:none"> |
@@ -125,6 +124,7 @@ | |||
125 | <a href="https://www.qin-juan-ge-zhu.top/works/Napoleon.html">历史感下拿破仑</a> | 124 | <a href="https://www.qin-juan-ge-zhu.top/works/Napoleon.html">历史感下拿破仑</a> |
126 | <a href="https://www.qin-juan-ge-zhu.top/works/education.html">救救孩子!</a> | 125 | <a href="https://www.qin-juan-ge-zhu.top/works/education.html">救救孩子!</a> |
127 | </div> | 126 | </div> |
127 | <a href="https://www.qin-juan-ge-zhu.top/works/book.html">-诗文总集</a> | ||
128 | </div> | 128 | </div> |
129 | 129 | ||
130 | <div class="main-menu" id="main2" onclick="clickit('child2')">-代码世界 | 130 | <div class="main-menu" id="main2" onclick="clickit('child2')">-代码世界 |
@@ -132,28 +132,32 @@ | |||
132 | <div class="child" id="child2" style="display:none"> | 132 | <div class="child" id="child2" style="display:none"> |
133 | <a onclick="clickit('grandson21')">-美好Linux</a> | 133 | <a onclick="clickit('grandson21')">-美好Linux</a> |
134 | <div class="grandson" id="grandson21" style="display:none"> | 134 | <div class="grandson" id="grandson21" style="display:none"> |
135 | <a href="https://www.qin-juan-ge-zhu.top/code/linux/aliyun_cloud.html">-我的免费云服</a> | 135 | <a href="https://www.qin-juan-ge-zhu.top/code/linux/aliyun_cloud.html">我的免费云服</a> |
136 | <a href="https://code.qin-juan-ge-zhu.top">-VSCode Online</a> | 136 | <a href="https://www.qin-juan-ge-zhu.top/code/linux/vim.html">vim学习与配置</a> |
137 | <a href="https://www.qin-juan-ge-zhu.top/code/linux/vim.html">-vim学习与配置</a> | 137 | <a href="https://www.qin-juan-ge-zhu.top/code/linux/keymap.html">键盘映射</a> |
138 | <a href="https://www.qin-juan-ge-zhu.top/code/linux/keymap.html">-键盘映射</a> | 138 | <a href="https://www.qin-juan-ge-zhu.top/code/linux/gitserver.html">属于自己的git托管</a> |
139 | <a href="https://www.qin-juan-ge-zhu.top/code/linux/httpmyserver.html">http浏览服务器文件</a> | ||
139 | </div> | 140 | </div> |
140 | <a href="https://www.qin-juan-ge-zhu.top/code/cpppp.html">-C++ Primer | ||
141 | Plus<br> 基础知识整理</a> | ||
142 | <a href="https://www.qin-juan-ge-zhu.top/code/highlight.html">-代码块高亮与<br> 一键复制</a> | ||
143 | <a onclick="clickit('grandson22')">-一些小玩意儿</a> | 141 | <a onclick="clickit('grandson22')">-一些小玩意儿</a> |
144 | <div class="grandson" id="grandson22" style="display:none"> | 142 | <div class="grandson" id="grandson22" style="display:none"> |
145 | <a href="https://www.qin-juan-ge-zhu.top/code/index.html">-C的小零件</a> | 143 | <a href="https://www.qin-juan-ge-zhu.top/code/highlight.html">代码高亮与复制</a> |
146 | <a href="https://www.qin-juan-ge-zhu.top/code/stdc++.html">-C++九千能头文件</a> | 144 | <a href="https://www.qin-juan-ge-zhu.top/code/index.html">C的小零件</a> |
145 | <a href="https://www.qin-juan-ge-zhu.top/code/cpppp.html">C++ Primer Plus基础</a> | ||
147 | <a href="https://www.qin-juan-ge-zhu.top/code/fileop(cpp).html">C++文件操作</a> | 146 | <a href="https://www.qin-juan-ge-zhu.top/code/fileop(cpp).html">C++文件操作</a> |
148 | <a href="https://www.qin-juan-ge-zhu.top/code/experiment">大物实验MATLAB</a> | 147 | <a href="https://www.qin-juan-ge-zhu.top/code/experiment">大物实验MATLAB</a> |
149 | <a href="https://www.qin-juan-ge-zhu.top/code/zeal.html">Zeal文档下载</a> | 148 | <a href="https://www.qin-juan-ge-zhu.top/code/zeal.html">Zeal文档下载</a> |
150 | </div> | 149 | </div> |
150 | <a onclick="clickit('grandson23')">-功能网页</a> | ||
151 | <div class="grandson" id="grandson23" style="display:none"> | ||
152 | <a href="https://code.qin-juan-ge-zhu.top">VSCode Online</a> | ||
153 | <a href="https://file.qin-juan-ge-zhu.top">服务器文件浏览</a> | ||
154 | </div> | ||
151 | </div> | 155 | </div> |
152 | 156 | ||
153 | <div class="main-menu" is="main3" onclick="clickit('child3')">-读书兴味</div> | 157 | <div class="main-menu" is="main3" onclick="clickit('child3')">-读书兴味</div> |
154 | <div class="child" id="child3" style="display:none"> | 158 | <div class="child" id="child3" style="display:none"> |
155 | <a href="https://www.qin-juan-ge-zhu.top/read/on_contradictions.html">-《矛盾论》提纲</a> | 159 | <a href="https://www.qin-juan-ge-zhu.top/read/on_contradictions.html">-矛盾论提纲</a> |
156 | <a href="https://www.qin-juan-ge-zhu.top/read/nation.html">- 国家?祖国?</a> | 160 | <a href="https://www.qin-juan-ge-zhu.top/read/nation.html">-国家?祖国?</a> |
157 | </div> | 161 | </div> |
158 | <div class="main-menu" is="main4" onclick="clickit('child4')">-贪玩蓝月</div> | 162 | <div class="main-menu" is="main4" onclick="clickit('child4')">-贪玩蓝月</div> |
159 | <div class="child" id="child4" style="display:none"> | 163 | <div class="child" id="child4" style="display:none"> |
diff --git a/common/script4works.js b/common/script4works.js index 561a18c..2e47392 100644 --- a/common/script4works.js +++ b/common/script4works.js | |||
@@ -115,7 +115,6 @@ document.writeln(" </div>"); | |||
115 | document.writeln(""); | 115 | document.writeln(""); |
116 | document.writeln(" <div class=\"child\" id=\"child1\" style=\"display:none\">"); | 116 | document.writeln(" <div class=\"child\" id=\"child1\" style=\"display:none\">"); |
117 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/works/index.html\">-勤倦阁记</a>"); | 117 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/works/index.html\">-勤倦阁记</a>"); |
118 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/works/book.html\">-诗文总集</a>"); | ||
119 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/works/poetry.html\">-诗词选</a>"); | 118 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/works/poetry.html\">-诗词选</a>"); |
120 | document.writeln(" <a onclick=\"clickit(\'grandson11\')\">-文章随笔</a>"); | 119 | document.writeln(" <a onclick=\"clickit(\'grandson11\')\">-文章随笔</a>"); |
121 | document.writeln(" <div class=\"grandson\" id=\"grandson11\" style=\"display:none\">"); | 120 | document.writeln(" <div class=\"grandson\" id=\"grandson11\" style=\"display:none\">"); |
@@ -126,6 +125,7 @@ document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/work | |||
126 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/works/Napoleon.html\">历史感下拿破仑</a>"); | 125 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/works/Napoleon.html\">历史感下拿破仑</a>"); |
127 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/works/education.html\">救救孩子!</a>"); | 126 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/works/education.html\">救救孩子!</a>"); |
128 | document.writeln(" </div>"); | 127 | document.writeln(" </div>"); |
128 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/works/book.html\">-诗文总集</a>"); | ||
129 | document.writeln(" </div>"); | 129 | document.writeln(" </div>"); |
130 | document.writeln(""); | 130 | document.writeln(""); |
131 | document.writeln(" <div class=\"main-menu\" id=\"main2\" onclick=\"clickit(\'child2\')\">-代码世界"); | 131 | document.writeln(" <div class=\"main-menu\" id=\"main2\" onclick=\"clickit(\'child2\')\">-代码世界"); |
@@ -133,28 +133,32 @@ document.writeln(" </div>"); | |||
133 | document.writeln(" <div class=\"child\" id=\"child2\" style=\"display:none\">"); | 133 | document.writeln(" <div class=\"child\" id=\"child2\" style=\"display:none\">"); |
134 | document.writeln(" <a onclick=\"clickit(\'grandson21\')\">-美好Linux</a>"); | 134 | document.writeln(" <a onclick=\"clickit(\'grandson21\')\">-美好Linux</a>"); |
135 | document.writeln(" <div class=\"grandson\" id=\"grandson21\" style=\"display:none\">"); | 135 | document.writeln(" <div class=\"grandson\" id=\"grandson21\" style=\"display:none\">"); |
136 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/linux/aliyun_cloud.html\">-我的免费云服</a>"); | 136 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/linux/aliyun_cloud.html\">我的免费云服</a>"); |
137 | document.writeln(" <a href=\"https://code.qin-juan-ge-zhu.top\">-VSCode Online</a>"); | 137 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/linux/vim.html\">vim学习与配置</a>"); |
138 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/linux/vim.html\">-vim学习与配置</a>"); | 138 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/linux/keymap.html\">键盘映射</a>"); |
139 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/linux/keymap.html\">-键盘映射</a>"); | 139 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/linux/gitserver.html\">属于自己的git托管</a>"); |
140 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/linux/httpmyserver.html\">http浏览服务器文件</a>"); | ||
140 | document.writeln(" </div>"); | 141 | document.writeln(" </div>"); |
141 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/cpppp.html\">-C++ Primer"); | ||
142 | document.writeln(" Plus<br> 基础知识整理</a>"); | ||
143 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/highlight.html\">-代码块高亮与<br> 一键复制</a>"); | ||
144 | document.writeln(" <a onclick=\"clickit(\'grandson22\')\">-一些小玩意儿</a>"); | 142 | document.writeln(" <a onclick=\"clickit(\'grandson22\')\">-一些小玩意儿</a>"); |
145 | document.writeln(" <div class=\"grandson\" id=\"grandson22\" style=\"display:none\">"); | 143 | document.writeln(" <div class=\"grandson\" id=\"grandson22\" style=\"display:none\">"); |
146 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/index.html\">-C的小零件</a>"); | 144 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/highlight.html\">代码高亮与复制</a>"); |
147 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/stdc++.html\">-C++九千能头文件</a>"); | 145 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/index.html\">C的小零件</a>"); |
146 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/cpppp.html\">C++ Primer Plus基础</a>"); | ||
148 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/fileop(cpp).html\">C++文件操作</a>"); | 147 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/fileop(cpp).html\">C++文件操作</a>"); |
149 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/experiment\">大物实验MATLAB</a>"); | 148 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/experiment\">大物实验MATLAB</a>"); |
150 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/zeal.html\">Zeal文档下载</a>"); | 149 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/zeal.html\">Zeal文档下载</a>"); |
151 | document.writeln(" </div>"); | 150 | document.writeln(" </div>"); |
151 | document.writeln(" <a onclick=\"clickit(\'grandson23\')\">-功能网页</a>"); | ||
152 | document.writeln(" <div class=\"grandson\" id=\"grandson23\" style=\"display:none\">"); | ||
153 | document.writeln(" <a href=\"https://code.qin-juan-ge-zhu.top\">VSCode Online</a>"); | ||
154 | document.writeln(" <a href=\"https://file.qin-juan-ge-zhu.top\">服务器文件浏览</a>"); | ||
155 | document.writeln(" </div>"); | ||
152 | document.writeln(" </div>"); | 156 | document.writeln(" </div>"); |
153 | document.writeln(""); | 157 | document.writeln(""); |
154 | document.writeln(" <div class=\"main-menu\" is=\"main3\" onclick=\"clickit(\'child3\')\">-读书兴味</div>"); | 158 | document.writeln(" <div class=\"main-menu\" is=\"main3\" onclick=\"clickit(\'child3\')\">-读书兴味</div>"); |
155 | document.writeln(" <div class=\"child\" id=\"child3\" style=\"display:none\">"); | 159 | document.writeln(" <div class=\"child\" id=\"child3\" style=\"display:none\">"); |
156 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/read/on_contradictions.html\">-《矛盾论》提纲</a>"); | 160 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/read/on_contradictions.html\">-矛盾论提纲</a>"); |
157 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/read/nation.html\">- 国家?祖国?</a>"); | 161 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/read/nation.html\">-国家?祖国?</a>"); |
158 | document.writeln(" </div>"); | 162 | document.writeln(" </div>"); |
159 | document.writeln(" <div class=\"main-menu\" is=\"main4\" onclick=\"clickit(\'child4\')\">-贪玩蓝月</div>"); | 163 | document.writeln(" <div class=\"main-menu\" is=\"main4\" onclick=\"clickit(\'child4\')\">-贪玩蓝月</div>"); |
160 | document.writeln(" <div class=\"child\" id=\"child4\" style=\"display:none\">"); | 164 | document.writeln(" <div class=\"child\" id=\"child4\" style=\"display:none\">"); |
diff --git a/md2html.sh b/md2html.sh new file mode 100755 index 0000000..7aaee04 --- /dev/null +++ b/md2html.sh | |||
@@ -0,0 +1,28 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | ########################################################################## | ||
4 | # File Name : md2html.sh | ||
5 | # Encoding : utf-8 | ||
6 | # Author : We-unite | ||
7 | # Email : weunite1848@gmail.com | ||
8 | # Created Time : 2023-12-15 | ||
9 | ########################################################################## | ||
10 | |||
11 | # origin是输入的第一个参数,指源文件名 | ||
12 | # src是原文件名前边加一个.,是源文件的复制 | ||
13 | # dst是原文件名的md后缀改成html | ||
14 | origin=$1 | ||
15 | src="."$origin | ||
16 | dst=${origin%.*}".html" | ||
17 | |||
18 | cp $origin $src | ||
19 | # src中所有的“```...”替换成“```”,其中...指换行前的所有内容 | ||
20 | sed -i 's/```.*$/```/g' $src | ||
21 | pandoc -s $src -o $dst | ||
22 | rm $src | ||
23 | |||
24 | sed -i '/<style/,/<\/style>/d' $dst | ||
25 | sed -i 's/<body>/<body>\n<div class="pandoc">\n<div class="main">/' $dst | ||
26 | sed -i 's/<\/body>/<script src="https:\/\/www.qin-juan-ge-zhu.top\/common\/js\/comment.js"><\/script>\n<\/div>\n<\/div>\n<\/body>/' $dst | ||
27 | sed -i 's/\t/ /g' $dst | ||
28 | sed -i 's/<\/head>/<link rel="stylesheet" href="https:\/\/www.qin-juan-ge-zhu.top\/common\/CSS\/pandoc.css">\n<script type="text\/javascript" src="https:\/\/www.qin-juan-ge-zhu.top\/common\/script4code.js"><\/script><\/head>/' $dst | ||
diff --git a/works/education.html b/works/education.html index 072e548..74b43c4 100644 --- a/works/education.html +++ b/works/education.html | |||
@@ -4,8 +4,6 @@ | |||
4 | <head> | 4 | <head> |
5 | <meta charset='UTF-8'> | 5 | <meta charset='UTF-8'> |
6 | <meta name='viewport' content='width=device-width initial-scale=1'> | 6 | <meta name='viewport' content='width=device-width initial-scale=1'> |
7 | <link href='https://fonts.loli.net/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext' | ||
8 | rel='stylesheet' type='text/css' /> | ||
9 | <script type="text/javascript" src="https://www.qin-juan-ge-zhu.top/common/script4works.js"></script> | 7 | <script type="text/javascript" src="https://www.qin-juan-ge-zhu.top/common/script4works.js"></script> |
10 | <title>救救孩子!</title> | 8 | <title>救救孩子!</title> |
11 | <!-- 评论区js --> | 9 | <!-- 评论区js --> |
diff --git a/works/poetry.html b/works/poetry.html index 848d72f..27fff26 100644 --- a/works/poetry.html +++ b/works/poetry.html | |||
@@ -6,53 +6,64 @@ | |||
6 | <meta http-equiv="X-UA-Compatible" content="IE=edge"> | 6 | <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
7 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> | 7 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
8 | <script type="text/javascript" src="https://www.qin-juan-ge-zhu.top/common/script4works.js"></script> | 8 | <script type="text/javascript" src="https://www.qin-juan-ge-zhu.top/common/script4works.js"></script> |
9 | <title>词</title> | 9 | <title>桃</title> |
10 | <!-- 评论区js --> | 10 | <!-- 评论区js --> |
11 | <script src='https://www.qin-juan-ge-zhu.top/common/js/valine.min.js'></script> | 11 | <script src='https://www.qin-juan-ge-zhu.top/common/js/valine.min.js'></script> |
12 | <script src="https://cdn.jsdelivr.net/gh/flatblowfish/cave-draw/dist/cave-draw.min.js"></script> | 12 | <script src="https://cdn.jsdelivr.net/gh/flatblowfish/cave-draw/dist/cave-draw.min.js"></script> |
13 | </head> | 13 | </head> |
14 | 14 | ||
15 | <div class='typora-export os-windows'> | 15 | <body class='typora-export os-windows'> |
16 | <div class="wall"> | 16 | <div class="wall"> |
17 | <div class="background"> | 17 | <div class="background"> |
18 | <div class="box"> | 18 | <div class="box"> |
19 | <p class="title">诗词选</p> | 19 | <p class="title">诗词选</p> |
20 | <div class='md-toc' mdtype='toc'> | 20 | <div class='md-toc' mdtype='toc'> |
21 | <p class="md-toc-content" role="list"><span role="listitem" class="md-toc-item md-toc-h1" | 21 | <p class="md-toc-content" role="list"> |
22 | data-ref="n89"><a class="md-toc-inner" href="#破阵子--桃林">破阵子 桃林</a></span><br><span | 22 | <span role="listitem" class="md-toc-item md-toc-h1" data-ref="n89"><a class="md-toc-inner" |
23 | role="listitem" class="md-toc-item md-toc-h1" data-ref="n93"><a class="md-toc-inner" | 23 | href="#破阵子--桃林">破阵子 桃林</a></span><br> |
24 | href="#传韵道德">传韵道德</a></span><br><span role="listitem" class="md-toc-item md-toc-h1" | 24 | <span role="listitem" class="md-toc-item md-toc-h1" data-ref="n93"><a class="md-toc-inner" |
25 | data-ref="n96"><a class="md-toc-inner" href="#咏抗战老兵">咏抗战老兵</a></span><br><span | 25 | href="#传韵道德">传韵道德</a></span><br> |
26 | role="listitem" class="md-toc-item md-toc-h1" data-ref="n99"><a class="md-toc-inner" | 26 | <span role="listitem" class="md-toc-item md-toc-h1" data-ref="n96"><a class="md-toc-inner" |
27 | href="#凌云">凌云</a></span><br><span role="listitem" class="md-toc-item md-toc-h1" | 27 | href="#咏抗战老兵">咏抗战老兵</a></span><br> |
28 | data-ref="n102"><a class="md-toc-inner" href="#游函关故道">游函关故道</a></span><br><span | 28 | <span role="listitem" class="md-toc-item md-toc-h1" data-ref="n99"><a class="md-toc-inner" |
29 | role="listitem" class="md-toc-item md-toc-h1" data-ref="n115"><a class="md-toc-inner" | 29 | href="#凌云">凌云</a></span><br> |
30 | <span role="listitem" class="md-toc-item md-toc-h1" data-ref="n102"><a class="md-toc-inner" | ||
31 | href="#游函关故道">游函关故道</a></span><br> | ||
32 | <span role="listitem" class="md-toc-item md-toc-h1" data-ref="n115"><a class="md-toc-inner" | ||
30 | href="#捣练子-春晓踏学途乐吟">捣练子 | 33 | href="#捣练子-春晓踏学途乐吟">捣练子 |
31 | 春晓踏学途乐吟</a></span><br><span role="listitem" class="md-toc-item md-toc-h1" | 34 | 春晓踏学途乐吟</a></span><br> |
32 | data-ref="n120"><a class="md-toc-inner" href="#夜读">夜读</a></span><br><span role="listitem" | 35 | <span role="listitem" class="md-toc-item md-toc-h1" data-ref="n120"><a class="md-toc-inner" |
33 | class="md-toc-item md-toc-h1" data-ref="n123"><a class="md-toc-inner" | 36 | href="#夜读">夜读</a></span><br> |
34 | href="#游关龙逄墓">游关龙逄墓</a></span><br><span role="listitem" class="md-toc-item md-toc-h1" | 37 | <span role="listitem" class="md-toc-item md-toc-h1" data-ref="n123"><a class="md-toc-inner" |
35 | data-ref="n128"><a class="md-toc-inner" href="#南乡子">南乡子</a></span><br><span role="listitem" | 38 | href="#游关龙逄墓">游关龙逄墓</a></span><br> |
36 | class="md-toc-item md-toc-h1" data-ref="n132"><a class="md-toc-inner" | 39 | <span role="listitem" class="md-toc-item md-toc-h1" data-ref="n128"><a class="md-toc-inner" |
37 | href="#初雪">初雪</a></span><br><span role="listitem" class="md-toc-item md-toc-h1" | 40 | href="#南乡子">南乡子</a></span><br> |
38 | data-ref="n135"><a class="md-toc-inner" href="#游项城">游项城</a></span><br><span role="listitem" | 41 | <span role="listitem" class="md-toc-item md-toc-h1" data-ref="n132"><a class="md-toc-inner" |
39 | class="md-toc-item md-toc-h1" data-ref="n138"><a class="md-toc-inner" href="#鹧鸪天-夜诉衷">鹧鸪天 | 42 | href="#初雪">初雪</a></span><br> |
40 | 夜诉衷</a></span><br><span role="listitem" class="md-toc-item md-toc-h1" data-ref="n147"><a | 43 | <span role="listitem" class="md-toc-item md-toc-h1" data-ref="n135"><a class="md-toc-inner" |
41 | class="md-toc-inner" href="#早读">早读</a></span><br><span role="listitem" | 44 | href="#游项城">游项城</a></span><br> |
42 | class="md-toc-item md-toc-h1" data-ref="n153"><a class="md-toc-inner" | 45 | <span role="listitem" class="md-toc-item md-toc-h1" data-ref="n138"><a class="md-toc-inner" |
43 | href="#悼袁隆平院士">悼袁隆平院士</a></span><br><span role="listitem" class="md-toc-item md-toc-h1" | 46 | href="#鹧鸪天-夜诉衷">鹧鸪天 夜诉衷</a></span><br> |
44 | data-ref="n156"><a class="md-toc-inner" href="#赠友">赠友</a></span><br><span role="listitem" | 47 | <span role="listitem" class="md-toc-item md-toc-h1" data-ref="n147"><a class="md-toc-inner" |
45 | class="md-toc-item md-toc-h1" data-ref="n160"><a class="md-toc-inner" | 48 | href="#早读">早读</a></span><br> |
46 | href="#九九">九九</a></span><br><span role="listitem" class="md-toc-item md-toc-h1" | 49 | <span role="listitem" class="md-toc-item md-toc-h1" data-ref="n153"><a class="md-toc-inner" |
47 | data-ref="n163"><a class="md-toc-inner" href="#自贺加冠诗">自贺加冠诗</a></span><br><span | 50 | href="#悼袁隆平院士">悼袁隆平院士</a></span><br> |
48 | role="listitem" class="md-toc-item md-toc-h1" data-ref="n166"><a class="md-toc-inner" | 51 | <span role="listitem" class="md-toc-item md-toc-h1" data-ref="n156"><a class="md-toc-inner" |
49 | href="#自嘲">自嘲</a></span><br><span role="listitem" class="md-toc-item md-toc-h1" | 52 | href="#赠友">赠友</a></span><br> |
50 | data-ref="n169"><a class="md-toc-inner" href="#癸卯随笔">癸卯随笔</a></span><br><span | 53 | <span role="listitem" class="md-toc-item md-toc-h1" data-ref="n160"><a class="md-toc-inner" |
51 | role="listitem" class="md-toc-item md-toc-h1" data-ref="n172"><a class="md-toc-inner" | 54 | href="#九九">九九</a></span><br> |
55 | <span role="listitem" class="md-toc-item md-toc-h1" data-ref="n163"><a class="md-toc-inner" | ||
56 | href="#自贺加冠诗">自贺加冠诗</a></span><br> | ||
57 | <span role="listitem" class="md-toc-item md-toc-h1" data-ref="n166"><a class="md-toc-inner" | ||
58 | href="#自嘲">自嘲</a></span><br> | ||
59 | <span role="listitem" class="md-toc-item md-toc-h1" data-ref="n169"><a class="md-toc-inner" | ||
60 | href="#癸卯随笔">癸卯随笔</a></span><br> | ||
61 | <span role="listitem" class="md-toc-item md-toc-h1" data-ref="n172"><a class="md-toc-inner" | ||
52 | href="#机上作">机上作</a></span><br> | 62 | href="#机上作">机上作</a></span><br> |
63 | <span role="listitem" class="md-toc-item md-toc-h1" data-ref="n172"><a class="md-toc-inner" | ||
64 | href="#顺天三日">顺天三日</a></span><br> | ||
53 | </p> | 65 | </p> |
54 | </div> | 66 | </div> |
55 | |||
56 | 67 | ||
57 | <h1 id='破阵子--桃林'><span>破阵子 桃林</span><br></h1> | 68 | <h1 id='破阵子--桃林'><span>破阵子 桃林</span><br></h1> |
58 | <p style="text-align: center;"><span>数鸟翱翔宇内,一筝犹在云端。</span><br> | 69 | <p style="text-align: center;"><span>数鸟翱翔宇内,一筝犹在云端。</span><br> |
@@ -265,10 +276,18 @@ | |||
265 | <span>不意五国重临近,精一实愿道心存。</span><br> | 276 | <span>不意五国重临近,精一实愿道心存。</span><br> |
266 | </p> | 277 | </p> |
267 | <p class="time"><span>23.2.11</span><br></p> | 278 | <p class="time"><span>23.2.11</span><br></p> |
279 | |||
280 | <h1 id="顺天三日">顺天三日<br></h1> | ||
281 | <p style="text-align: center;"><span>夜半登车辔,晨风谒主席。</span><br> | ||
282 | <span>一哭石鼓字,三叹党人碑。</span><br> | ||
283 | <span>皇史竟谁睹,长城岂世违?</span><br> | ||
284 | <span>不闻君主业,新月笑为炊。</span><br> | ||
285 | </p> | ||
286 | <p class="time"><span>23.12.20</span><br></p> | ||
268 | <script src="https://www.qin-juan-ge-zhu.top/common/js/comment4works.js"></script> | 287 | <script src="https://www.qin-juan-ge-zhu.top/common/js/comment4works.js"></script> |
269 | </div> | 288 | </div> |
270 | </div> | 289 | </div> |
271 | </div> | 290 | </div> |
272 | </body> | 291 | </body> |
273 | 292 | ||
274 | </html> \ No newline at end of file | 293 | </html> \ No newline at end of file |