<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Flyky&#39;s blog space</title>
  
  <subtitle>Flyky的个人博客空间</subtitle>
  <link href="/atom.xml" rel="self"/>
  
  <link href="https://blog8.flyky.org/"/>
  <updated>2021-01-28T02:30:03.057Z</updated>
  <id>https://blog8.flyky.org/</id>
  
  <author>
    <name>Flyky</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>- pyinstaller打包django项目踩坑 -</title>
    <link href="https://blog8.flyky.org/20210126/Note-of-django-apps-packed-by-pyinstaller-1/"/>
    <id>https://blog8.flyky.org/20210126/Note-of-django-apps-packed-by-pyinstaller-1/</id>
    <published>2021-01-26T09:30:50.000Z</published>
    <updated>2021-01-28T02:30:03.057Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --><p>工作需要把django应用的环境打包，生成exe<br>花了一下午踩坑pyinstaller打包，稍微memo一下<br><em>(Django==2.2.5 | Python==3.8.5 | win)</em></p><a id="more"></a><ul><li>项目文件结构，<strong>以下称“本GM项目”</strong><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line">├─.vscode</span><br><span class="line">├─apps</span><br><span class="line">│  ├─common</span><br><span class="line">│  ├─DailyReport</span><br><span class="line">│  ├─GM_system</span><br><span class="line">│  ├─performance</span><br><span class="line">│  ├─user</span><br><span class="line">│  ├─。。。。。。。。。</span><br><span class="line">│  └─__pycache__</span><br><span class="line">├─config</span><br><span class="line">├─core</span><br><span class="line">│  └─__pycache__</span><br><span class="line">├─download</span><br><span class="line">├─GM</span><br><span class="line">│  └─__pycache__</span><br><span class="line">├─log</span><br><span class="line">├─mysql</span><br><span class="line">├─static</span><br><span class="line">│  ├─css</span><br><span class="line">│  ├─images</span><br><span class="line">│  ├─js</span><br><span class="line">│  ├─plugins</span><br><span class="line">│  ├─resources</span><br><span class="line">├─templates</span><br><span class="line">│  ├─dailyReport</span><br><span class="line">│  ├─layout</span><br><span class="line">│  ├─login</span><br><span class="line">│  ├─performance</span><br><span class="line">│  ├─public</span><br><span class="line">│  └─user</span><br><span class="line">│  └─。。。。。。。</span><br><span class="line">└─__pycache__</span><br></pre></td></tr></table></figure></li></ul><h1 id="安装pyinstaller"><a href="#安装pyinstaller" class="headerlink" title="安装pyinstaller"></a>安装pyinstaller</h1><p>pip安装pyinstaller库</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install pyinstaller</span><br></pre></td></tr></table></figure><h1 id="生成打包配置文件specfile"><a href="#生成打包配置文件specfile" class="headerlink" title="生成打包配置文件specfile"></a>生成打包配置文件specfile</h1><p>cd进入项目根目录，执行命令生成spec文件，文件位于当前目录下</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pyi-makespec -D manage.py</span><br></pre></td></tr></table></figure><p>生成的文件内容如下</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># -*- mode: python ; coding: utf-8 -*-</span></span><br><span class="line"></span><br><span class="line">block_cipher = <span class="literal">None</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">a = Analysis([<span class="string">'manage.py'</span>],</span><br><span class="line">             pathex=[<span class="string">'D:\\SVN\\GMs\\03_Source\\trank\\GMsV3.0'</span>],</span><br><span class="line">             binaries=[],</span><br><span class="line">             datas=[],</span><br><span class="line">             hiddenimports=[],</span><br><span class="line">             hookspath=[],</span><br><span class="line">             runtime_hooks=[],</span><br><span class="line">             excludes=[],</span><br><span class="line">             win_no_prefer_redirects=<span class="literal">False</span>,</span><br><span class="line">             win_private_assemblies=<span class="literal">False</span>,</span><br><span class="line">             cipher=block_cipher,</span><br><span class="line">             noarchive=<span class="literal">False</span>)</span><br><span class="line">pyz = PYZ(a.pure, a.zipped_data,</span><br><span class="line">             cipher=block_cipher)</span><br><span class="line">exe = EXE(pyz,</span><br><span class="line">          a.scripts,</span><br><span class="line">          [],</span><br><span class="line">          exclude_binaries=<span class="literal">True</span>,</span><br><span class="line">          name=<span class="string">'manage'</span>,</span><br><span class="line">          debug=<span class="literal">False</span>,</span><br><span class="line">          bootloader_ignore_signals=<span class="literal">False</span>,</span><br><span class="line">          strip=<span class="literal">False</span>,</span><br><span class="line">          upx=<span class="literal">True</span>,</span><br><span class="line">          console=<span class="literal">True</span> )</span><br><span class="line">coll = COLLECT(exe,</span><br><span class="line">               a.binaries,</span><br><span class="line">               a.zipfiles,</span><br><span class="line">               a.datas,</span><br><span class="line">               strip=<span class="literal">False</span>,</span><br><span class="line">               upx=<span class="literal">True</span>,</span><br><span class="line">               upx_exclude=[],</span><br><span class="line">               name=<span class="string">'manage'</span>)</span><br></pre></td></tr></table></figure><p>其中<code>exe</code>项里的<code>name</code>值为生成exe的文件名<br><code>console</code>项表示运行是否显示控制台终端<br>若需要指定生成exe文件的图标，则可以在其中新增一项icon，如<code>icon=&#39;favicon.ico&#39;</code></p><h1 id="打包生成exe"><a href="#打包生成exe" class="headerlink" title="打包生成exe"></a>打包生成exe</h1><ul><li>运行如下命令打包项目生成exe<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pyinstaller manage.spec</span><br></pre></td></tr></table></figure><div class="note info"><p>打包时似乎会将当前python环境里安装的所有包都打包进去<br>可能报一些和最终生成无关的其他包的依赖错误等，打包时会较慢<br>并且可能会由于打包进了很多无关项目的包而导致最终生成的目录大小较大<br>虽说可能无关紧要可以忽略，但强迫症可能就难受了，可以事先准备一个没有多余包的纯净python环境</p></div></li></ul><p>生成后项目目录结构将会多出<code>build</code>与<code>dist</code>目录<br><code>dist</code>目录即为生成的打包项目，exe生成在<code>dist\manage\</code>目录里</p><ul><li>运行项目<figure class="highlight dos"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">rem cd进入manage.exe的目录下</span></span><br><span class="line">.\manage.exe runserver</span><br></pre></td></tr></table></figure></li></ul><h1 id="踩坑Start"><a href="#踩坑Start" class="headerlink" title="踩坑Start"></a>踩坑Start</h1><h2 id="hiddenimports配置"><a href="#hiddenimports配置" class="headerlink" title="hiddenimports配置"></a>hiddenimports配置</h2><p>直接生成exe后运行报错提示如<code>No module named XXX</code><br>这是因为打包后的Django有些module不会自动收集，需要手动添加<br>需要在spec文件中修改<code>hiddenimports</code>列表，将未导入的包添加进去<br>如下为这次在GM项目中修改的hiddenimports</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">hiddenimports=[<span class="string">"core.perms"</span>, <span class="string">"corsheaders"</span>, <span class="string">"corsheaders.middleware"</span>, <span class="string">"django.middleware.common"</span>,</span><br><span class="line">             <span class="string">"django.contrib.auth.templatetags"</span>, <span class="string">"apps.suloss.templatetags"</span>, <span class="string">"apps.efwpf.context_processors"</span>,</span><br><span class="line">             <span class="string">"django.contrib"</span>,],</span><br></pre></td></tr></table></figure><h2 id="TemplateDoesNotExist"><a href="#TemplateDoesNotExist" class="headerlink" title="TemplateDoesNotExist"></a>TemplateDoesNotExist</h2><p><em>解决上面的问题之后应该就能正常启动项目</em><br>但是打开网页就会报TemplateDoesNotExist，找不到前端模板<br>由于打包程序只讲python代码部分打包，所以template需要自行复制到打包后的项目目录中<br>根据错误的提示消息，把项目中的模板文件templates拷贝到相应的位置，刷新页面即可。</p><p><em>于GM项目，我将templates目录复制到<code>dist\manage\</code>下即可</em></p><h2 id="xx静态资源xx-lost"><a href="#xx静态资源xx-lost" class="headerlink" title="xx静态资源xx lost"></a>xx静态资源xx lost</h2><p>既然template都没有被打包进去，那么项目引用的静态资源更不必说了<br>解决完上述问题后网页或许可以打开，但引用的本地的静态css和js都会404 not found<br>这里的解决方法如下</p><ol><li>首先在项目的<code>settings.py</code>文件中添加如下代码，其中static是项目中的静态文件位置，static_root是static下的一个空文件夹，然后执行<code>python manage.py collectstatic</code>命令将静态文件收录到<code>static_root</code>中<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">STATIC_ROOT = os.path.join(BASE_DIR, <span class="string">'static'</span>, <span class="string">'static_root'</span>)</span><br></pre></td></tr></table></figure></li><li>然后在项目的<code>urls.py</code>文件中添加如下代码<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> django.conf.urls <span class="keyword">import</span> static</span><br><span class="line"><span class="keyword">from</span> project_1 <span class="keyword">import</span> settings</span><br><span class="line"><span class="comment"># project_1记得改成项目settings所在的目录名</span></span><br><span class="line"> </span><br><span class="line">urlpatterns += static.static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)</span><br></pre></td></tr></table></figure></li></ol><p>到这里之后再<strong>重新打包生成项目</strong>即可√</p><div class="note danger"><p>关于STATIC_ROOT配置，以及<code>python manage.py collectstatic</code>命令的作用等<br>建议看一下下面链接的文章，我就不在这里再写了（lazy…）<br><a href="https://blog.csdn.net/jackliu16/article/details/78861934" target="_blank" rel="noopener">django中STATIC_ROOT和STATICFILES_DIRS区别</a></p><p>简单理解为<code>STATICFILES_DIRS</code>是开发环境的静态资源目录配置，<code>STATIC_ROOT</code>是生产环境的静态资源目录配置，二者目录不可相同</p><p>由于项目中导出xlsx等功能不好再将静态资源放在<code>static\static_root\</code>目录下，<br>我最后的做法是：在打包项目时，将原来的<code>STATICFILES_DIRS = (os.path.join(BASE_DIR, &#39;static&#39;), )</code>配置注释掉，<br><code>STATIC_ROOT</code>配置改为<code>STATIC_ROOT = os.path.join(BASE_DIR, &#39;static&#39;)</code><br>这样打包后的静态资源目录仍然是<code>static\</code></p></div><h2 id="anything-else"><a href="#anything-else" class="headerlink" title="anything else"></a>anything else</h2><p><strong>下面问题可能只与本GM项目相关，仅供参考</strong></p><h3 id="log目录"><a href="#log目录" class="headerlink" title="log目录"></a>log目录</h3><p>解决上述问题后启动仍报错：<code>ValueError: Unable to configure handler &#39;collect&#39;</code>，出在log相关的代码处<br>上面也报有<code>FileNotFoundError: [Errno 2] No such file or directory: &#39;D:\\SVN\\GMs\\03_Source\\trank\\GMsV3.0\\dist\\manage\\log\\collect.log&#39;</code>的错误，想必是并没有生成log目录，也无法在不存在的目录下写入<code>collect.log</code>等log</p><p>解决方法即照报错信息，<span class="label default">在打包项目目录下新建log目录即可</span></p><h3 id="conf目录"><a href="#conf目录" class="headerlink" title="conf目录"></a>conf目录</h3><p>启动时报错<code>[16508] Failed to execute script manage</code><br>具体报错<code>FileNotFoundError: [Errno 2] No such file or directory: &#39;D:\\SVN\\GeneralMills\\03_Source\\trank\\GeneralMillsV3.0\\dist\\manage\\config\\email.json&#39;</code><br>报错处代码读取该文件失败，观察打包的项目中并无config目录，更不会有email.json文件</p><p>GM项目中数据库配置与email配置放在config目录中未被打包，将原项目中config目录复制到打包的项目中即可<br>然而坑爹的是，可能与项目代码读取配置文件的方式有关，读取的目录总是在启动项目命令执行的当前目录中，若在桌面或其他目录中使用exe的绝对路径启动项目，项目会在当前执行的目录中尝试读取config目录的文件<br>这点会影响到之后批处理/运行脚本的编写，即需要cd到exe所在目录中后再运行</p><h3 id="静态资源请求被中间件拦截"><a href="#静态资源请求被中间件拦截" class="headerlink" title="静态资源请求被中间件拦截"></a>静态资源请求被中间件拦截</h3><p><em>上面两个问题简单来说就是“缺啥补啥”，然而本项目中更坑爹的事情出现了。。</em><br>进入页面之后退出登录，进入login界面时，页面竟然渲染不了样式和js，F12查看所有资源均为200正常请求资源，这就很奇怪了<br>后来点进去那些请求回来的静态资源，发现无论css或者是js全部变成了<br><code>&lt;html&gt;&lt;body onLoad=&quot;alert(&#39;登录过期, 请重新登录！&#39;);window.top.location.href=&#39;/login&#39;&quot; &gt;&lt;/body&gt;&lt;/html&gt;</code><br>同时提醒后发现，退出登录状态后，验证权限的中间件将静态资源请求也拦截了下来，<br>原本用django manage.py直接启动时，django会处理本地静态资源所以并不会被拦截<br>然而打包的exe启动后，所有的静态资源请求也变成了“外部请求”，请求会走中间件，于是被拦截<br>解决方法即最后在中间件中判断若请求为<code>/static/</code>开头则放行</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">process_request</span><span class="params">(self, request)</span>:</span></span><br><span class="line">    request_url = request.path_info</span><br><span class="line">    <span class="comment"># print(request_url)</span></span><br><span class="line">    <span class="keyword">for</span> url <span class="keyword">in</span> settings.SAFE_URL:</span><br><span class="line">        <span class="keyword">if</span> re.match(url, request_url):</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">None</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">######</span></span><br><span class="line">    <span class="keyword">if</span> request_url.startswith(<span class="string">'/static/'</span>):</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">None</span></span><br><span class="line">    <span class="comment">######</span></span><br><span class="line"></span><br><span class="line">    userInfo = request.session.get(<span class="string">'userInfo'</span>, <span class="literal">None</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> <span class="keyword">not</span> userInfo:</span><br><span class="line">        <span class="keyword">return</span> self.is_ajax_return(request, <span class="string">"登录过期, 请重新登录！"</span>)</span><br></pre></td></tr></table></figure><h1 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h1><p><a href="https://www.cnblogs.com/liubing8/p/13567271.html" target="_blank" rel="noopener">Django框架14 /pyinstaller打包django项目成exe文件</a><br><a href="https://blog.csdn.net/qq_34809033/article/details/81873896" target="_blank" rel="noopener">pyinstaller打包django项目</a><br><a href="https://www.cnblogs.com/victor0/p/13913534.html" target="_blank" rel="noopener">bat脚本创建桌面快捷方式</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --&gt;&lt;p&gt;工作需要把django应用的环境打包，生成exe&lt;br&gt;花了一下午踩坑pyinstaller打包，稍微memo一下&lt;br&gt;&lt;em&gt;(Django==2.2.5 | Python==3.8.5 | win)&lt;/em&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="Tech" scheme="https://blog8.flyky.org/categories/Tech/"/>
    
      <category term="django" scheme="https://blog8.flyky.org/categories/Tech/django/"/>
    
    
      <category term="note" scheme="https://blog8.flyky.org/tags/note/"/>
    
      <category term="django" scheme="https://blog8.flyky.org/tags/django/"/>
    
      <category term="pyinstaller" scheme="https://blog8.flyky.org/tags/pyinstaller/"/>
    
  </entry>
  
  <entry>
    <title>关于日期时间相关处理的函数（js/py）</title>
    <link href="https://blog8.flyky.org/20210125/Notes-of-Functions-about-datetime/"/>
    <id>https://blog8.flyky.org/20210125/Notes-of-Functions-about-datetime/</id>
    <published>2021-01-25T02:38:16.000Z</published>
    <updated>2021-01-26T09:06:13.103Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --><p>最近工作相关项目有些功能写了/搜集了一些日期时间相关处理的函数，做个笔记<br>Javescript / Python</p><a id="more"></a><h1 id="日期格式化相关"><a href="#日期格式化相关" class="headerlink" title="日期格式化相关"></a>日期格式化相关</h1><ul><li>输入时间戳(number)或其他字符串格式的日期，会转化成年月日形式输出日期，默认分隔符为‘-’<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> formatTime = <span class="function"><span class="keyword">function</span>(<span class="params">time,spliter = <span class="string">'-'</span></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">let</span> date = <span class="keyword">new</span> <span class="built_in">Date</span>(time);</span><br><span class="line">    <span class="keyword">let</span> year = date.getFullYear();</span><br><span class="line">    <span class="keyword">let</span> month = (date.getMonth() + <span class="number">1</span>) &gt;= <span class="number">10</span> ? (date.getMonth() + <span class="number">1</span>) : <span class="string">'0'</span> + (date.getMonth() + <span class="number">1</span>);</span><br><span class="line">    <span class="keyword">let</span> day = date.getDate() &gt;= <span class="number">10</span> ? date.getDate() : <span class="string">'0'</span> + date.getDate();</span><br><span class="line">    <span class="keyword">return</span> <span class="string">`<span class="subst">$&#123;year&#125;</span><span class="subst">$&#123;spliter&#125;</span><span class="subst">$&#123;month&#125;</span><span class="subst">$&#123;spliter&#125;</span><span class="subst">$&#123;day&#125;</span>`</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li></ul><h1 id="日期计算相关"><a href="#日期计算相关" class="headerlink" title="日期计算相关"></a>日期计算相关</h1><ul><li><p>输入两日期<code>d1</code>&amp;<code>d2</code>，计算<code>d1</code>-<code>d2</code>两天数相差的天数</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> getDateDeltaDays = <span class="function"><span class="keyword">function</span>(<span class="params">d1, d2</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// return d2 - d1</span></span><br><span class="line">    <span class="keyword">var</span> a1 = <span class="built_in">Date</span>.parse(<span class="keyword">new</span> <span class="built_in">Date</span>(d1));</span><br><span class="line">    <span class="keyword">var</span> a2 = <span class="built_in">Date</span>.parse(<span class="keyword">new</span> <span class="built_in">Date</span>(d2));</span><br><span class="line">    <span class="keyword">var</span> day = <span class="built_in">parseInt</span>((a2-a1)/ (<span class="number">1000</span> * <span class="number">60</span> * <span class="number">60</span> * <span class="number">24</span>));<span class="comment">// 时间戳相减，然后除以天数</span></span><br><span class="line">    <span class="keyword">return</span> day</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li><p>输入日期<code>start_date</code>与天数<code>day</code>，计算从<code>start_date</code>起<code>day</code>天后的日期</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> getDay = <span class="function"><span class="keyword">function</span>(<span class="params">start_date, day</span>) </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">doHandleMonth</span>(<span class="params">month</span>)</span>&#123;  <span class="comment">// month若为个位数则前面加0</span></span><br><span class="line">      <span class="keyword">var</span> m = month;</span><br><span class="line">      <span class="keyword">if</span>(month.toString().length == <span class="number">1</span>)&#123;</span><br><span class="line">        m = <span class="string">"0"</span> + month;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">return</span> m;</span><br><span class="line">    &#125;;</span><br><span class="line">    <span class="keyword">var</span> start_date = <span class="keyword">new</span> <span class="built_in">Date</span>(start_date)</span><br><span class="line">    <span class="keyword">var</span> targetday_milliseconds=start_date.getTime() + <span class="number">1000</span>*<span class="number">60</span>*<span class="number">60</span>*<span class="number">24</span>*day;</span><br><span class="line">    start_date.setTime(targetday_milliseconds); <span class="comment">//注意，这行是关键代码</span></span><br><span class="line">    <span class="keyword">var</span> tYear = start_date.getFullYear();</span><br><span class="line">    <span class="keyword">var</span> tMonth = start_date.getMonth();</span><br><span class="line">    <span class="keyword">var</span> tDate = start_date.getDate();</span><br><span class="line">    tMonth = doHandleMonth(tMonth + <span class="number">1</span>);</span><br><span class="line">    tDate = doHandleMonth(tDate);</span><br><span class="line">    <span class="keyword">return</span> tYear+<span class="string">"-"</span>+tMonth+<span class="string">"-"</span>+tDate;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li></ul><h1 id="分割-范围"><a href="#分割-范围" class="headerlink" title="分割 / 范围"></a>分割 / 范围</h1><ul><li><p>输入一个日期范围<code>start_date</code> ~ <code>end_date</code>，将按照<code>divideDays</code>的天数将日期范围分割，默认30天分割</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> divideDateRangeList = <span class="function"><span class="keyword">function</span>(<span class="params">start_date, end_date, divideDays=<span class="number">30</span></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">let</span> result = []</span><br><span class="line">    start_date = start_date === <span class="literal">null</span> ? <span class="literal">null</span>:start_date</span><br><span class="line">    end_date = end_date === <span class="literal">null</span> ? <span class="literal">null</span>:end_date</span><br><span class="line">    <span class="keyword">if</span>(!start_date || !end_date) <span class="keyword">return</span> result</span><br><span class="line">    <span class="keyword">if</span>(getDateDeltaDays(start_date, end_date)+<span class="number">1</span> &lt;= divideDays) result.push(&#123;<span class="attr">start</span>: start_date, <span class="attr">end</span>: end_date&#125;)</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">        start = start_date</span><br><span class="line">        <span class="keyword">while</span>(getDateDeltaDays(start, end_date)+<span class="number">1</span> &gt; divideDays) &#123;</span><br><span class="line">            end = getDay(start, divideDays)</span><br><span class="line">            tmp = &#123;<span class="attr">start</span>:start, <span class="attr">end</span>:end&#125;</span><br><span class="line">            result.push(tmp)</span><br><span class="line">            start = getDay(end, <span class="number">1</span>)</span><br><span class="line">        &#125;</span><br><span class="line">        tmp = &#123;<span class="attr">start</span>: start, <span class="attr">end</span>: end_date&#125;</span><br><span class="line">        result.push(tmp)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li><p>输入一个日期范围<code>start_date</code> ~ <code>end_date</code>（需按照‘年-月-日’格式），将返回包含期间所有日期的列表</p><div class="tabs" id="日期范围"><ul class="nav-tabs"><li class="tab active"><a href="#日期范围-1">Javascript</a></li><li class="tab"><a href="#日期范围-2">python</a></li></ul><div class="tab-content"><div class="tab-pane active" id="日期范围-1"><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> getDateRange = <span class="function"><span class="keyword">function</span>(<span class="params">start_date,end_date</span>) </span>&#123;</span><br><span class="line">    range_list = []</span><br><span class="line"></span><br><span class="line">    start_date = start_date ? start_date: <span class="literal">null</span></span><br><span class="line">    end_date = end_date ? end_date: <span class="literal">null</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span>(!start_date || !end_date) <span class="keyword">return</span> range_list</span><br><span class="line"></span><br><span class="line">    start_date = start_date.split(<span class="string">'-'</span>)</span><br><span class="line">    end_date = end_date.split(<span class="string">'-'</span>)</span><br><span class="line">    start_date = <span class="keyword">new</span> <span class="built_in">Date</span>(start_date[<span class="number">0</span>], start_date[<span class="number">1</span>]<span class="number">-1</span>, start_date[<span class="number">2</span>]).getTime()</span><br><span class="line">    end_date = <span class="keyword">new</span> <span class="built_in">Date</span>(end_date[<span class="number">0</span>], end_date[<span class="number">1</span>]<span class="number">-1</span>, end_date[<span class="number">2</span>]).getTime()</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">let</span> i = start_date; i&lt;= end_date;) &#123;</span><br><span class="line">        range_list.push(formatTime(i, <span class="string">'-'</span>))</span><br><span class="line">        i += <span class="number">24</span>*<span class="number">60</span>*<span class="number">60</span>*<span class="number">1000</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> range_list</span><br><span class="line">&#125;</span><br><span class="line">    </span><br></pre></td></tr></table></figure></div><div class="tab-pane" id="日期范围-2"><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> datetime</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">rangeDate</span><span class="params">(start, end)</span>:</span></span><br><span class="line">    result = []</span><br><span class="line">    start_date = datetime.datetime.strptime(start, <span class="string">'%Y-%m-%d'</span>)</span><br><span class="line">    end_date = datetime.datetime.strptime(end, <span class="string">'%Y-%m-%d'</span>)</span><br><span class="line">    step = datetime.timedelta(days=<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span> start_date!=end_date:</span><br><span class="line">        result.append(str(start_date.date()))</span><br><span class="line">        start_date += step</span><br><span class="line">    result.append(end)</span><br><span class="line">    <span class="keyword">return</span> result</span><br><span class="line">    </span><br></pre></td></tr></table></figure></div></div></div></li></ul><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --&gt;&lt;p&gt;最近工作相关项目有些功能写了/搜集了一些日期时间相关处理的函数，做个笔记&lt;br&gt;Javescript / Python&lt;/p&gt;
    
    </summary>
    
      <category term="Tech" scheme="https://blog8.flyky.org/categories/Tech/"/>
    
      <category term="Programming" scheme="https://blog8.flyky.org/categories/Tech/Programming/"/>
    
    
      <category term="note" scheme="https://blog8.flyky.org/tags/note/"/>
    
  </entry>
  
  <entry>
    <title>For own notes 1 in 2020</title>
    <link href="https://blog8.flyky.org/20200805/For-own-notes-1-in-2020/"/>
    <id>https://blog8.flyky.org/20200805/For-own-notes-1-in-2020/</id>
    <published>2020-08-05T09:00:09.000Z</published>
    <updated>2021-01-26T09:06:13.102Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><div id="hexo-blog-encrypt" data-wpm="Oh, this is an invalid password. Check and try again, please." data-whm="OOPS, these decrypted content may changed, but you can still have a look.">  <div class="hbe-input-container">  <input type="password" id="hbePass" placeholder="Hey, password is required here." />    <label for="hbePass">Hey, password is required here.</label>    <div class="bottom-line"></div>  </div>  <script id="hbeData" type="hbeData" data-hmacdigest="d03ba9f2f8c0a588f1dacf797cd64345971ff54f9758767b92cbffc116f25dca">768b4bf8f838d38ec91d0597dbbce7e7bff99f9da1272849fa14e7da9438506ce454a2ddec95d5aeac264a0741fa271c8c6e8a4218749ac520c713f84f69c1c99a9f56aa0d254802a375243340ab9b2ca199fb9dbed86d3968ec0920df7589dbd810de45d85f9cbae257f8482ef616a49df850825a8d0ffee652374e8e2f4f1349471efcdf11ee16a5d58f9376f09cd58d4107f3582e565dbe5af7b65824b3f565cb5845567d9d7b9cf0bb47c682fa021000624aa996083f99843f7cfd88222b1ca3d3f0918d1ec339eadf33c85326a63994df964c94e9fd400e221f08efbd16f90cac99eb27d9f9814f7d2b9ec066d6cadf228e9791e471e21f61455d79fb2de66a60ec1ba089904f4e85df6db241503f04768748f19fc750b14533715c6875c2a38c7f551d7fa9d404beb96682ff1b14492a528573021330f58b8a882d62d4aebb0ee561744b4118911fa8e5897e55d1d0b1e1de7839e67ca8ebbbf18f153a53a6685b5a2bd84aa624f933a7f8a3e687f97192fe082b869f12c84e64399f0184ee5d4486fc56db79899c0f4332c9cc086f7d2521904336b6f0ae78f59ac222a1ce982220aeb0dc7c39c5ca7925ec08fa416373c61cab49fe2187d0be0b1c7bd23a619e617a6dda9f4bb3e2afed38a77d89efb878f4068ede2788de5c62277e88d196465eb6ed5a31a08912621bc0d4ca43fa7fe8a18d60107be373580f7d25</script></div><script src="/lib/blog-encrypt.js"></script><link href="/css/blog-encrypt.css" rel="stylesheet" type="text/css">]]></content>
    
    <summary type="html">
    
      Here&#39;s something encrypted, password is required to continue reading.
    
    </summary>
    
    
      <category term="note" scheme="https://blog8.flyky.org/tags/note/"/>
    
  </entry>
  
  <entry>
    <title>Nginx目录列表(autoindex)配置相关以及页面美化</title>
    <link href="https://blog8.flyky.org/20191128/nginx-autoindex-conf/"/>
    <id>https://blog8.flyky.org/20191128/nginx-autoindex-conf/</id>
    <published>2019-11-28T05:26:38.000Z</published>
    <updated>2021-01-26T09:06:13.106Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --><p>Nginx做静态资源服务器是一个十分基础的应用了，但是一般默认是不会将静态资源的目录直接列出来的。不过要想直接列出目录内的文件，做一个目录文件列表也是他原生的功能，配置也十分简单，只需要配置autoindex项即可。<br>一般在网络上很容易见到的一些资源站、下载站之类的、甚至是某些镜像站，也是通过配置nginx的autoindex实现的，如下图页面<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/163_mirror_autoindex.webp" alt="163_mirror_autoindex"></p><a id="more"></a><h1 id="autoindex配置"><a href="#autoindex配置" class="headerlink" title="autoindex配置"></a>autoindex配置</h1><h2 id="配置项相关"><a href="#配置项相关" class="headerlink" title="配置项相关"></a>配置项相关</h2><p>autoindex项的默认值是off，开启目录列表只需要在<code>server</code>或者<code>location</code>块里配置<code>autoindex on;</code>即可<br>我下面的示例是会在location路由块里配置，<span class="label primary">主要还是觉得在location块里设置会比较好</span></p><p>当然除了配置autoindex项之外，还有一些其他的配置项，如下表</p><table><thead><tr><th align="left">配置项</th><th align="center">值</th><th align="center">描述</th></tr></thead><tbody><tr><td align="left">autoindex</td><td align="center">on / off</td><td align="center">默认 off，不开启目录浏览<br>on,开启目录浏览</td></tr><tr><td align="left">autoindex_exact_size</td><td align="center">on / off</td><td align="center">默认 on，精确文件大小显示，单位Bytes<br>推荐 off，文件大小显示使用KB/MB/GB单位估算显示</td></tr><tr><td align="left">autoindex_format</td><td align="center">html / xml / json / jsonp</td><td align="center">目录列表的显示格式<br>默认 html</td></tr><tr><td align="left">autoindex_localtime</td><td align="center">on / off</td><td align="center">默认 off，显示的文件时间为GMT时间<br>on，显示的文件时间为文件的服务器时间</td></tr></tbody></table><div class="note warning"><p>这里还需要配置charset使目录支持中文显示，否则中文文件名会产生乱码<br><code>charset utf-8,gbk;</code></p></div><p>这里贴出一段示例的配置</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">location</span> /dl/ &#123;</span><br><span class="line">    <span class="attribute">root</span> /home/flyky/fileindex/;</span><br><span class="line">    <span class="attribute">charset</span> utf-<span class="number">8</span>;</span><br><span class="line"></span><br><span class="line">    <span class="attribute">autoindex</span> <span class="literal">on</span>;</span><br><span class="line">    <span class="attribute">autoindex_exact_size</span> <span class="literal">off</span>;</span><br><span class="line">    <span class="attribute">autoindex_format</span> html;</span><br><span class="line">    <span class="attribute">autoindex_localtime</span> <span class="literal">on</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="关于-root-与-alias"><a href="#关于-root-与-alias" class="headerlink" title="关于 root 与 alias"></a>关于 root 与 alias</h2><p><strong>上面示例配置中，列出的目录在主机上的位置是<code>/home/flyky/fileindex/dl/</code></strong><br>上面使用的是<code>root</code>指令来配置服务请求的<strong>根目录</strong>，因为要列出的是<code>fileindex</code>下的<code>dl</code>目录，所以在<code>root</code>项中应该配置<code>dl</code>所在的<code>fileindex</code>目录为根目录，然后在<code>location</code>配置<code>dl</code>目录的路由<br>也就是说，<code>root</code>配置的是资源的根目录，是所要做文件列表展示的目录的『所在目录』或者说是『上层目录』，而不是被展示列表的那个目录 ，并且要确保<code>location</code>路由的目录，也就是目录<code>dl</code>在<code>fileindex</code>目录下</p><p>当然，上面说得这么绕，还有一种情况，使用alias就好理解一点了<br>alias即<strong>别名</strong>，也就是给服务请求的目录起了一个别名，譬如配置<code>/home/flyky/fileindex/dl/</code>的目录的路由为<code>/download</code>，我们可以这样写</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">location</span> /download/ &#123;</span><br><span class="line">    <span class="attribute">alias</span> /home/flyky/fileindex/dl/;</span><br><span class="line">    <span class="attribute">autoindex</span> <span class="literal">on</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>假设server为localhost，监听8080端口，这里我们访问<code>localhost:8080/download/</code>浏览到的就是<code>dl</code>目录，之后访问的uri内所有的<code>/download/</code>都会被<strong>替换</strong>成<code>/home/flyky/fileindex/dl/</code>目录，相当于是给<code>dl</code>目录起了个别名<code>download</code>，也有点类似与linux里的目录软链接<br>但是这里有个坑，由于这个<code>alias</code>实际是用的“替换”路径，所以在配置location项的路由名后面一定要加上<code>/</code>，比如上面例子的<code>/download/</code>，如果不加上斜杠的话，比如要访问主机<code>dl/test.png</code>图片资源，那在浏览器中应该访问的地址是<code>servername:port/dowload/test.png</code>，服务器访问会被替换成<code>dltest.png</code>，一定会报<code>404 not found</code>的。<br>当然如果使用root设置根目录的话就没必要后添斜杠了，location配置直接<code>/download</code>就可以</p><h2 id="其他"><a href="#其他" class="headerlink" title="其他"></a>其他</h2><p>注意访问的目录权限，如果nginx无法访问到该目录报了403 forbidden错误的话，大概率是权限问题<br>查看配置的目录的访问权限以及所有者，启动nginx的用户是否可以访问该目录<br>另外最好不要设置访问<code>/root</code>，普通用户无法访问root目录下的文件，如果一定要设置root目录或者其他root用户权限目录下的目录，可以更改nginx的配置文件，将<code>user</code>项配置成<code>root</code>用户。</p><h1 id="autoindex页面的美化"><a href="#autoindex页面的美化" class="headerlink" title="autoindex页面的美化"></a>autoindex页面的美化</h1><p>配置好的autoindex页面效果极度简洁，并不美观，如果想要赏心悦目那必定还得一番折腾</p><h2 id="安装-ngx-fancyindex-插件"><a href="#安装-ngx-fancyindex-插件" class="headerlink" title="安装 ngx-fancyindex 插件"></a>安装 <a href="https://github.com/aperezdc/ngx-fancyindex" target="_blank" rel="noopener">ngx-fancyindex</a> 插件</h2><p>首先需要给Nginx安装ngx-fancyindex插件，安装方法还是编译安装，<a href="../../20190630/Nginx-make-install-script">之前的博文</a>已经具体写过nginx编译安装了，这里也不赘述了。这里只描述给已安装的nginx添加插件的过程</p><p>使用<code>2&gt;&amp;1 nginx -V | tr &#39; &#39; &#39;\n&#39;|grep module</code>命令可以查看当前nginx编译安装好的模块</p><p>首先在nginx源码包目录下下载解压插件ngx-fancyindex源码，直接git clone也好</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/aperezdc/ngx-fancyindex.git ngx-fancyindex</span><br></pre></td></tr></table></figure><p>然后将 <code>--add-module=ngx-fancyindex \</code> 添加到configure配置中执行configure<br>如果没有用<a href="../../20190630/Nginx-make-install-script/#configure脚本">Nginx编译安装指北</a>这篇博文里的configure脚本的话，可以使用<code>nginx -V</code>，可以查看到当初安装nginx的configure参数配置。</p><p><code>configure</code>执行后<code>make</code>编译，编译结束后不需要<code>make install</code>了（当然如果你还没有安装nginx的话直接<code>make install</code>就可以了）<br>进入nginx源码目录下的<code>objs</code>目录，可以看到编译好的nginx可执行程序文件<br>首先执行<code>2&gt;&amp;1 ./nginx -V | tr &#39; &#39; &#39;\n&#39;|grep fan</code>查看是否编译了插件，没问题了之后再把<code>objs/nginx</code>复制替换到安装位置的nginx就可以了，我的configure参数设置了<code>sbin-path</code>为<code>/usr/sbin/nginx</code>,所以我只需要把objs下的nginx复制到<code>/usr/sbin/</code>即可。</p><h2 id="fancyindex主题安装配置"><a href="#fancyindex主题安装配置" class="headerlink" title="fancyindex主题安装配置"></a>fancyindex主题安装配置</h2><p>插件安装好之后就可以使用fancyindex主题了。<br>去github搜fancyindex-theme就能看到很多别人写好的主题，随便选一个，然后根据文档进行配置即可</p><span class="label danger">因为根据不同的主题可能有不同的安装方法，我就不详细讲关于主题的安装配置了</span><p>我这里是使用的是<a href="https://github.com/Naereen/Nginx-Fancyindex-Theme" target="_blank" rel="noopener">Naereen/Nginx-Fancyindex-Theme</a>，也有<a href="https://perso.crans.org/besson/publis/Nginx-Fancyindex-Theme/" target="_blank" rel="noopener">使用文档</a><br>使用效果如图<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/autoindex_flyky.webp" alt="autoindex_flyky"></p><p>其实主题安装配置过程讲起来也就几步</p><ul><li>首先下载主题解压到网站根目录，或者git clone到网站根目录</li><li>然后在nginx的配置autoindex的location块中引入fancyindex配置文件<br><code>include /your/website/root/fancyindex.conf</code></li><li>之后你也可以修改fancyindex配置文件，譬如我使用的这个主题可以配置light或dark两种配色主题等</li></ul><p>这里要注意主题要放在网站根目录，同时也要配置好<code>location /</code>的路由</p><h1 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h1><p><a href="https://segmentfault.com/a/1190000012606305" target="_blank" rel="noopener">Nginx浏览目录配置及美化</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --&gt;&lt;p&gt;Nginx做静态资源服务器是一个十分基础的应用了，但是一般默认是不会将静态资源的目录直接列出来的。不过要想直接列出目录内的文件，做一个目录文件列表也是他原生的功能，配置也十分简单，只需要配置autoindex项即可。&lt;br&gt;一般在网络上很容易见到的一些资源站、下载站之类的、甚至是某些镜像站，也是通过配置nginx的autoindex实现的，如下图页面&lt;br&gt;&lt;img src=&quot;https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/163_mirror_autoindex.webp&quot; alt=&quot;163_mirror_autoindex&quot;&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="Tech" scheme="https://blog8.flyky.org/categories/Tech/"/>
    
      <category term="nginx" scheme="https://blog8.flyky.org/categories/Tech/nginx/"/>
    
    
      <category term="nginx" scheme="https://blog8.flyky.org/tags/nginx/"/>
    
  </entry>
  
  <entry>
    <title>Redis编译安装以及service配置</title>
    <link href="https://blog8.flyky.org/20191113/Redis-makeinstall-and-service/"/>
    <id>https://blog8.flyky.org/20191113/Redis-makeinstall-and-service/</id>
    <published>2019-11-13T14:55:47.000Z</published>
    <updated>2021-01-26T09:06:13.103Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --><p>今天写这篇的原因是刚好在搭建一个东西需要用到redis环境，关于原因也就不多说了。<br><a href="https://redis.io" target="_blank" rel="noopener">Redis</a>是什么这种问题也不具体说了，就是一个基于内存的数据库软件。这边贴一段百科的介绍，具体的可以自己去查资料。</p><blockquote class="blockquote-center"><p>Redis 是完全开源免费的，遵守BSD协议，是一个高性能的key-value数据库。</p></blockquote><p>这篇的操作是<strong>基于linux的安装</strong>，redis版本5.0，Windows可以退散了。<br>这边就不扯其他的了，单刀直入地讲了</p><a id="more"></a><h1 id="源码编译安装"><a href="#源码编译安装" class="headerlink" title="源码编译安装"></a>源码编译安装</h1><p><em>为什么选择源码编译安装，这点我在介绍<a href="../../20190630/Nginx-make-install-script/">【nginx编译安装】</a>那篇博文里讲过一点原因，redis的话主要还是因为软件包管理安装的版本比较老吧。</em></p><p>惯例编译安装前需要安装gcc和make，<em>如果是ubuntu可以直接安装<code>build-essential</code></em>，这点我在nginx编译安装那篇也说过了，不赘述。</p><p>首先在<a href="https://redis.io/download" target="_blank" rel="noopener">官网下载redis源码包</a>后解压，进入解压的源码包目录直接<code>make</code>、<code>make install</code>两步走就行了</p><p>这边<code>make install</code>默认的redis安装位置在<code>/usr/local</code>目录下，二进制文件在<code>/usr/local/bin</code>，不是root用户的话可能需要<code>sudo</code><br>如果需要改变安装位置的话可以在<code>make install</code>后指定<code>PREFIX</code><br>譬如<code>make install PREFIX=/usr/local/redis</code>修改安装位置在<code>/usr/local/redis</code>下，二进制文件就在<code>/usr/local/redis/bin</code>里。</p><p>我这里还是按照默认的位置安装，这样的话安装完成后可以直接使用<code>redis-server</code>测试运行一下。</p><h1 id="配置文件"><a href="#配置文件" class="headerlink" title="配置文件"></a>配置文件</h1><p>redis源码包里有示例的配置文件，我们直接使用即可，不过建一个专门存放redis配置文件的目录比较好，一般软件的配置文件都放在<code>/etc</code>下<br>我们就在<code>/etc</code>下创建一个redis的目录用来存放redis的配置文件，然后把源码包下的示例配置文件复制过去，并重命名为<code>6379.conf</code></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo mkdir /etc/redis</span><br><span class="line">sudo cp /your/redis/redis.conf /etc/redis/6379.conf</span><br></pre></td></tr></table></figure><p><strong>这里重命名的6379是redis默认的启动端口。</strong></p><p>现在修改一下<code>6379.conf</code>这个配置文件<br>将里面的<code>daemonize no</code>改为<code>yes</code>，启用后台运行</p><h1 id="添加服务项"><a href="#添加服务项" class="headerlink" title="添加服务项"></a>添加服务项</h1><p>这边参考了<a href="https://www.cnblogs.com/rstyro/articles/10715759.html" target="_blank" rel="noopener">这篇博文</a>的内容，感兴趣可以看看</p><h2 id="关于linux的系统服务管理的说明"><a href="#关于linux的系统服务管理的说明" class="headerlink" title="关于linux的系统服务管理的说明"></a>关于linux的系统服务管理的说明</h2><p>linux的系统服务管理命令主要有两个，<code>service</code>和<code>systemctl</code>。<br>现在新版本发行版的linux基本上都是用<code>systemctl</code>，然后<code>service</code>命令也可以使用，但是执行时会被重写成<code>systemctl</code>命令，所以实际上用的还是<code>systemctl</code>。服务项的配置一般是放在<code>/etc/systemd/system</code>或者<code>/lib/systemd/system</code>下的，这个根据发行版本不同略有区别，自行确认。<br>老一点的发行版本可能用的就是原来的<code>service</code>命令，它的命令脚本位置一般在<code>/etc/init.d</code>或者<code>/etc/rc.d/init.d</code>下，根据发行版本不同略有区别，自行确认。</p><p>这边接下来就根据这两个不同情况来说明配置方法:</p><h2 id="systemctl-systemd"><a href="#systemctl-systemd" class="headerlink" title="systemctl(systemd)"></a>systemctl(systemd)</h2><p>上面也说过了，服务配置可能放在<code>/etc/systemd/system</code>或者<code>/lib/systemd/system</code>下，自行确认。<br>现在服务配置的目录下新建一个<code>redis.service</code>脚本，内容如下</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">[Unit]</span><br><span class="line">Description=Redis</span><br><span class="line">After=syslog.target network.target remote-fs.target nss-lookup.target</span><br><span class="line"></span><br><span class="line">[Service]</span><br><span class="line">Type=forking</span><br><span class="line">PIDFile=/var/run/redis_6379.pid</span><br><span class="line">ExecStart=/usr/<span class="built_in">local</span>/bin/redis-server /etc/redis/6379.conf</span><br><span class="line">ExecReload=/bin/<span class="built_in">kill</span> -s HUP <span class="variable">$MAINPID</span></span><br><span class="line">ExecStop=/bin/<span class="built_in">kill</span> -s QUIT <span class="variable">$MAINPID</span></span><br><span class="line">PrivateTmp=<span class="literal">true</span></span><br><span class="line"></span><br><span class="line">[Install]</span><br><span class="line">WantedBy=multi-user.target</span><br></pre></td></tr></table></figure><p>这里要注意，里面变量的具体值要是你自身安装的实际情况自行修改，譬如你修改了安装位置，那么<code>ExecStart</code>项里<code>redis-server</code>的绝对路径肯定也是要修改的<br>然后提一下这个<code>PIDFile</code>的值是和6379配置文件里的<code>pidfile</code>项一致。</p><p>接下来重载一下系统服务，就可以使用redis服务了</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">systemctl daemon-reload  <span class="comment"># 重载系统服务</span></span><br><span class="line"></span><br><span class="line">systemctl start redis <span class="comment"># 启动redis服务</span></span><br><span class="line">systemctl status redis <span class="comment"># 查看redis服务状态</span></span><br><span class="line">systemctl stop redis <span class="comment"># 停止redis服务</span></span><br></pre></td></tr></table></figure><h2 id="service-init-d"><a href="#service-init-d" class="headerlink" title="service(init.d)"></a>service(init.d)</h2><p>一开始也说过了，服务配置脚本位置可能在<code>/etc/init.d</code>或者<code>/etc/rc.d/init.d</code>下，自行确认<br>在redis的源码包下的<code>utils</code>目录里有redis服务的启动脚本，我们只需要将它复制到系统服务配置的目录下即可，这里假设是<code>/etc/init.d</code></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo cp /your/redis/utils/redis_init_script /etc/init.d/redis</span><br></pre></td></tr></table></figure><p>然后将下面两行的内容添加到<code>redis</code>启动脚本的第二、三行（也就是<code>#!/bin/sh</code>的下面）</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># chkconfig: 2345 90 10</span></span><br><span class="line"><span class="comment"># description: Redis is a persistentkey-value database</span></span><br></pre></td></tr></table></figure><p>指的是redis服务必须在运行级2，3，4，5下被启动或关闭，启动的优先级是90，关闭的优先级是10。</p><p>接下来就可以添加并使用服务了</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">chkconfig --add redis       <span class="comment"># 如果没报错的话，说明成功，可以用</span></span><br><span class="line">chkconfig --list            <span class="comment"># 查看所有服务</span></span><br><span class="line"></span><br><span class="line">service redis start         <span class="comment"># 启动redis服务</span></span><br><span class="line">service redis status         <span class="comment"># 查看redis服务状态</span></span><br><span class="line">service redis stop         <span class="comment"># 关闭redis服务</span></span><br></pre></td></tr></table></figure><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --&gt;&lt;p&gt;今天写这篇的原因是刚好在搭建一个东西需要用到redis环境，关于原因也就不多说了。&lt;br&gt;&lt;a href=&quot;https://redis.io&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Redis&lt;/a&gt;是什么这种问题也不具体说了，就是一个基于内存的数据库软件。这边贴一段百科的介绍，具体的可以自己去查资料。&lt;/p&gt;&lt;blockquote class=&quot;blockquote-center&quot;&gt;&lt;p&gt;Redis 是完全开源免费的，遵守BSD协议，是一个高性能的key-value数据库。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;这篇的操作是&lt;strong&gt;基于linux的安装&lt;/strong&gt;，redis版本5.0，Windows可以退散了。&lt;br&gt;这边就不扯其他的了，单刀直入地讲了&lt;/p&gt;
    
    </summary>
    
      <category term="Tech" scheme="https://blog8.flyky.org/categories/Tech/"/>
    
      <category term="redis" scheme="https://blog8.flyky.org/categories/Tech/redis/"/>
    
    
      <category term="redis" scheme="https://blog8.flyky.org/tags/redis/"/>
    
  </entry>
  
  <entry>
    <title>Gitea安装部署自建git托管系统</title>
    <link href="https://blog8.flyky.org/20191111/gitea-install/"/>
    <id>https://blog8.flyky.org/20191111/gitea-install/</id>
    <published>2019-11-10T17:16:18.000Z</published>
    <updated>2021-01-26T09:06:13.105Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --><p>在之前<a href="../../20191105/build-git-server-to-use-hexo-deploy/#在服务器上搭建git服务并配置">【自建git服务实现hexo博客部署】</a>这篇博文中提到了如何自建git服务远程仓库。这种方式需要在远程端输入命令来创建仓库和配置，比较麻烦，更希望可以搭建一个像github一样的web环境来方便地进行管理仓库以及配置。<br>突然想到chino把TIS外服的白名单放在自建的git服务下托管，每个部落的管理即使不懂得git也可以在网页上管理各自的白名单。一看原来是用<a href="https://gogs.io/" target="_blank" rel="noopener">Gogs</a>搭建的<br>上网搜了一下还有很多人推荐<a href="https://gitea.io/zh-cn/" target="_blank" rel="noopener">Gitea</a>，gitea是从Gogs源码的基础上开发的，听说使用起来也很不错，而且维护更新也更频繁，于是我就选择了<a href="https://gitea.io/zh-cn/" target="_blank" rel="noopener">Gitea</a><br>官方也是很有趣，官网上写着 「Git with a cup of tea」，这大概也是gitea名字的含义吧。</p><blockquote class="blockquote-center"><p>Gitea 是一个开源社区驱动的轻量级代码托管解决方案，后端采用 Go 编写，采用 MIT 许可证</p></blockquote><a id="more"></a><p>先来看一下我部署好的gitea的首页界面<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/Flyky_gitea_index.webp" alt="Flyky_gitea_index"></p><h1 id="安装MySQL数据库"><a href="#安装MySQL数据库" class="headerlink" title="安装MySQL数据库"></a>安装MySQL数据库</h1><p>Gitea需要有数据库，支持postgresql、mysql、sqlite，那我这里还是选择MySQL。我们选择安装软件源，用包管理安装</p><h2 id="下载软件源"><a href="#下载软件源" class="headerlink" title="下载软件源"></a>下载软件源</h2><p>首先要下载软件源，去<a href="https://dev.mysql.com/downloads/" target="_blank" rel="noopener">MySQL的官网下载站点</a>下载软件源，我这里用的是CentOS，所以我使用<code>Yum Repository</code><br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/mysql_repo_download.webp" alt="mysql_repo_download"><br>选择相应系统版本的软件源下载，然后点击右侧的小感叹号（红框框出），在下面会有链接跳转到用该软件源安装的quick guide（指南），里面会详细的讲解如何使用软件源安装mysql<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/mysql_yum_quick_guide_link.webp" alt="mysql_yum_quick_guide_link"></p><div class="note warning"><p>由于我这里使用的yum，我在下面也简单的描述一下用yum软件源安装的过程，其他的譬如apt可以看指南步骤安装</p></div>## 安装软件源 首先将下载的软件源安装好<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo rpm -Uvh mysql80-community-release-el7-3.noarch.rpm</span><br></pre></td></tr></table></figure>## 选择mysql安装的release版本 首先先查看一下安装的软件源里包含了哪些包，以及默认启用的包版本<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum repolist all | grep mysql</span><br></pre></td></tr></table></figure>我这里看到默认启用的是mysql8。0 ![mysql_grep_default](https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/mysql_grep_default.webp) 但是我要装的是5.7的版本，所以我们需要禁用8.0的源，启用5.7<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo yum-config-manager --<span class="built_in">disable</span> mysql80-community</span><br><span class="line">sudo yum-config-manager --<span class="built_in">enable</span> mysql57-community</span><br></pre></td></tr></table></figure>然后用下面的命令查看一下启用的包，会发现8.0没有了，5.7启用成功<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum repolist enabled | grep mysql</span><br></pre></td></tr></table></figure>## 安装mysql<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo yum install mysql-community-server</span><br></pre></td></tr></table></figure>安装完毕后`mysqld -V`查看一下mysql版本，确认是5.7 ## 启动mysql服务<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">sudo service mysqld start</span><br><span class="line"><span class="comment"># 或者</span></span><br><span class="line">sudo systemctl start mysqld.service</span><br></pre></td></tr></table></figure>上面的命令启动mysql服务。 ## 查看密码 / 设置密码<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep <span class="string">'temporary password'</span> /var/<span class="built_in">log</span>/mysqld.log</span><br></pre></td></tr></table></figure>可以查看到安装时自动生成的root密码 如果什么都没有查到说明没有生成密码，可以直接`mysql -uroot -p`登录，然后设置密码`mysqladmin -u root password "newpwd"` 如果查到了密码，登陆后要修改密码<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">alter</span> <span class="keyword">user</span> <span class="string">'root'</span>@<span class="string">'localhost'</span> <span class="keyword">identified</span> <span class="keyword">by</span> <span class="string">'your-new-passwd'</span>;</span><br></pre></td></tr></table></figure><div class="note danger"><p>假如更新密码时遇到了<code>ERROR 1819 (HY000): Your password does not satisfy the current policy requirements</code>的错误提示<br>可以看一下<a href="https://blog.csdn.net/hello_world_qwp/article/details/79551789" target="_blank" rel="noopener">这篇文章</a>的解决方法</p></div><h1 id="安装Gitea前的准备"><a href="#安装Gitea前的准备" class="headerlink" title="安装Gitea前的准备"></a>安装Gitea前的准备</h1><h2 id="创建git用户（组）"><a href="#创建git用户（组）" class="headerlink" title="创建git用户（组）"></a>创建git用户（组）</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">groupadd git</span><br><span class="line">useradd -g git git -s /bin/git-shell</span><br></pre></td></tr></table></figure><p>上面命令创建了一个git用户并加入了git用户组（并且为了安全禁止使用shell登录，这个创建用户后也可以在<code>/etc/passwd</code>文件里修改），我们接下来就用这个git用户运行gitea程序。</p><p><em>当然这一步不做也可以，不用git用户的话用当前用户或者root用户也可以，只是在配置gitea的时候要注意一下</em></p><h2 id="创建gitea数据库"><a href="#创建gitea数据库" class="headerlink" title="创建gitea数据库"></a>创建gitea数据库</h2><p>使用下面的sql代码创建gitea数据库<br><strong>注意将示例代码中的<code>gitea</code>、<code>gitea_user</code>、<code>gitea_password</code>替换成实际的内容</strong></p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">create</span> <span class="keyword">database</span> gitea <span class="keyword">DEFAULT</span> <span class="built_in">CHARACTER</span> <span class="keyword">SET</span> utf8 <span class="keyword">DEFAULT</span> <span class="keyword">COLLATE</span> utf8_general_ci;</span><br><span class="line"><span class="keyword">CREATE</span> <span class="keyword">USER</span> <span class="string">'gitea_user'</span>@<span class="string">'localhost'</span> <span class="keyword">IDENTIFIED</span> <span class="keyword">BY</span> <span class="string">'git_password'</span>;</span><br><span class="line"><span class="keyword">GRANT</span> <span class="keyword">ALL</span> <span class="keyword">PRIVILEGES</span> <span class="keyword">ON</span> gitea.* <span class="keyword">TO</span> gitea_user@localhost <span class="keyword">IDENTIFIED</span> <span class="keyword">BY</span> <span class="string">'gitea_password'</span>;</span><br><span class="line"><span class="keyword">FLUSH</span> <span class="keyword">PRIVILEGES</span>;</span><br></pre></td></tr></table></figure><h1 id="启动并配置Gitea"><a href="#启动并配置Gitea" class="headerlink" title="启动并配置Gitea"></a>启动并配置Gitea</h1><h2 id="启动Gitea与安装配置"><a href="#启动Gitea与安装配置" class="headerlink" title="启动Gitea与安装配置"></a>启动Gitea与安装配置</h2><p>第一次启动gitea</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">chmod +x gitea</span><br><span class="line">./gitea web</span><br></pre></td></tr></table></figure><p>web默认端口在3000，打开gitea页面之后，随便点击界面上的按钮（注册，登录之类的），或者在地址后加上<code>/install</code>，会跳转到『初始配置』页面进行安装前的配置，如下图：<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/gitea_first_config.webp" alt="gitea_first_config"></p><p>这里的配置按照自己的实际情况来就可以了，配置完之后安装即可<br>配置之后也是可以更改的，gitea的配置文件在<code>gitea/custom/conf/app.ini</code><br>具体的配置项可以去官方文档查看，也可以在本文的<a href="#参考文章">参考文章</a>里的文章里查看</p><h2 id="创建gitea-service来启动Gitea"><a href="#创建gitea-service来启动Gitea" class="headerlink" title="创建gitea service来启动Gitea"></a>创建gitea service来启动Gitea</h2><p>这里配置的是<code>systemctl</code>命令的系统服务。关于linux的系统服务管理相关，我在<a href="../../20191113/Redis-makeinstall-and-service/#关于linux的系统服务管理的说明">这篇博文</a>中提过，建议先去了解一下。</p><p>由于我们创建的git账户无法使用shell登录，不好直接用git用户启动gitea，我们选择创建一个服务来启动关闭gitea。下面的创建服务的位置要根据你自己系统的service文件的实际位置改变，我这里是centos，所以在<code>/etc</code>目录下</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vim /etc/systemd/system/gitea.service  <span class="comment">#创建gitea.service</span></span><br></pre></td></tr></table></figure><p>下面是一份示例，可以根据实际情况修改</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">[Unit]</span><br><span class="line">Description=Gitea (Git with a cup of tea)</span><br><span class="line">After=syslog.target</span><br><span class="line">After=network.target</span><br><span class="line"></span><br><span class="line">[Service]</span><br><span class="line">RestartSec=2s</span><br><span class="line">Type=simple</span><br><span class="line">User=git</span><br><span class="line">Group=git</span><br><span class="line">WorkingDirectory=/usr/program/gitea/</span><br><span class="line">ExecStart=/usr/program/gitea/gitea web -c /usr/program/gitea/custom/conf/app.ini</span><br><span class="line">Restart=always</span><br><span class="line">Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/usr/program/gitea</span><br><span class="line">CapabilityBoundingSet=CAP_NET_BIND_SERVICE</span><br><span class="line">AmbientCapabilities=CAP_NET_BIND_SERVICE</span><br><span class="line"></span><br><span class="line">[Install]</span><br><span class="line">WantedBy=multi-user.target</span><br></pre></td></tr></table></figure><p>之后就可以通过<code>service gitea start</code>，<code>service gitea stop</code>，<code>service gitea status</code><br>或者<code>systemctl start gitea</code>，<code>systemctl stop gitea</code>，<code>systemctl status gitea</code>来开关和查看状态了</p><h1 id="Nginx反向代理设置"><a href="#Nginx反向代理设置" class="headerlink" title="Nginx反向代理设置"></a>Nginx反向代理设置</h1><p>如果需要用nginx反向代理的话。<br>这次我贴出一份完整的我的nginx配置(当然域名和证书路径还是假的啦)<br>我用了ssl证书，监听80重定向到443</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">server</span> &#123;</span><br><span class="line">    <span class="attribute">listen</span> <span class="number">80</span>;</span><br><span class="line">    <span class="attribute">server_name</span> git.example.com  git.example.cn;</span><br><span class="line">    <span class="attribute">rewrite</span><span class="regexp"> ^(.*)$</span> https://<span class="variable">$&#123;server_name&#125;</span><span class="variable">$1</span> <span class="literal">permanent</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="section">server</span> &#123;</span><br><span class="line">    <span class="attribute">listen</span> <span class="number">443</span> ssl;</span><br><span class="line">    <span class="attribute">server_name</span> git.example.com  git.example.cn;</span><br><span class="line"></span><br><span class="line">    <span class="attribute">ssl_certificate</span> /your/ssl/certificate/location;</span><br><span class="line">    <span class="attribute">ssl_certificate_key</span> /your/ssl/certificate/key/location;</span><br><span class="line">    <span class="attribute">ssl_protocols</span> TLSv1.<span class="number">2</span> TLSv1.<span class="number">1</span> TLSv1;</span><br><span class="line">    <span class="attribute">ssl_prefer_server_ciphers</span> <span class="literal">on</span>;</span><br><span class="line">    <span class="attribute">ssl_session_cache</span> shared:SSL:<span class="number">1m</span>;</span><br><span class="line">    <span class="attribute">ssl_session_timeout</span> <span class="number">5m</span>;</span><br><span class="line"></span><br><span class="line">    <span class="attribute">location</span> / &#123;</span><br><span class="line">        <span class="attribute">proxy_pass</span> http://127.0.0.1:3000;</span><br><span class="line">        <span class="attribute">proxy_set_header</span> Host <span class="variable">$host</span>;</span><br><span class="line">        <span class="attribute">proxy_set_header</span> X-Forwarded-For <span class="variable">$proxy_add_x_forwarded_for</span>;</span><br><span class="line">        <span class="attribute">proxy_set_header</span> X-Real-IP <span class="variable">$remote_addr</span>;</span><br><span class="line">        <span class="attribute">proxy_set_header</span> X-Nginx-Proxy <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="attribute">expires</span> max;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h1><ul><li><a href="https://5h.work/posts/24536989/" target="_blank" rel="noopener">CentOS 安装 Gitea 和错误处理</a></li></ul><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --&gt;&lt;p&gt;在之前&lt;a href=&quot;../../20191105/build-git-server-to-use-hexo-deploy/#在服务器上搭建git服务并配置&quot;&gt;【自建git服务实现hexo博客部署】&lt;/a&gt;这篇博文中提到了如何自建git服务远程仓库。这种方式需要在远程端输入命令来创建仓库和配置，比较麻烦，更希望可以搭建一个像github一样的web环境来方便地进行管理仓库以及配置。&lt;br&gt;突然想到chino把TIS外服的白名单放在自建的git服务下托管，每个部落的管理即使不懂得git也可以在网页上管理各自的白名单。一看原来是用&lt;a href=&quot;https://gogs.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Gogs&lt;/a&gt;搭建的&lt;br&gt;上网搜了一下还有很多人推荐&lt;a href=&quot;https://gitea.io/zh-cn/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Gitea&lt;/a&gt;，gitea是从Gogs源码的基础上开发的，听说使用起来也很不错，而且维护更新也更频繁，于是我就选择了&lt;a href=&quot;https://gitea.io/zh-cn/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Gitea&lt;/a&gt;&lt;br&gt;官方也是很有趣，官网上写着 「Git with a cup of tea」，这大概也是gitea名字的含义吧。&lt;/p&gt;&lt;blockquote class=&quot;blockquote-center&quot;&gt;&lt;p&gt;Gitea 是一个开源社区驱动的轻量级代码托管解决方案，后端采用 Go 编写，采用 MIT 许可证&lt;/p&gt;&lt;/blockquote&gt;
    
    </summary>
    
    
      <category term="git" scheme="https://blog8.flyky.org/tags/git/"/>
    
      <category term="gitea" scheme="https://blog8.flyky.org/tags/gitea/"/>
    
  </entry>
  
  <entry>
    <title>Certbot签发泛域名SSL证书（通过DNS TXT记录来验证域名有效性）</title>
    <link href="https://blog8.flyky.org/20191108/certbot-DNS-TXT-check/"/>
    <id>https://blog8.flyky.org/20191108/certbot-DNS-TXT-check/</id>
    <published>2019-11-08T11:51:51.000Z</published>
    <updated>2021-01-26T09:06:13.105Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --><p>我们在使用<a href="https://letsencrypt.org/" target="_blank" rel="noopener"><code>let&#39;s encrypt</code></a>获取免费的HTTPS证书的时候，<a href="https://letsencrypt.org/" target="_blank" rel="noopener"><code>let&#39;s encrypt</code></a>需要对域名进行验证，以确保域名是你自己的<br>之前用默认的文件验证方式总有奇怪的问题导致失败，我也是很无奈，于是改用验证DNS-TXT记录的方式来验证，而且貌似如果申请泛域名证书也只能通过这个方式验证</p><blockquote><p>本来呢我只打算在这篇记一下验证DNS记录的方式签发证书，不过以前也没写过如何用<a href="https://certbot.eff.org/" target="_blank" rel="noopener"><code>certbot</code></a>签发免费Let’s Encrypt SSL证书诶，那正好就重头把过程写一遍。</p></blockquote><a id="more"></a><h1 id="安装Certbot"><a href="#安装Certbot" class="headerlink" title="安装Certbot"></a>安装Certbot</h1><h2 id="根据官网提示步骤安装"><a href="#根据官网提示步骤安装" class="headerlink" title="根据官网提示步骤安装"></a>根据官网提示步骤安装</h2><p>先去<a href="https://certbot.eff.org/" target="_blank" rel="noopener">Certbot 官网</a>，在网页上选择使用的服务器软件和系统版本，会跳转到安装的文档，<br>根据提示的步骤安装即可<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/certbot%E5%AE%98%E7%BD%91%E6%88%AA%E5%9B%BE.webp" alt="certbot官网截图"></p><h2 id="使用自动安装脚本安装"><a href="#使用自动安装脚本安装" class="headerlink" title="使用自动安装脚本安装"></a>使用自动安装脚本安装</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">wget https://dl.eff.org/certbot-auto</span><br><span class="line">chmod a+x certbot-auto <span class="comment"># 给脚本执行权限</span></span><br></pre></td></tr></table></figure><p>接下来直接使用该脚本进行签发证书等操作即可<br>第一次使用该脚本时会自动安装依赖。</p><div class="note danger"><p>官网提示的通过软件包管理安装的certbot，之后是可以直接使用certbot命令进行操作的<br>我接下来的描述中，执行命令默认是直接用<code>certbot</code>命令<br><strong>如果你是用自动安装脚本certbot-auto的话，直接用这个脚本进行操作，我下面描述的命令里的<code>certbot</code>换成<code>./certbot-auto</code></strong></p></div><h1 id="获取签发证书（standalone）"><a href="#获取签发证书（standalone）" class="headerlink" title="获取签发证书（standalone）"></a>获取签发证书（standalone）</h1><p>直接使用<code>certbot certonly</code>命令即可开始签发，根据提示，先选择模式，一般选择<code>standalone</code>（使用standalone需要先停止nginx等服务器运行），然后根据提示列出需签的域名，之后会开始验证，通过之后会将生成的证书文件保存。</p><h1 id="获取泛域名签发证书（manual，通过DNS-TXT记录来验证域名有效性）"><a href="#获取泛域名签发证书（manual，通过DNS-TXT记录来验证域名有效性）" class="headerlink" title="获取泛域名签发证书（manual，通过DNS-TXT记录来验证域名有效性）"></a>获取泛域名签发证书（manual，通过DNS-TXT记录来验证域名有效性）</h1><span class="label info">标题上线啦</span>，这篇主要还是来讲这个验证问题的，*感觉用这种方式签发更稳当一点*。<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">certbot certonly  --preferred-challenges dns -d <span class="string">"*.example.com"</span> -d example.com --manual</span><br></pre></td></tr></table></figure><p>用这个命令来手动验证DNS签发<br>这里我用<code>example.com</code>来假设要签的域名，<code>-d</code>后面跟着一个域名，如果有多个域名要签的话记得每一个单独的域名前都要写<code>-d</code>。<br>我指定了两个-d参数，因为certbot的泛域名其实只支持诸如<code>*.example.com</code>，如要直接使用example.com，就得为其单独也签发一条。</p><p>回车执行之后，会开始提示你给你的域名添加TXT解析记录。如下图：<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/certbot2.webp" alt="certbot2"><br>这里是提示你为域名添加一个<code>_acme-challenge</code>的TXT记录，记录值为生成的一串字符（图中红框）。<br>这个只需要你去DNS服务商那里添加即可，<span class="label warning">这里如果你 -d 了几条不同的二级域名，那每个二级域名都要添加记录；在你添加完一个域名的记录值，在控制台回车之后会提示你下一个域名的记录值</span><br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/%E6%B7%BB%E5%8A%A0TXT%E8%A7%A3%E6%9E%90%E8%AE%B0%E5%BD%95.webp" alt="添加TXT解析记录"></p><p>在你添加完记录保存之后，最好要<strong>检查一下解析记录</strong>。<br>在其他终端输入下面命令（示例example.com，记得修改）：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">nslookup -<span class="built_in">type</span>=txt _acme-challenge.example.com 8.8.8.8</span><br><span class="line"><span class="comment"># 或者</span></span><br><span class="line">dig -t txt _acme-challenge.example.com</span><br></pre></td></tr></table></figure><p>如果包含你所添加的记录值，那么说明添加成功<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/%E6%A3%80%E6%9F%A5%E8%AE%B0%E5%BD%95%E6%98%AF%E5%90%A6%E6%B7%BB%E5%8A%A0.webp" alt="检查记录是否添加"></p><p>那现在就可以控制台继续回车，不会意外就会把签发的证书文件保存，控制台打印出来证书文件的存放位置，一般情况下是会保存在<code>/etc/letsencrypt/live/example.com</code>目录下<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/%E6%88%90%E5%8A%9F%E7%AD%BE%E5%8F%91.webp" alt="成功签发"></p><p>这个目录下一般会有四个文件：</p><table><thead><tr><th align="left">文件</th><th align="center">描述</th></tr></thead><tbody><tr><td align="left">cert.pem</td><td align="center">服务器证书</td></tr><tr><td align="left">chain.pem</td><td align="center">包含Web浏览器为验证服务器而需要的证书或附加中间证书</td></tr><tr><td align="left">fullchain.pem</td><td align="center">cert.pem+chain.pem</td></tr><tr><td align="left">privkey.pem</td><td align="center">证书的私钥</td></tr></tbody></table><p>我们一般用<code>fullchain.pem</code>和<code>privkey.pem</code>就可以了</p><h1 id="在Nginx配置使用证书"><a href="#在Nginx配置使用证书" class="headerlink" title="在Nginx配置使用证书"></a>在Nginx配置使用证书</h1><p>这里我就不展开说了，监听的443端口设置<code>ssl_certificate</code>和<code>ssl_certificate_key</code>基本上就可以了<br>我这里贴上我自己的一段示例</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">server</span> &#123;</span><br><span class="line">    <span class="attribute">listen</span>  <span class="number">443</span> ssl;</span><br><span class="line">    <span class="attribute">server_name</span> example.com;</span><br><span class="line"></span><br><span class="line">    <span class="attribute">ssl_certificate</span> /etc/letsencrypt/live/example.com/fullchain.pem;</span><br><span class="line">    <span class="attribute">ssl_certificate_key</span> /etc/letsencrypt/live/example.com/privkey.pem;</span><br><span class="line">    <span class="attribute">ssl_session_timeout</span> <span class="number">10m</span>;</span><br><span class="line">    <span class="attribute">ssl_protocols</span> TLSv1 TLSv1.<span class="number">1</span> TLSv1.<span class="number">2</span>;</span><br><span class="line">    <span class="attribute">ssl_ciphers</span> ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;</span><br><span class="line">    <span class="attribute">ssl_prefer_server_ciphers</span> <span class="literal">on</span>;</span><br><span class="line"></span><br><span class="line">    <span class="attribute">location</span> / &#123;</span><br><span class="line">        <span class="comment"># 你自己配置;</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="证书续期与注销"><a href="#证书续期与注销" class="headerlink" title="证书续期与注销"></a>证书续期与注销</h1><h2 id="续期"><a href="#续期" class="headerlink" title="续期"></a>续期</h2><p>免费的<a href="https://letsencrypt.org/" target="_blank" rel="noopener"><code>let&#39;s encrypt</code></a>有3个月的时间，到期前需要续期<br>第一次使用certbot签时如果输入了邮箱地址，证书快到期前是会发邮件提醒你的<br>使用下面的命令续期</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">certbot renew --dry-run</span><br></pre></td></tr></table></figure><h2 id="设置自动续期"><a href="#设置自动续期" class="headerlink" title="设置自动续期"></a>设置自动续期</h2><p>设置自动续期的话，只需要写脚本放在Cron中定时运行即可，<code>crontab -e</code>打开crontab脚本，添加如下的脚本</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">0 3 */7 * * /bin/certbot renew --renew-hook <span class="string">"/where/your/nginx -s reload"</span> </span><br></pre></td></tr></table></figure><p>这个脚本表示<span class="label primary">每隔 7 天，夜里 3 点整自动执行检查续期命令一次。续期完成后，重启 nginx 服务</span><br>添加完后重启cron服务即可<code>sudo service crond restart</code></p><h2 id="泛域名通过DNS-TXT记录-自动-续期"><a href="#泛域名通过DNS-TXT记录-自动-续期" class="headerlink" title="泛域名通过DNS-TXT记录(自动)续期"></a>泛域名通过DNS-TXT记录(自动)续期</h2><p>这个就稍微麻烦一点，我们需要使用到DNS服务商提供的API，在renew证书时可以自动添加更新TXT记录来实现自动更新，当然一般还需要DNS服务商给用户提供的API密钥确保安全等<br>我先列出一些DNS插件的地址，具体的可以去查看插件安装使用方法，当然其他第三方的DNS插件也可以在github里找找</p><ul><li><a href="https://github.com/certbot/certbot" target="_blank" rel="noopener">certbot提供的DNS插件列表</a></li><li><a href="https://github.com/tengattack/certbot-dns-aliyun" target="_blank" rel="noopener">阿里云DNS插件</a></li><li><a href="https://github.com/al-one/certbot-auth-dnspod" target="_blank" rel="noopener">dnspod插件（腾讯云）</a></li></ul><hr><p>我这里使用的是DNSPOD，于是我也就只描述以下使用dnspod插件的情况</p><ol><li>下载<a href="https://github.com/al-one/certbot-auth-dnspod" target="_blank" rel="noopener">certbot-auth-dnspod</a>脚本<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">wget https://raw.githubusercontent.com/al-one/certbot-auth-dnspod/master/certbot-auth-dnspod.sh</span><br><span class="line">   chmod +x certbot-auth-dnspod.sh</span><br></pre></td></tr></table></figure></li><li>获取用户DNSPOD token<br>登录dnspod后，在控制台的<a href="https://www.dnspod.cn/console/user/security" target="_blank" rel="noopener">用户中心 -&gt; 安全设置</a>下找到「API Token」，开启并创建token后，复制下id和token</li><li>配置token信息<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">echo</span> <span class="string">"id,token"</span> &gt; /etc/dnspod_token</span><br></pre></td></tr></table></figure>把`id`和`token`换成刚刚复制下来的真实内容 接下来就可以**使用插件进行续期**了<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">certbot renew --manual --preferred-challenges dns --manual-auth-hook /path/to/certbot-auth-dnspod.sh --force-renewal</span><br></pre></td></tr></table></figure></li></ol><p>如果要<strong>自动续期</strong>，就可以将下面的代码加入crontab中再重启cron服务，具体的过程<a href="#设置自动续期">上面</a>说过了，这里也不再赘述</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">29 3 1 * * root /bin/certbot renew --manual --preferred-challenges dns  --manual-auth-hook /path/to/certbot-auth-dnspod.sh --force-renewal --post-hook <span class="string">"/where/your/nginx -s reload"</span>  </span><br></pre></td></tr></table></figure><p>这是每个月1号3点29分执行一次强制证书更新后重启nginx</p><p><em>当然用插件进行申请证书自动DNS验证也是可以的</em></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">certbot certonly --manual --preferred-challenges dns-01 --email mail@domain.com -d laravel.run -d *.example.com --server https://acme-v02.api.letsencrypt.org/directory --manual-auth-hook /path/to/certbot-auth-dnspod.sh </span><br></pre></td></tr></table></figure><h2 id="注销"><a href="#注销" class="headerlink" title="注销"></a>注销</h2><p>使用下面的命令可以查看已生成的证书信息，包括证书名称，包含的域名，到期时间以及证书文件路径</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">certbot certificates</span><br></pre></td></tr></table></figure><p><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/certbot_certificates.webp" alt="certbot_certificates"></p><p>找到你要注销的证书，复制下证书文件的路径，然后使用下面的命令注销</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">certbot revoke --cert-path   /etc/letsencrypt/live/example.com/fullchain.pem</span><br></pre></td></tr></table></figure><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --&gt;&lt;p&gt;我们在使用&lt;a href=&quot;https://letsencrypt.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;let&amp;#39;s encrypt&lt;/code&gt;&lt;/a&gt;获取免费的HTTPS证书的时候，&lt;a href=&quot;https://letsencrypt.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;let&amp;#39;s encrypt&lt;/code&gt;&lt;/a&gt;需要对域名进行验证，以确保域名是你自己的&lt;br&gt;之前用默认的文件验证方式总有奇怪的问题导致失败，我也是很无奈，于是改用验证DNS-TXT记录的方式来验证，而且貌似如果申请泛域名证书也只能通过这个方式验证&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;本来呢我只打算在这篇记一下验证DNS记录的方式签发证书，不过以前也没写过如何用&lt;a href=&quot;https://certbot.eff.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;certbot&lt;/code&gt;&lt;/a&gt;签发免费Let’s Encrypt SSL证书诶，那正好就重头把过程写一遍。&lt;/p&gt;&lt;/blockquote&gt;
    
    </summary>
    
      <category term="Tech" scheme="https://blog8.flyky.org/categories/Tech/"/>
    
    
      <category term="Let&#39;s Encrypt" scheme="https://blog8.flyky.org/tags/Let-s-Encrypt/"/>
    
      <category term="SSL证书" scheme="https://blog8.flyky.org/tags/SSL%E8%AF%81%E4%B9%A6/"/>
    
      <category term="certbot" scheme="https://blog8.flyky.org/tags/certbot/"/>
    
      <category term="https" scheme="https://blog8.flyky.org/tags/https/"/>
    
  </entry>
  
  <entry>
    <title>初探腾讯云对象存储服务</title>
    <link href="https://blog8.flyky.org/20191106/TencentCOS-First-Exploration/"/>
    <id>https://blog8.flyky.org/20191106/TencentCOS-First-Exploration/</id>
    <published>2019-11-06T10:48:11.000Z</published>
    <updated>2021-01-26T09:06:13.104Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --><p>之前一直不太了解『对象存储是个什么玩意儿』。只是在腾讯云阿里云都见到过，但是不清楚也不太想了解</p><p>今天突然想了解它的契机是<code>图床</code>来着。<br>在我配置压缩博文的过程中，需要把图片资源压缩，我选择了<code>webp</code>。正当我要把webp文件传到图床的时候，却发现常用的图床都不支持<code>webp</code>。 于是突然爱折腾的我想着『自建图床』，这才去百度上一搜，发现很多推荐『七牛云』的『对象存储』服务。这我就突然想起来了，腾讯云阿里云不也有这玩意嘛，于是我就想到用我现在常用的「腾讯云」来弄。</p><blockquote class="blockquote-center"><p>对象存储可以简单理解为用来存储图片、音频、视频等非结构化数据的数据池。相对于主机服务器,具有读写速度快,利于分享的特点。</p></blockquote><p><em>就像个云盘一样</em></p><a id="more"></a><h1 id="创建腾讯云对象存储服务COS（Cloud-Object-Storage）"><a href="#创建腾讯云对象存储服务COS（Cloud-Object-Storage）" class="headerlink" title="创建腾讯云对象存储服务COS（Cloud Object Storage）"></a>创建腾讯云对象存储服务COS（Cloud Object Storage）</h1><p>打开腾讯云官网，登陆后来到控制台，激活COS服务，然后再概览中就会看到提示『创建存储桶 』<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/tencent_obj_sto_1.webp" alt="tencent_obj_sto_1"></p><p><em>存储桶（bucket），顾名思义，我们将把要存储的对象文件存储在这个桶里</em><br>点击「创建存储桶」，名称随意，地域随意<br>访问权限选择「公有读私有写」，然后就可以点「确定」<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/%E5%88%9B%E5%BB%BA%E5%AD%98%E5%82%A8%E6%A1%B6.webp" alt="创建存储桶"></p><p>在控制台左侧栏里除了「存储桶列表」还有「资源包管理」，点进去可以看到当前有效的资源包以及购买资源<br>这里的<em>资源包<em>主要包含</em>容量资源包<em>以及</em>流量资源包*，因为容量和流量是计费的项目，详细的可以去看腾讯云的<a href="https://buy.cloud.tencent.com/price/cos/overview#E68C89E9878FE8AEA1E8B4B9E5AE9AE4BBB7" target="_blank" rel="noopener">计费定价</a><br>买了对应存储桶的所在地区对应的资源包，就可以直接抵用该桶的消费<br>*当然目前这个时间点腾讯云是赠送新手一定量的容量资源包的，还有1元新手容量包</em></p><h1 id="COS存储桶的使用"><a href="#COS存储桶的使用" class="headerlink" title="COS存储桶的使用"></a>COS存储桶的使用</h1><h2 id="存储桶控制台-上传文件等"><a href="#存储桶控制台-上传文件等" class="headerlink" title="存储桶控制台 / 上传文件等"></a>存储桶控制台 / 上传文件等</h2><p>点进刚刚创建好的存储桶，在「文件列表」里可以看到上传在该桶之中的文件(夹)<br>在这里可以直观的在桶里进行上传文件，创建文件夹等操作<br>那我这里专门创建了一个文件夹，用于存储博客用到的图片资源，给博客提供图床外链<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/%E5%AF%B9%E8%B1%A1%E5%AD%98%E5%82%A8%E6%8E%A7%E5%88%B6%E5%8F%B0.webp" alt="对象存储控制台"></p><h2 id="获取外链"><a href="#获取外链" class="headerlink" title="获取外链"></a>获取外链</h2><p>将你想要分享的文件上传到桶里之后，在该文件的右边点详细信息，可以看到该文件对象的基本信息，包含名称，大小，时间，下载文件对象等,<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/%E5%AF%B9%E8%B1%A1%E5%9F%BA%E6%9C%AC%E4%BF%A1%E6%81%AF-%E8%8E%B7%E5%8F%96%E5%A4%96%E9%93%BE.webp" alt="对象基本信息-获取外链"><br>倒数第二项是「对象地址」，这个便是该文件的外链了，点击复制按钮，贴在博客里，便可以实现它的图床功能啦</p><p>当然不仅仅是图片，音乐视频都可以上传在桶里，外链贴在博客等需要他的地方，相当容易</p><blockquote><p>你可能注意到了最后一项的「临时链接」，这个是由于外链可能有一些权限限制访问，或者是向下面提到的<a href="#防盗链设置">「防盗链」</a>设置后，我们就不能直接通过外链访问这个文件对象了<br>临时链接带有签名参数，但有时间限制，可以用该链接暂时直接访问，但是<strong>这个链接不要用在博客等</strong>做外链，外链还是得用上面的对象地址。</p></blockquote><h2 id="COSBrowser客户端操作腾讯对象存储（推荐）"><a href="#COSBrowser客户端操作腾讯对象存储（推荐）" class="headerlink" title="COSBrowser客户端操作腾讯对象存储（推荐）"></a>COSBrowser客户端操作腾讯对象存储（推荐）</h2><p>腾讯云官方为我们提供了COS客户端，Windows/Mac/Linux/iOS/Android主流系统都有，十分方便<br><em>这下对象存储真的可以当云盘用了（笑:-D</em><br>拉开控制台最左侧栏里可以看到「工具」- &gt; 「客户端下载」，下载对应的客户端使用即可<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/COS%E5%AE%A2%E6%88%B7%E7%AB%AF.webp" alt="COS客户端"></p><p>那我这里就不具体描述客户端的使用了，就放一下客户端的界面图，是我使用的Linux和Android端<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/COSBrowser-Android.webp" alt="COSBrowser-Android"> <img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/COSBrowser-Linux.webp" alt="COSBrowser-Linux"></p><h1 id="防盗链设置"><a href="#防盗链设置" class="headerlink" title="防盗链设置"></a>防盗链设置</h1><p><strong>防盗链设置还是挺重要的，如果被盗链会导致你的流量费用可能会跑的极快呢</strong><br>在存储桶的基础配置里可以找到「防盗链设置」，在该项里设置即可<br>下图是我的设置，以白名单类型为例，在<code>Referer</code>里添加可以访问的域名或地址即可<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/%E9%98%B2%E7%9B%97%E9%93%BE.webp" alt="防盗链"></p><p>保存设置之后，只有白名单里的域名地址才可以访问外链了。<br>即使其他人获取到链接也无法访问相应图片<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/%E6%97%A0%E6%B3%95%E8%AE%BF%E9%97%AE.webp" alt="无法访问"></p><h1 id="自定义源站域名访问外链"><a href="#自定义源站域名访问外链" class="headerlink" title="自定义源站域名访问外链"></a>自定义源站域名访问外链</h1><p>默认的访问域名是腾讯云分配的公共域名，使用起来没有任何问题，就是太长了。。所以这里我们可以用自己的域名绑定到对应的存储桶里去生成访问外链。<br>这样做的另一个好处是，假设换了一个存储桶，我们可以通过接口将原桶文件转移过去，但是用了新桶的默认访问域名，这样会导致原本访问文件的链接不同，你写在博客里的外链会失效，然而如果用自定义访问域名，只需要换绑域名到新桶即可，只要桶内的文件目录没有变化，文件生成的外链也就不会变了。</p><h2 id="设置存储桶自定义访问域名"><a href="#设置存储桶自定义访问域名" class="headerlink" title="设置存储桶自定义访问域名"></a>设置存储桶自定义访问域名</h2><p>在控制台点进需要设置的存储桶，可以看到「域名设置」，在里面可以看到「自定义源站域名」这一项<br>点击添加域名，填写内容即可。这里「源站类型」选择「默认源站」，然后将CNAME项的值复制下来，下一步解析域名需要使用<br><em>另外根据要求，自定义的域名必须经过备案</em><br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/%E8%87%AA%E5%AE%9A%E4%B9%89%E6%BA%90%E7%AB%99%E5%9F%9F%E5%90%8D.webp" alt="自定义源站域名"></p><h2 id="添加域名解析记录"><a href="#添加域名解析记录" class="headerlink" title="添加域名解析记录"></a>添加域名解析记录</h2><p>DNS服务商处设置好对应的CNAME记录即可，下图示例<br>记录值填写上一步复制下来的CNAME项的值<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/%E6%B7%BB%E5%8A%A0%E8%A7%A3%E6%9E%90%E8%AE%B0%E5%BD%95.webp" alt="添加解析记录"><br>等待生效即可</p><h2 id="获取对象文件自定义域名访问外链"><a href="#获取对象文件自定义域名访问外链" class="headerlink" title="获取对象文件自定义域名访问外链"></a>获取对象文件自定义域名访问外链</h2><p>这一步和之前获取外链是一样的<br>在文件的基本信息里，将「指定域名」选择成「自定义源站域名」再选择刚刚新建的域名，这样在下面的对象地址就会生成自定义的域名外链了<br>当然其实你只需要把获取到的默认域名的对象地址里的域名改成你自定义的域名即可。<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/%E8%87%AA%E5%AE%9A%E4%B9%89%E6%BA%90%E7%AB%99%E5%9F%9F%E5%90%8D%E8%AE%BF%E9%97%AE%E5%A4%96%E9%93%BE.webp" alt="自定义源站域名访问外链"></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --&gt;&lt;p&gt;之前一直不太了解『对象存储是个什么玩意儿』。只是在腾讯云阿里云都见到过，但是不清楚也不太想了解&lt;/p&gt;&lt;p&gt;今天突然想了解它的契机是&lt;code&gt;图床&lt;/code&gt;来着。&lt;br&gt;在我配置压缩博文的过程中，需要把图片资源压缩，我选择了&lt;code&gt;webp&lt;/code&gt;。正当我要把webp文件传到图床的时候，却发现常用的图床都不支持&lt;code&gt;webp&lt;/code&gt;。 于是突然爱折腾的我想着『自建图床』，这才去百度上一搜，发现很多推荐『七牛云』的『对象存储』服务。这我就突然想起来了，腾讯云阿里云不也有这玩意嘛，于是我就想到用我现在常用的「腾讯云」来弄。&lt;/p&gt;&lt;blockquote class=&quot;blockquote-center&quot;&gt;&lt;p&gt;对象存储可以简单理解为用来存储图片、音频、视频等非结构化数据的数据池。相对于主机服务器,具有读写速度快,利于分享的特点。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;em&gt;就像个云盘一样&lt;/em&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="Tech" scheme="https://blog8.flyky.org/categories/Tech/"/>
    
    
      <category term="对象存储服务" scheme="https://blog8.flyky.org/tags/%E5%AF%B9%E8%B1%A1%E5%AD%98%E5%82%A8%E6%9C%8D%E5%8A%A1/"/>
    
      <category term="COS" scheme="https://blog8.flyky.org/tags/COS/"/>
    
      <category term="图床" scheme="https://blog8.flyky.org/tags/%E5%9B%BE%E5%BA%8A/"/>
    
      <category term="腾讯云" scheme="https://blog8.flyky.org/tags/%E8%85%BE%E8%AE%AF%E4%BA%91/"/>
    
  </entry>
  
  <entry>
    <title>自建git服务实现hexo博客部署</title>
    <link href="https://blog8.flyky.org/20191105/build-git-server-to-use-hexo-deploy/"/>
    <id>https://blog8.flyky.org/20191105/build-git-server-to-use-hexo-deploy/</id>
    <published>2019-11-05T05:45:01.000Z</published>
    <updated>2021-01-26T09:06:13.104Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --><p>一直以来我的hexo博客都是用自带的server跑，然后nginx反代，说白了<code>hexo s</code>只是用于生产环境下使用的，我却一只用于部署。没用到hexo生成静态页面和部署，有点遗憾也有不少的弊端。<br>但是hexo deploy大多数人是部署到github上，我并不想用github的域名，也不想部署到github上再把自己的域名解析CNAME到上面，因为国内github的访问时不时就有问题，而且这样有一种“寄人篱下”的感觉，很不爽。<br>于是就得自建git服务再部署了。<br>所幸过程也并不繁琐，简单来说也就下面几步：</p><ol><li>先建立git服务，配置好远程仓库</li><li>在hexo配置中设置push到远程仓库</li><li>设置git hook，钩子把静态资源拷贝到自定义网站目录</li><li>nginx配置web server<br>剩下的就用hexo原生的生成静态文件，上传部署，两步走即可</li></ol><p><strong>下面讲讲详细过程</strong></p><a id="more"></a><h1 id="在服务器上搭建git服务并配置"><a href="#在服务器上搭建git服务并配置" class="headerlink" title="在服务器上搭建git服务并配置"></a>在服务器上搭建git服务并配置</h1><blockquote><p>当然首先服务器上得装好git，用软件包管理安装即可，不多赘述</p></blockquote><h2 id="创建git用户"><a href="#创建git用户" class="headerlink" title="创建git用户"></a>创建git用户</h2><p>这里我们创建一个git用户，用来运行git服务</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo adduser git</span><br></pre></td></tr></table></figure><h2 id="设置免密登录（ssh密钥对）"><a href="#设置免密登录（ssh密钥对）" class="headerlink" title="设置免密登录（ssh密钥对）"></a>设置免密登录（ssh密钥对）</h2><p>由于你的本地Git仓库和Git仓库之间的传输是通过SSH加密的，所以之后本机hexo部署上传需要设置密钥登录<br>首先在本地机生成密钥对<code>ssh-keygen -t rsa</code></p><div class="note info"><p>这里详细的关于密钥对的设置和介绍我曾经在hadoop的那篇博文里提过了<br>不了解ssh的可以去看一下 <a href="../../20170928/notes_of_big_data_study-Hadoop-Fdistributed-build/#生成公私钥并配置免密登录">点击这里跳转</a></p></div><p><strong>收集所有需要登录的用户的公钥，就是他们自己的<code>id_rsa.pub</code>文件，把所有公钥内容导入到<code>/home/git/.ssh/authorized_keys</code>文件里，一行一个。</strong><br>这里我们就直接把本地的<code>~/.ssh/id_rsa.pub</code>内容直接复制添加到服务器的<code>/home/git/.ssh/authorized_keys</code>文件即可。</p><p>之后本机尝试免密登录服务器git用户<code>ssh git@server.ip</code>，如果可以表示之前的设置无误。<br>那现在我们为了安全起见就可以<strong>禁用git用户登录shell了</strong><br>编辑服务器<code>/etc/passwd</code>文件，找到类似下面的这行<br><code>git:x:1001:1001:,,,:/home/git:/bin/bash</code><br>将其改为<br><code>git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell</code><br>即可。这样，git用户可以正常通过ssh使用git，但无法登录shell。</p><div class="note warning"><p>这里测试时如果无法免密登录，有很大的原因是因为服务器git用户目录的.ssh目录权限和里面文件权限问题 这里通过chmod命令将.ssh目录权限设置成700，里面的文件权限为600，并且owner为git<br>这个在<a href="../../20170928/notes_of_big_data_study-Hadoop-Fdistributed-build/#生成公私钥并配置免密登录">之前的hadoop博文</a>里也是提到了，可以去了解</p></div><h2 id="初始化远程Git仓库"><a href="#初始化远程Git仓库" class="headerlink" title="初始化远程Git仓库"></a>初始化远程Git仓库</h2><p>首先自定义git仓库位置，假定是<code>/home/git/blog.git</code>，在<code>/home/git</code>目录下输入命令</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo git init --bare blog.git</span><br></pre></td></tr></table></figure><p>Git就会创建一个裸仓库</p><p>然后我们把该目录的owner改为git</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo chown -R git:git blog.git</span><br></pre></td></tr></table></figure><p>现在我们在本地随便什么地方，试试clone这个裸仓库，如果没问题即可</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> git@server.ip:~/blog.git </span><br></pre></td></tr></table></figure><h1 id="设置git-hook（钩子）"><a href="#设置git-hook（钩子）" class="headerlink" title="设置git hook（钩子）"></a>设置git hook（钩子）</h1><p>首先cd到远程仓库的hooks目录下，<code>cd /home/git/blog.git/hooks</code><br>之后创建并编写<code>post-receive</code>文件，<code>vim post-receive</code></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#!/bin/bash -l</span></span><br><span class="line">GIT_REPO=/home/git/blog.git</span><br><span class="line">TMP_GIT_CLONE=/home/git/tmp/blog</span><br><span class="line">PUBLIC_WWW=/home/git/project/blog</span><br><span class="line">rm -rf <span class="variable">$&#123;TMP_GIT_CLONE&#125;</span></span><br><span class="line">git <span class="built_in">clone</span> <span class="variable">$GIT_REPO</span> <span class="variable">$TMP_GIT_CLONE</span></span><br><span class="line">rm -rf <span class="variable">$&#123;PUBLIC_WWW&#125;</span></span><br><span class="line">cp -rf <span class="variable">$&#123;TMP_GIT_CLONE&#125;</span> <span class="variable">$&#123;PUBLIC_WWW&#125;</span></span><br></pre></td></tr></table></figure><p>其中public_www就是用于最终存放nginx映射的静态资源文件目录<br><strong>* 通过此脚本，每次仓库接收到新上传的内容时都会自动拷贝资源到该目录下 *</strong></p><blockquote><p>这里的<code>tmp</code>目录可能要自己新建，<code>mkdir /home/git/tmp</code>即可。</p></blockquote><p>然后记得更改脚本和各个目录的权限</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">chmod +x /home/git/blog.git/hooks/post-receive</span><br><span class="line">chmod 777 -R /home/git/blog.git</span><br><span class="line">chmod 777 -R /home/git/project</span><br><span class="line">chmod 777 -R /home/git/tmp</span><br><span class="line"></span><br><span class="line">chown -R git:git /home/git/</span><br></pre></td></tr></table></figure><h1 id="在hexo配置中设置push到远程仓库"><a href="#在hexo配置中设置push到远程仓库" class="headerlink" title="在hexo配置中设置push到远程仓库"></a>在hexo配置中设置push到远程仓库</h1><p>修改hexo工程的<code>_config.yml</code>文件，在<code>deploy</code>项中填写：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">deploy:</span></span><br><span class="line">    <span class="attr">type:</span> <span class="string">git</span></span><br><span class="line">    <span class="attr">message:</span> <span class="string">update</span></span><br><span class="line">    <span class="attr">repo:</span> <span class="string">git@server.ip:~/blog.git</span></span><br><span class="line"><span class="attr">    branch:</span> <span class="string">master</span></span><br></pre></td></tr></table></figure><h1 id="Nginx-配置"><a href="#Nginx-配置" class="headerlink" title="Nginx 配置"></a>Nginx 配置</h1><p><strong>这一步熟悉Nginx的小伙伴应该可以自己写</strong>，我这里就贴一个样例，目录啥的都是上面提到的</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">server</span> &#123;</span><br><span class="line">    <span class="attribute">listen</span>  <span class="number">80</span>;</span><br><span class="line">    <span class="attribute">server_name</span> your.server.name;</span><br><span class="line">    <span class="attribute">location</span> / &#123;</span><br><span class="line">        <span class="attribute">root</span>    /home/git/project/blog;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>这种最简单的就可以了</p><p><em>当然如果你是像我这样用http的话就得稍微改一改，还得把80重定向到443<br>这种设置如果你用到了不会的话就自行百度吧～</em></p><h1 id="本地测试hexo博客后上传部署"><a href="#本地测试hexo博客后上传部署" class="headerlink" title="本地测试hexo博客后上传部署"></a>本地测试hexo博客后上传部署</h1><p>这就是最后啦，每次写完博文或者修改之后，先在本地工程目录下跑一下服务</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo s -p 端口号</span><br></pre></td></tr></table></figure><p>然后打开浏览器查看测试的博客页面</p><p>没有问题的话就可以生成静态资源了，当然先清除掉<code>public</code>目录下已有的静态资源文件</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">hexo clean</span><br><span class="line">hexo g</span><br></pre></td></tr></table></figure><p>这之后你可以使用这个命令测试</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo s -s -p 端口号</span><br></pre></td></tr></table></figure><p>多加一个<code>-s</code>表示只用静态资源跑服务器测试，测试一下静态资源的生成，同样打开浏览器查看网站</p><p>现在确认无误之后就要<strong>把静态资源上传部署到服务器</strong>了</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo d</span><br></pre></td></tr></table></figure><p>不报错的话说明没有问题啦，大功告成</p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --&gt;&lt;p&gt;一直以来我的hexo博客都是用自带的server跑，然后nginx反代，说白了&lt;code&gt;hexo s&lt;/code&gt;只是用于生产环境下使用的，我却一只用于部署。没用到hexo生成静态页面和部署，有点遗憾也有不少的弊端。&lt;br&gt;但是hexo deploy大多数人是部署到github上，我并不想用github的域名，也不想部署到github上再把自己的域名解析CNAME到上面，因为国内github的访问时不时就有问题，而且这样有一种“寄人篱下”的感觉，很不爽。&lt;br&gt;于是就得自建git服务再部署了。&lt;br&gt;所幸过程也并不繁琐，简单来说也就下面几步：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;先建立git服务，配置好远程仓库&lt;/li&gt;&lt;li&gt;在hexo配置中设置push到远程仓库&lt;/li&gt;&lt;li&gt;设置git hook，钩子把静态资源拷贝到自定义网站目录&lt;/li&gt;&lt;li&gt;nginx配置web server&lt;br&gt;剩下的就用hexo原生的生成静态文件，上传部署，两步走即可&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;下面讲讲详细过程&lt;/strong&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="Tech" scheme="https://blog8.flyky.org/categories/Tech/"/>
    
      <category term="hexo" scheme="https://blog8.flyky.org/categories/Tech/hexo/"/>
    
    
      <category term="git" scheme="https://blog8.flyky.org/tags/git/"/>
    
      <category term="hexo" scheme="https://blog8.flyky.org/tags/hexo/"/>
    
  </entry>
  
  <entry>
    <title>ubuntu 18.04 (Gnome桌面)等的个人美化过程记录</title>
    <link href="https://blog8.flyky.org/20191104/recording_for_beautify_ubuntu-18-04-Gnome/"/>
    <id>https://blog8.flyky.org/20191104/recording_for_beautify_ubuntu-18-04-Gnome/</id>
    <published>2019-11-04T08:04:00.000Z</published>
    <updated>2021-01-26T09:06:13.107Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --><p>今天才把物理机上的Ubuntu升到了18.04，原因有很大一部分是因为不想去鼓捣桌面界面之类的，毕竟<strong><em>Ubuntu从18.04开始，桌面程序放弃了unity而回归了Gnome</em></strong>～～美化是一定要美化的，毕竟这是自己电脑里用作图形桌面的，又不是要做server，要看的东西当然要赏心悦目啦。</p><h1 id="写在前面"><a href="#写在前面" class="headerlink" title="写在前面"></a>写在前面</h1><p>首先先看看美化后的桌面效果，这里用的是仿Mac的Mojave-dark主题<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/front1.webp" alt="front1"></p><a id="more"></a><p>由于ubuntu回归Gnome桌面，以下的美化过程也是针对Gnome3的，所以<strong>大部分的美化过程可以套用在其他系统的Gnome桌面上</strong>，可能主题解压安装的目录会有些不同。<br>嘛，安装自己慢慢鼓捣就好，上网搜一搜，毕竟用的都是别人写的设计的主题。</p><h1 id="美化资源下载网站等介绍"><a href="#美化资源下载网站等介绍" class="headerlink" title="美化资源下载网站等介绍"></a>美化资源下载网站等介绍</h1><h2 id="资源网站介绍"><a href="#资源网站介绍" class="headerlink" title="资源网站介绍"></a>资源网站介绍</h2><p><a href="https://www.gnome-look.org/" target="_blank" rel="noopener">Gnome的外观主题等资源网站： https://www.gnome-look.org/</a><br>这个网站里包含了Gnome桌面的各种外观资源，网站左侧分类栏里可以看到如GTK3、GTK2的系统主题，图标icon主题，grub主题，Plymouth开机画面主题、GDM (GNOME Display Manager,用户登录界面，显示管理器)主题 乃至鼠标主题等<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/gnomelook-left.webp" alt="gnomelook-left"></p><h2 id="下载外观资源"><a href="#下载外观资源" class="headerlink" title="下载外观资源"></a>下载外观资源</h2><h3 id="GTK3桌面主题"><a href="#GTK3桌面主题" class="headerlink" title="GTK3桌面主题"></a>GTK3桌面主题</h3><p>在左侧分类栏选择想要下载的外观资源，首先是桌面主题，选择GTK3的主题（GTK3 Themes），然后会列出所有的GTK3主题，列表默认是Latest最新，点击Score按评分列出。<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/gtk-score.webp" alt="gtk-score"><br>那写这篇的这个时间里名为<a href="https://www.gnome-look.org/p/1275087/" target="_blank" rel="noopener">【McMojave】</a>的GTK3主题评分最高，当然我安装的也就是这个主题，以下也是描述安装这个主题，<em>当然如果你想安装其他的主题也都是一样的步骤</em>。<br>这边点进你想要安装的主题的详细信息页面，可以看到作者对主题的描述等，下面还有作者推荐的图标主题(icon theme)，这里点击【file】进入下载主题文件的页面<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/mojave-infos.webp" alt="mojave-infos"><br>这里有很多文件，<strong>不需要全部下载</strong>，下载需要的或者想要的就可以了。我下载了【Mojave-dark.tar.xz】和【Mojave-light.tar.xz】也就是暗色和亮色主题。这里的solid指的是非透明主题，至于alt是什么意思我也不清楚。。。而我在前言里的图片就是它的暗色主题啦。<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/mojave-files.webp" alt="mojave-files"></p><h3 id="图标主题资源"><a href="#图标主题资源" class="headerlink" title="图标主题资源"></a>图标主题资源</h3><p>那到这里桌面主题就下载完成了，现在还需要去下载图标主题资源<br>像McMojave这个主题在详情页推荐了它对应的图标主题，我们直接点进去，在【file】里下载就可以了，同样有很多文件，我们只下载想要的就可以了。<br>那如果有的主题没有推荐的图标或者并不想用对应主题的推荐图标，我们也可以在Gnome-look网站左侧栏点击【Icon Themes】,找到自己心仪的图标主题，过程和之前描述的GTK3主题如出一辙，我就不多赘述了</p><h3 id="其他主题资源"><a href="#其他主题资源" class="headerlink" title="其他主题资源"></a>其他主题资源</h3><p>那如果你需要下载其他的主题资源，譬如grub主题，Plymouth开机画面主题、GDM (GNOME Display Manager,用户登录界面，显示管理器)主题、Cursors鼠标主题等，下载过程也是跟上面描述的GTK3桌面主题一样</p><h1 id="桌面系统美化"><a href="#桌面系统美化" class="headerlink" title="桌面系统美化"></a>桌面系统美化</h1><h2 id="主题资源安装（解压）"><a href="#主题资源安装（解压）" class="headerlink" title="主题资源安装（解压）"></a>主题资源安装（解压）</h2><p>将资源文件解压到对应的目录中<br>其中桌面主题解压到<code>/usr/share/themes/</code>目录下<br>图标主题或鼠标主题解压到<code>/usr/share/icons/</code>目录下<br>桌面/锁屏背景图放到<code>/usr/share/backgrounds/</code>目录下</p><div class="note warning"><p>这里要注意主题是以目录形式放在<code>themes</code>或者<code>icons</code>目录下的，不是直接散在那两个目录下的，解压完之后要注意ls看一下</p></div><h2 id="主题配置工具安装"><a href="#主题配置工具安装" class="headerlink" title="主题配置工具安装"></a>主题配置工具安装</h2><p>主题配置需要「gnome-tweak-tool」</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get install gnome-tweak-tool</span><br><span class="line">sudo apt-get install gnome-shell-extensions</span><br></pre></td></tr></table></figure><h2 id="shell拓展安装"><a href="#shell拓展安装" class="headerlink" title="shell拓展安装"></a>shell拓展安装</h2><p>这里推荐用火狐浏览器插件安装拓展</p><ol><li>打开你的<strong>Firefox火狐浏览器</strong>，打开<a href="https://extensions.gnome.org/" target="_blank" rel="noopener">https://extensions.gnome.org/</a></li><li>网页提示需要完成安装浏览器插件和本地应用两步<br>直接点click here to install brower extension安装浏览器插件</li><li>然后终端输入命令安装本地软件<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install chrome-gnome-shell</span><br></pre></td></tr></table></figure></li><li>安装完后打开<a href="https://extensions.gnome.org/extension/19/user-themes/" target="_blank" rel="noopener">https://extensions.gnome.org/extension/19/user-themes/</a>安装user-themes拓展</li></ol><p>这边安装拓展的方式很简单，在user-themes的右边可以看到一个按钮。不需要在下面选择版本，直接点击按钮拨到「on」，过一会儿会弹出一个弹窗提示你是否安装，点安装即可。<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/extension-user-themes.webp" alt="extension-user-themes"></p><p>在这个网站里你还可以通过这种方式安装其他的拓展，建议安装<br>「Dash to Dock」、「Hide Top Bar」、「Simple net speed」这几个拓展</p><p>当然除了通过火狐浏览器插件安装拓展以外，也可以通过软件包管理来安装，这里不做描述了。</p><h2 id="桌面美化过程"><a href="#桌面美化过程" class="headerlink" title="桌面美化过程"></a>桌面美化过程</h2><ul><li>打开gnome-tweak-tool（优化），选择拓展，打开User themes （这里上一条通过火狐浏览器安装拓展已经打开的话就可以忽略这条）</li><li>选择外观，进行设置<br>这里【应用程序】指的是安装的GTK3的主题，光标指的是cursor鼠标主题，图标即icon主题，shell选择主题对应的即可；至于下面锁屏和背景的图像，选择自己复制在background目录下的图片即可<br><em>如果shell上有感叹号，关闭tweak，按Alt+F2，输入r，执行后重新打开tweak再设置shell选项。</em><br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/%E5%A4%96%E8%A7%82%E8%AE%BE%E7%BD%AE.webp" alt="外观设置"></li><li>调整标题栏按钮位置<br>选择【窗口】，滑到最下面，将【放置】改为左</li><li>调整Dock，使用Dash to Dock拓展<br>选择【拓展】，开启【Dash to Dock】，点击设置图标(小齿轮)，然后按下图设置<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/Dash_to_Dock_config.webp" alt="Dash_to_Dock_config"></li></ul><h1 id="开关机启动动画美化"><a href="#开关机启动动画美化" class="headerlink" title="开关机启动动画美化"></a>开关机启动动画美化</h1><ul><li>首先还是下载启动动画主题<br>还是在<a href="https://www.gnome-look.org/" target="_blank" rel="noopener">gnome-look网站</a>里，左侧栏选择【Plymouth Themes】找到你想要的主题<br>那我这里选择的是<a href="https://www.pling.com/p/1156215/" target="_blank" rel="noopener">Paw Ubuntu/Mint Floral</a></li></ul><p><em>这位<a href="https://www.pling.com/u/markospoko/" target="_blank" rel="noopener">MARKOSPOKO</a>还有不少不错的ubuntu Plymouth开关机主题，可以看一看选择一下</em></p><ul><li>将下载下来的主题压缩包解压，将解压下来的主题目录复制到<code>/usr/share/plymouth/themes/</code>目录</li><li>备份原来的plymouth配置文件并编辑修改<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo cp /etc/alternatives/default.plymouth /etc/alternatives/default.plymouth.bak</span><br><span class="line">sudo vim /etc/alternatives/default.plymouth</span><br></pre></td></tr></table></figure></li><li>最后将<code>default.plymouth</code>文件的最后两行按下图方式修改，注意修改的主题目录和自己下载复制的匹配，最后的script文件要自己去主题目录下ls看一下script文件名是什么。<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/plymouth-config.webp" alt="plymouth-config"></li></ul><h1 id="登录界面GDM（显示管理器）主题美化"><a href="#登录界面GDM（显示管理器）主题美化" class="headerlink" title="登录界面GDM（显示管理器）主题美化"></a>登录界面GDM（显示管理器）主题美化</h1><ul><li>还是在<a href="https://www.gnome-look.org/" target="_blank" rel="noopener">gnome-look网站</a>里，左侧栏选择【GDM Themes】找到你想要的主题 下载<br>我这里演示的是仿Mac的<a href="https://www.pling.com/s/Gnome/p/1207015/" target="_blank" rel="noopener">High Ubunterra</a>，我也比较推荐这个。<br>打开High Ubunterra的详细描述页面，下面很详细的介绍了注意事项和安装方式，包括不同版本的Ubuntu应该下载不同的版本，还分为有密码和无密码两种<br>那我这里是Ubuntu18.04，于是我下载的是【High_Ubunterra_2.3(Pass).tar.xz】</li><li>将下载下来的压缩文件解压，按照主题的详细页面所描述的，使用install.sh脚本直接安装即可<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/high_ubunterra_install.webp" alt="high_ubunterra_install"><br>然后根据终端提示的，按Alt+F2，输入r，执行后再按Win+L进入锁屏查看效果<blockquote><p><strong>emm……本来应该是这样就可以了，但是实际上进入锁屏界面却发现情况有点不对，界面的背景图片没有了</strong><br>于是我们查看 <code>/etc/alternatives/gdm3.css</code>文件里的lockDialogGroup类，发现背景图片指向<code>/usr/share/backgrounds/gdmlock.jpg</code><br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/lockDialogGroup.webp" alt="lockDialogGroup"><br>但是在/usr/share/backgrounds/目录下ls并未发现gdmlock.jpg图片文件<br>于是问题找到了，也好解决<br><strong>只需要将背景图复制到<code>/usr/share/backgrounds/gdmlock.jpg</code> 即可，或者修改<code>/etc/alternatives/gdm3.css</code>文件，但更推荐复制背景图</strong></p></blockquote></li></ul><h1 id="grub-美化"><a href="#grub-美化" class="headerlink" title="grub 美化"></a>grub 美化</h1><ul><li>还是在<a href="https://www.gnome-look.org/" target="_blank" rel="noopener">gnome-look网站</a>里，左侧栏选择【GRUB Themes】找到你想要的主题 下载<br>我这里演示的是<a href="https://www.gnome-look.org/p/1009236/" target="_blank" rel="noopener">Vimix</a>主题</li><li>这个主题的安装方式也是很简单粗暴，解压后在里面打开终端，使用<code>install.sh</code>脚本安装即可<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo ./install.sh</span><br></pre></td></tr></table></figure></li></ul><h1 id="终端美化"><a href="#终端美化" class="headerlink" title="终端美化"></a>终端美化</h1><h2 id="gnome-terminal的配置"><a href="#gnome-terminal的配置" class="headerlink" title="gnome-terminal的配置"></a>gnome-terminal的配置</h2><p>terminal的美化过程很简单，Ctrl+Alt+T打开终端</p><ul><li>选择【编辑】-&gt; 【首选项】-&gt; 【常规】，将第一项【默认在新终端中显示菜单栏】的勾去掉</li><li>然后点击下面的配置文件进行修改，将【使用系统主题的透明度】的勾去掉，再把【使用透明背景】勾上，在右边调整透明度<br>透明度不要太高，太透明就不好看清字了，稍微透明一点就可以了<h2 id="shell-zsh"><a href="#shell-zsh" class="headerlink" title="shell(zsh)"></a>shell(zsh)</h2></li></ul><p><strong>推荐放弃bash，使用zsh配合<a href="https://ohmyz.sh/" target="_blank" rel="noopener">oh-my-zsh</a>起飞</strong></p><h3 id="安装zsh与oh-my-zsh"><a href="#安装zsh与oh-my-zsh" class="headerlink" title="安装zsh与oh-my-zsh"></a>安装zsh与oh-my-zsh</h3><ul><li>首先安装「zsh」 「git 」「curl 」<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get install zsh  git  curl</span><br></pre></td></tr></table></figure></li><li>然后根据<a href="https://ohmyz.sh/" target="_blank" rel="noopener">oh-my-zsh</a>官网的安装脚本进行安装<div class="tabs" id="tab标签列表"><ul class="nav-tabs"><li class="tab active"><a href="#tab标签列表-1">通过curl安装</a></li><li class="tab"><a href="#tab标签列表-2">通过wget安装</a></li></ul><div class="tab-content"><div class="tab-pane active" id="tab标签列表-1"><p><code>sh -c &quot;$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)&quot;</code></p></div><div class="tab-pane" id="tab标签列表-2"><p><code>sh -c &quot;$(wget https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)&quot;</code></p></div></div></div></li></ul><blockquote><p>安装过程中会询问是否切换默认shell为zsh，记得选“Y”</p></blockquote><blockquote><p>当然如果不能通过脚本直接安装oh-my-zsh的情况下，官方文档里也有手动安装的过程教程<a href="https://github.com/robbyrussell/oh-my-zsh#manual-installation" target="_blank" rel="noopener">https://github.com/robbyrussell/oh-my-zsh#manual-installation</a></p></blockquote><h3 id="更改oh-my-zsh主题"><a href="#更改oh-my-zsh主题" class="headerlink" title="更改oh-my-zsh主题"></a>更改oh-my-zsh主题</h3><p>更改oh-my-zsh主题需要修改zsh的配置</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vim ~/.zshrc</span><br></pre></td></tr></table></figure><p>在11行左右会有「ZSH_THEME」变量，也就是oh-my-zsh主题了，默认是<code>robbyrussell</code>，你可以去搜一搜有哪些好看的自带主题，修改这一变量的值为主题名即可<br>我这里提几个我常用的，「ys」「agnoster」「amuse」「candy」<br>当然你也可以写「random」，每次打开终端都会随机选择一个主题呈现，也挺有趣的<br>当然也可以选择几个固定的主题，每次在这些主题中随机，你只需要将<code>ZSH_THEME</code>变量修改<code>random</code>之后，将下面的<code>ZSH_THEME_RANDOM_CANDIDATES</code>变量的#注释去掉，并像这样修改即可</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">ZSH_THEME_RANDOM_CANDIDATES=(</span><br><span class="line">  <span class="string">"robbyrussell"</span></span><br><span class="line">  <span class="string">"agnoster"</span></span><br><span class="line">   <span class="string">"ys"</span></span><br><span class="line">)</span><br></pre></td></tr></table></figure><h3 id="powerline字体安装"><a href="#powerline字体安装" class="headerlink" title="powerline字体安装"></a>powerline字体安装</h3><p>oh-my-zsh的许多主题需要<a href="https://github.com/powerline/fonts" target="_blank" rel="noopener">powerline字体</a>支持<br>ubuntu可以直接通过apt安装</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get install fonts-powerline</span><br></pre></td></tr></table></figure><p>这时重启终端，像<code>agnoster</code>这样的主题应该就不会乱码了</p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --&gt;&lt;p&gt;今天才把物理机上的Ubuntu升到了18.04，原因有很大一部分是因为不想去鼓捣桌面界面之类的，毕竟&lt;strong&gt;&lt;em&gt;Ubuntu从18.04开始，桌面程序放弃了unity而回归了Gnome&lt;/em&gt;&lt;/strong&gt;～～美化是一定要美化的，毕竟这是自己电脑里用作图形桌面的，又不是要做server，要看的东西当然要赏心悦目啦。&lt;/p&gt;&lt;h1 id=&quot;写在前面&quot;&gt;&lt;a href=&quot;#写在前面&quot; class=&quot;headerlink&quot; title=&quot;写在前面&quot;&gt;&lt;/a&gt;写在前面&lt;/h1&gt;&lt;p&gt;首先先看看美化后的桌面效果，这里用的是仿Mac的Mojave-dark主题&lt;br&gt;&lt;img src=&quot;https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/front1.webp&quot; alt=&quot;front1&quot;&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="Tech" scheme="https://blog8.flyky.org/categories/Tech/"/>
    
      <category term="ubuntu" scheme="https://blog8.flyky.org/categories/Tech/ubuntu/"/>
    
      <category term="美化" scheme="https://blog8.flyky.org/categories/Tech/ubuntu/%E7%BE%8E%E5%8C%96/"/>
    
    
      <category term="ubuntu" scheme="https://blog8.flyky.org/tags/ubuntu/"/>
    
      <category term="美化" scheme="https://blog8.flyky.org/tags/%E7%BE%8E%E5%8C%96/"/>
    
      <category term="Gnome" scheme="https://blog8.flyky.org/tags/Gnome/"/>
    
      <category term="zsh" scheme="https://blog8.flyky.org/tags/zsh/"/>
    
      <category term="oh my zsh" scheme="https://blog8.flyky.org/tags/oh-my-zsh/"/>
    
      <category term="grub美化" scheme="https://blog8.flyky.org/tags/grub%E7%BE%8E%E5%8C%96/"/>
    
  </entry>
  
  <entry>
    <title>Nginx编译安装指北</title>
    <link href="https://blog8.flyky.org/20190630/Nginx-make-install-script/"/>
    <id>https://blog8.flyky.org/20190630/Nginx-make-install-script/</id>
    <published>2019-06-30T02:19:46.000Z</published>
    <updated>2021-01-26T09:06:13.102Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --><p>Nginx 无疑是我最最常用的Web Server。就我多年使用的经验来说，这玩意的安装方式(Linux)，最最好还是编译安装<br>虽然不如软件包管理来的方便，但是万一哪天你想装个插件写个插件啥的你就哭去吧，等着你卸载重装<br>另外就是软件包管理的nginx版本，有的可以老出几个世纪（笑）<br>编译安装的话在这方面就灵活的多啦～～～</p><p><em>当然今天突然想起来写这篇还是因为之前腾讯云阿里云的学生认证到期了，得重新买了，当然这边环境也就重新搭，顺便写一下<br>（话说这个安装脚本一直都是记在OneNote上的，哪天心情好把记在OneNote里的东西都转到博客上来呢，，hh我还是太懒）</em></p><a id="more"></a><h1 id="依赖安装"><a href="#依赖安装" class="headerlink" title="依赖安装"></a>依赖安装</h1><p>编译安装nginx前需要解决两个问题</p><ol><li><p>编译所需的编译器等软件，比如<code>gcc</code>，<code>make</code>之类的</p></li><li><p>第三方依赖包，安装nginx的第三方依赖一般是这三个</p><ul><li><p>pcre库（支持rewrite模块）『一个Perl库，包括 Perl兼容的正则表达式库』</p></li><li><p>zlib库（支持gzip模块）『提供数据压缩用的函式库』</p></li><li><p>openssl库（支持ssl模块）『一个强大的安全套接字层密码库』</p><p>那这些库就完全没有必要编译安装了，一般的linux发行版直接用软件包管理安装即可</p></li></ul></li></ol><p><strong>下面就贴出软件包管理安装这些依赖的命令</strong></p><div class="tabs" id="安装依赖"><ul class="nav-tabs"><li class="tab active"><a href="#安装依赖-1">RedHat系(yum)</a></li><li class="tab"><a href="#安装依赖-2">Debian系(apt)</a></li></ul><div class="tab-content"><div class="tab-pane active" id="安装依赖-1"><p><code>yum -y install gcc gcc-c++ automake pcre-devel zlib-devel openssl-devel</code></p></div><div class="tab-pane" id="安装依赖-2"><p><code>sudo apt-get install build-essential libpcre3-dev libssl-dev zlib1g-dev</code></p></div></div></div><hr><div class="note primary"><p>当然这三个第三方库也可以编译安装</p><ul><li>先去<a href="http://www.pcre.org/" target="_blank" rel="noopener">pcre</a>、<a href="http://zlib.net/" target="_blank" rel="noopener">zlib</a>、<a href="https://www.openssl.org/" target="_blank" rel="noopener">openssl</a>的官网或者镜像站下载源码包</li><li>解压包之后在源码包根目录 configure, make, sudo make install 即可，编译安装如遇问题自行百度<br><strong>记得configure的时候prefix安装位置</strong>，比如<div class="tabs" id="configures"><ul class="nav-tabs"><li class="tab active"><a href="#configures-1">pcre</a></li><li class="tab"><a href="#configures-2">zlib</a></li><li class="tab"><a href="#configures-3">openssl</a></li></ul><div class="tab-content"><div class="tab-pane active" id="configures-1"><p><code>./configure --prefix=/usr/local/libpcre</code></p></div><div class="tab-pane" id="configures-2"><p><code>./configure --prefix=/usr/local/zlib</code></p></div><div class="tab-pane" id="configures-3"><p><code>./Configure darwin64-x86_64-cc --prefix=/usr/local/openssl --openssldir=/usr/local/openssl</code></p></div></div></div></li><li>在下面的脚本后添加如下几段选项配置<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">--with-pcre=/xxx/pcre_source \</span><br><span class="line">--with-zlib=/xxx/zlib_source \</span><br></pre></td></tr></table></figure>这里面的`/xxx/source`要替换成你下载解压的pcre和zlib的**源码包目录路径**，注意是源码包</li></ul></div><h1 id="configure脚本"><a href="#configure脚本" class="headerlink" title="configure脚本"></a>configure脚本</h1><p><strong>废话也不多说了，直接上脚本，会用的直接拿去，不用听我在下面解释了～～～</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">./configure --prefix=/usr/<span class="built_in">local</span>/nginx \</span><br><span class="line">--sbin-path=/usr/sbin/nginx \</span><br><span class="line">--conf-path=/etc/nginx/nginx.conf \</span><br><span class="line">--error-log-path=/var/<span class="built_in">log</span>/nginx/error.log \</span><br><span class="line">--pid-path=/var/run/nginx/nginx.pid \</span><br><span class="line">--lock-path=/var/run/nginx.lock \</span><br><span class="line">--with-http_ssl_module \</span><br><span class="line">--user=nginx \</span><br><span class="line">--group=nginx \</span><br><span class="line">--http-log-path=/var/<span class="built_in">log</span>/nginx/access.log \</span><br><span class="line">--http-client-body-temp-path=/var/cache/nginx/client_temp \</span><br><span class="line">--http-proxy-temp-path=/var/cache/nginx/proxy_temp \</span><br><span class="line">--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \</span><br><span class="line">--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \</span><br><span class="line">--http-scgi-temp-path=/var/cache/nginx/scgi_temp \</span><br><span class="line">--with-http_sub_module \</span><br><span class="line">--with-http_realip_module \</span><br><span class="line">--with-http_dav_module \</span><br><span class="line">--with-http_mp4_module \</span><br><span class="line">--with-http_flv_module \</span><br><span class="line">--with-http_gzip_static_module \</span><br><span class="line">--with-http_gunzip_module \</span><br><span class="line">--with-http_stub_status_module \</span><br><span class="line">--with-http_random_index_module \</span><br><span class="line">--with-http_secure_link_module \</span><br><span class="line">--with-http_auth_request_module \</span><br><span class="line">--with-mail \</span><br><span class="line">--with-mail_ssl_module \</span><br><span class="line">--with-file-aio \</span><br><span class="line">--with-threads \</span><br><span class="line">--with-stream_ssl_module \</span><br><span class="line">--with-http_slice_module \</span><br><span class="line">--with-http_v2_module</span><br></pre></td></tr></table></figure><p>这是我每次编译安装nginx都会用到的选项配置（虽然里面有很多选项都是默认配置，不过列出来方便修改也直观），我基本上除了外加的nginx插件配置，其他的安装配置都在这里面了</p><h1 id="添加第三方Nginx插件"><a href="#添加第三方Nginx插件" class="headerlink" title="添加第三方Nginx插件"></a>添加第三方Nginx插件</h1><p>Nginx能够添加许多第三方插件，但是大部分都需要编译安装添加<br>这里我以<a href="https://github.com/winshining/nginx-http-flv-module" target="_blank" rel="noopener"><code>nginx-http-flv-module</code></a>模块举例</p><blockquote><p><a href="https://github.com/winshining/nginx-http-flv-module" target="_blank" rel="noopener">nginx-http-flv-module</a>是一个基于<a href="https://github.com/arut/nginx-rtmp-module" target="_blank" rel="noopener">nginx-rtmp-module</a>的流媒体服务器<br>因为以前用nginx搭过直播服务器，机缘巧合了解的</p></blockquote><ul><li>首先下载该模块源码，解压到nginx的源码包根目录(推荐)，将模块源码目录名改成<code>nginx-http-flv-module</code></li><li>修改上面的脚本，添加下面的代码<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">--add-module=nginx-http-flv-module</span><br></pre></td></tr></table></figure><em>这里如果你没有把解压的模块源码包放在nginx包根目录也没有改名，那么在<code>--add-module=</code>后面写它的绝对路径 或者 于nginx包的相对路径</em></li><li>之后按下面的继续编译安装即可</li></ul><div class="note warning"><p>注意解决该模块自身的依赖问题，具体详见自己安装的模块的文档描述</p></div><h1 id="configure脚本使用"><a href="#configure脚本使用" class="headerlink" title="configure脚本使用"></a>configure脚本使用</h1><p>嘛这个使用起来很简单的嘞，先把nginx官网下载的源码包解压了，然后进入到源码包根目录，新建一个sh文件，那我这里一般就简单粗暴的叫<code>c.sh</code>，然后把上面的脚本粘进去保存。<br>记得给<code>c.sh</code>执行权限，之后执行这个脚本就可以了</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">chmod +x c.sh</span><br><span class="line">./c.sh</span><br></pre></td></tr></table></figure><h1 id="编译安装"><a href="#编译安装" class="headerlink" title="编译安装"></a>编译安装</h1><blockquote><p>至于编译安装的过程就不赘述了，configure之后就是make加make install三步走就完了，不报错就行了<br>make install因为上面脚本配置上涉及写入文件到一些需要root权限的目录，非root用户记得加<code>sudo</code></p></blockquote><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">make</span><br><span class="line">sudo make install</span><br></pre></td></tr></table></figure><p>安装完之后使用nginx命令启动不报错即可，如果需要停止nginx，使用<code>nginx -s stop</code>，修改配置后重新启动使用<code>nginx -s reload</code></p><h1 id="常见报错"><a href="#常见报错" class="headerlink" title="常见报错"></a>常见报错</h1><h2 id="nginx-emerg-getpwnam-“nginx”-failed"><a href="#nginx-emerg-getpwnam-“nginx”-failed" class="headerlink" title="nginx: [emerg] getpwnam(“nginx”) failed"></a>nginx: [emerg] getpwnam(“nginx”) failed</h2><p>出现原因是因为编译配置指定了启动的用户和用户组：<code>--user=nginx</code> 和 <code>--group=nginx</code><br>然而系统内并没有该用户和用户组以启动导致的报错<br>解决方案无非两种：</p><ol><li>将编译配置中的指定用户和用户组的两行配置去掉，重新编译安装</li><li>新建该用户 <code>sudo useradd -s /sbin/nologin -M nginx</code></li></ol><p>虽然两种都可以，但一般更建议使用第二种<br>因为出于安全性考虑，还是用独立权限的账户运行更安全</p><h2 id="nginx-emerg-mkdir-“-var-cache-nginx-client-temp”-failed-2-No-such-file-or-directory"><a href="#nginx-emerg-mkdir-“-var-cache-nginx-client-temp”-failed-2-No-such-file-or-directory" class="headerlink" title="nginx: [emerg] mkdir() “/var/cache/nginx/client_temp” failed (2: No such file or directory)"></a>nginx: [emerg] mkdir() “/var/cache/nginx/client_temp” failed (2: No such file or directory)</h2><p>那这种一看就知道是权限问题，无法创建目录<br>因为指定了的启动用户没有权限在该目录下创建文件或目录的类似报错<br>解决方法很简单直接sudo或切root手动创建目录<br><code>mkdir -p /var/cache/nginx/client_temp</code></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --&gt;&lt;p&gt;Nginx 无疑是我最最常用的Web Server。就我多年使用的经验来说，这玩意的安装方式(Linux)，最最好还是编译安装&lt;br&gt;虽然不如软件包管理来的方便，但是万一哪天你想装个插件写个插件啥的你就哭去吧，等着你卸载重装&lt;br&gt;另外就是软件包管理的nginx版本，有的可以老出几个世纪（笑）&lt;br&gt;编译安装的话在这方面就灵活的多啦～～～&lt;/p&gt;&lt;p&gt;&lt;em&gt;当然今天突然想起来写这篇还是因为之前腾讯云阿里云的学生认证到期了，得重新买了，当然这边环境也就重新搭，顺便写一下&lt;br&gt;（话说这个安装脚本一直都是记在OneNote上的，哪天心情好把记在OneNote里的东西都转到博客上来呢，，hh我还是太懒）&lt;/em&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="Tech" scheme="https://blog8.flyky.org/categories/Tech/"/>
    
      <category term="nginx" scheme="https://blog8.flyky.org/categories/Tech/nginx/"/>
    
    
      <category term="nginx" scheme="https://blog8.flyky.org/tags/nginx/"/>
    
      <category term="make install" scheme="https://blog8.flyky.org/tags/make-install/"/>
    
  </entry>
  
  <entry>
    <title>~ frp内网穿透简单配置 ~</title>
    <link href="https://blog8.flyky.org/20181206/frp_configs/"/>
    <id>https://blog8.flyky.org/20181206/frp_configs/</id>
    <published>2018-12-06T11:07:02.000Z</published>
    <updated>2021-01-26T09:06:13.105Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --><h1 id="内网穿透"><a href="#内网穿透" class="headerlink" title="内网穿透"></a>内网穿透</h1><p>即NAT穿透，本质上是通过映射端口，使得内网的网络服务可以被外网所访问<br>嘛，，实际意义就是，大家家里的网络都是运营商分配的ip，并不是外网ip，无法直接用家里的电脑/服务器提供网络服务，譬如网站等<br>通过内网穿透即可将内网中你所提供的网络服务的端口映射到外网某ip的某端口，即可实现通过被映射的外网端口访问到内网服务<br>一般有很多提供这种服务的服务商譬如花生壳等，也有很多人知道一些譬如Ngrok的服务，而这里我所要描述的是一款名为<strong>frp</strong>的应用</p><h1 id="what-is-the-「frp」"><a href="#what-is-the-「frp」" class="headerlink" title="what is the 「frp」"></a>what is the 「frp」</h1><blockquote class="blockquote-center"><p>frp 是一个可用于内网穿透的高性能的反向代理应用，支持 tcp, udp, http, https 协议。</p></blockquote><p><em>来自文档描述</em><br><a href="https://github.com/fatedier/frp" target="_blank" rel="noopener">frp项目github地址</a></p><a id="more"></a><p>话说了解frp的契机嘛，就是MinecraftServer了<br>腾讯云阿里云等的小基础配置根本带不动现在越来越卡优化越来越差游戏版本了，也买不起更高配置的VPS了，当然是用自己的电脑开最经济。那就得解决内网问题了。正好不知道在哪儿看到了<a href="https://www.natfrp.com/" target="_blank" rel="noopener">SakuraFrp</a>的宣传，那与其用公用的那当然不如自建啦。<br>当然这玩意的用处不只是搭游戏服务器，无论是网站还是什么服务基本上都可以，大部分的网络通信协议都支持，只不过就普通的网站之类的服务，vps的基础配置也绰绰有余了，犯不着用这玩意在自己家搭，，不过话说回来，搭个NAS啊监控啊之类的还是用得着的恩恩。</p><h1 id="frps-server-部署配置"><a href="#frps-server-部署配置" class="headerlink" title="frps (server) 部署配置"></a>frps (server) 部署配置</h1><p>首先是服务端，那做内网穿透的话，服务端当然是建在有公网ip的远程服务器上。 （服务端机器相当于是服务提供者和服务访问者中间的桥梁）<br>先在<a href="https://github.com/fatedier/frp/releases" target="_blank" rel="noopener">Frp官网(github)</a>上下载下来的对应系统的frp程序包，解压后可以看到frp的服务端、客户端的程序和配置文件。<br>因为这里是做服务端，可以先把客户端相关的东西删了（当然不删也无所谓）。在frp目录下执行：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">rm ./frpc*</span><br></pre></td></tr></table></figure><p>现在就该修改配置文件了</p><h1 id="frpc-client-配置"><a href="#frpc-client-配置" class="headerlink" title="frpc (client) 配置"></a>frpc (client) 配置</h1><p>现在轮到客户端了。<br>不过提一下，这里的客户端指的是提供<code>想要被外网访问的服务</code>的内网机器。<br><em>提这一句的原因是，frp的客户端还有一种用法，是在<a href="https://github.com/fatedier/frp/blob/master/README_zh.md#安全地暴露内网服务" target="_blank" rel="noopener">stcp</a>这种安全访问的服务上，或者是<a href="https://github.com/fatedier/frp/blob/master/README_zh.md#点对点内网穿透" target="_blank" rel="noopener">xtcp</a>这种p2p连接服务上，客户端需要同时设置在内网服务和访问者两端，当然这种情况我这篇博文不会展开描述，有兴趣欢迎去看<a href="https://github.com/fatedier/frp/blob/master/README_zh.md" target="_blank" rel="noopener">官方文档</a></em></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --&gt;&lt;h1 id=&quot;内网穿透&quot;&gt;&lt;a href=&quot;#内网穿透&quot; class=&quot;headerlink&quot; title=&quot;内网穿透&quot;&gt;&lt;/a&gt;内网穿透&lt;/h1&gt;&lt;p&gt;即NAT穿透，本质上是通过映射端口，使得内网的网络服务可以被外网所访问&lt;br&gt;嘛，，实际意义就是，大家家里的网络都是运营商分配的ip，并不是外网ip，无法直接用家里的电脑/服务器提供网络服务，譬如网站等&lt;br&gt;通过内网穿透即可将内网中你所提供的网络服务的端口映射到外网某ip的某端口，即可实现通过被映射的外网端口访问到内网服务&lt;br&gt;一般有很多提供这种服务的服务商譬如花生壳等，也有很多人知道一些譬如Ngrok的服务，而这里我所要描述的是一款名为&lt;strong&gt;frp&lt;/strong&gt;的应用&lt;/p&gt;&lt;h1 id=&quot;what-is-the-「frp」&quot;&gt;&lt;a href=&quot;#what-is-the-「frp」&quot; class=&quot;headerlink&quot; title=&quot;what is the 「frp」&quot;&gt;&lt;/a&gt;what is the 「frp」&lt;/h1&gt;&lt;blockquote class=&quot;blockquote-center&quot;&gt;&lt;p&gt;frp 是一个可用于内网穿透的高性能的反向代理应用，支持 tcp, udp, http, https 协议。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;em&gt;来自文档描述&lt;/em&gt;&lt;br&gt;&lt;a href=&quot;https://github.com/fatedier/frp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;frp项目github地址&lt;/a&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="Tech" scheme="https://blog8.flyky.org/categories/Tech/"/>
    
      <category term="端口映射" scheme="https://blog8.flyky.org/categories/Tech/%E7%AB%AF%E5%8F%A3%E6%98%A0%E5%B0%84/"/>
    
      <category term="frp" scheme="https://blog8.flyky.org/categories/Tech/%E7%AB%AF%E5%8F%A3%E6%98%A0%E5%B0%84/frp/"/>
    
    
      <category term="note" scheme="https://blog8.flyky.org/tags/note/"/>
    
      <category term="frp" scheme="https://blog8.flyky.org/tags/frp/"/>
    
  </entry>
  
  <entry>
    <title>ASS字幕常用基础特效代码整理</title>
    <link href="https://blog8.flyky.org/20181105/summary_of_ASSsubtitle_codes/"/>
    <id>https://blog8.flyky.org/20181105/summary_of_ASSsubtitle_codes/</id>
    <published>2018-11-05T13:44:37.000Z</published>
    <updated>2021-01-26T09:06:13.108Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --><p>其实并不常做字幕特效，毕竟也基本上都是心血来潮自己完成全部的字幕任务，不过每次想做的时候总是记不住那些特效代码，翻帖子去找然后慢慢试效果，果然还是自己整理一个较常用的标签列表比较妥当</p><p>先贴一个<strong>完整</strong>的<a href="https://aegi.vmoe.info/docs/3.2/ASS_Tags/" target="_blank" rel="noopener">标签代码手册</a></p><a id="more"></a><h1 id="基本规则"><a href="#基本规则" class="headerlink" title="基本规则"></a>基本规则</h1><ul><li>形如<code>{\代码名1(值)\代码名2\代码名3值}</code>的用<strong>大括号{}</strong>括起的即为生效的一块代码组，每个代码前必须有<strong>反斜杠*</strong>，<strong>小括号</strong>不是必须（看相应代码是否需要，值可如坐标，持续时间等），上例为三个代码组成的一组，因为代码前都有反斜杠，可以通过反斜杠来区分组内的每个代码，而代码1需要小括号和值，代码2不需要值，代码3后面直接加值不需要小括号</li><li>反之，括号外的即<em>字幕内容</em>，如果大括号{}外出现了带反斜杠\的代码，不用怀疑，那肯定不是特效代码，十有八九是<strong>转义字符</strong>，譬如\N即为换行，\h为空格</li><li>若行内出现了被若干组代码，切记代码会对在其后的<strong><em>所有文字</em></strong>生效，而特性相同值不同的代码会<strong><em>被后面的代码覆盖</em></strong></li></ul><h1 id="代码整理"><a href="#代码整理" class="headerlink" title="代码整理"></a>代码整理</h1><h2 id="基本效果"><a href="#基本效果" class="headerlink" title="基本效果"></a>基本效果</h2><ol><li><p>pos 位置，没什么好说的，动一下就会有，然后xy微调即可<br>(0,0)为左上顶点，向右x正方向，向下y正方向</p></li><li><p>fad 淡入淡出<br>如<code>\fad(100,150)</code>100和150分别是开始和结束时间，单位嘛，这里的1000毫秒是1秒<br>再如<code>\fad(100,0)</code>指渐渐出现直接消失，\fad(0,100)是直接出现渐渐消失</p></li><li><p>move 位移<br><code>{\move(X1,Y1,X2,Y2,t1,t2)}</code>，即字幕从(X1,Y1)的位置在本字幕始的t1毫秒到t2毫秒，以均速平滑移动到(X2,Y2)<br>t1,t2可省略，默认为整行字幕的时间</p></li><li><p>blur 边缘柔化/模糊<br>如<code>\blur1</code>，blur后直接跟模糊值，不必小括号</p></li><li><p>bord 边框宽度<br>如<code>\bord1</code>，bord后直接跟宽度值，不必小括号</p></li><li><p>fs 即font size,字体大小<br><code>\fs10</code>即字体大小设置为10，注意这里的值必须是整数</p></li><li><p>fsp 即font spacing字符间距，间距可以为负</p></li><li><p>frx,fry,frz 文本旋转 font rotate<br><code>\frx45</code>把文本沿 X 轴方向旋转45度<br><code>\fry-45</code>把文本沿 Y 轴反方向旋转45度<br><code>\frz180</code>把文本沿 Z 轴旋转180度，即上下翻转</p></li><li><p>fscx,fscy 即Font scale字体在x或y轴上缩放<br><code>\fscx150</code>字体比正常的宽50%<br><code>\fscy50</code>字体比正常的矮50%<br><code>\fscx200\fscy200</code>字体大小变成正常的两倍</p></li><li><p>设置颜色<br><code>\c&amp;H&lt;bb&gt;&lt;gg&gt;&lt;rr&gt;&amp;</code> 为1c的缩写。。。。<br><code>\1c&amp;H&lt;bb&gt;&lt;gg&gt;&lt;rr&gt;&amp;</code> 设置主要填充颜色<br><code>\2c&amp;H&lt;bb&gt;&lt;gg&gt;&lt;rr&gt;&amp;</code> 设置次要填充颜色<br><code>\3c&amp;H&lt;bb&gt;&lt;gg&gt;&lt;rr&gt;&amp;</code> 设置边框颜色<br><code>\4c&amp;H&lt;bb&gt;&lt;gg&gt;&lt;rr&gt;&amp;</code> 设置阴影颜色<br>颜色代码要以十六进制填写，顺序是蓝、绿、红。注意这个顺序和 WEB颜色的顺序是相反的。颜色代码必须以&amp;H开头，以&amp;结尾。</p></li><li><p>设置透明度<br><code>\alpha&amp;H&lt;aa&gt;</code> 一次设置以下4个部分的透明度。<br><code>\1a&amp;H&lt;aa&gt;</code> 设置主要填充透明度。<br><code>\2a&amp;H&lt;aa&gt;</code> 设置次要填充透明度<br><code>\3a&amp;H&lt;aa&gt;</code> 设置边框透明度。<br><code>\4a&amp;H&lt;aa&gt;</code> 设置阴影透明度。<br>alpha 值为00意味着完全不透明，而为FF（十进制的255）即为完全透明。</p></li></ol><hr><h2 id="t渐变的动画效果（重要）"><a href="#t渐变的动画效果（重要）" class="headerlink" title="t渐变的动画效果（重要）"></a>t渐变的动画效果（重要）</h2><p><code>\t(t1,t2,速度,特效标签)</code> 其中t1,t2和速度可省略</p><hr><h2 id="自动化相关"><a href="#自动化相关" class="headerlink" title="自动化相关"></a>自动化相关</h2><ol><li>\k 即karaoke</li><li>\r 重置样式，重置其后字符的样式，会让一切样式标签失效，包括动画效果</li></ol><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --&gt;&lt;p&gt;其实并不常做字幕特效，毕竟也基本上都是心血来潮自己完成全部的字幕任务，不过每次想做的时候总是记不住那些特效代码，翻帖子去找然后慢慢试效果，果然还是自己整理一个较常用的标签列表比较妥当&lt;/p&gt;&lt;p&gt;先贴一个&lt;strong&gt;完整&lt;/strong&gt;的&lt;a href=&quot;https://aegi.vmoe.info/docs/3.2/ASS_Tags/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;标签代码手册&lt;/a&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="Notes" scheme="https://blog8.flyky.org/categories/Notes/"/>
    
      <category term="ASS subtitle" scheme="https://blog8.flyky.org/categories/Notes/ASS-subtitle/"/>
    
    
      <category term="note" scheme="https://blog8.flyky.org/tags/note/"/>
    
      <category term="aegisub" scheme="https://blog8.flyky.org/tags/aegisub/"/>
    
      <category term="ASS字幕" scheme="https://blog8.flyky.org/tags/ASS%E5%AD%97%E5%B9%95/"/>
    
  </entry>
  
  <entry>
    <title>Data Structure - programming implementation</title>
    <link href="https://blog8.flyky.org/20180714/Data-Structure-programming-implementation/"/>
    <id>https://blog8.flyky.org/20180714/Data-Structure-programming-implementation/</id>
    <published>2018-07-14T15:42:23.000Z</published>
    <updated>2021-01-26T09:06:13.102Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --><p>来源于<em>大一数据结构上机课程的练习</em>，最近复习数据结构时候做个备份吧感觉当时写的还算很有心<br>有时间慢慢整理吧~</p><hr><p>标注OOP的话就是cpp面向对象实现的，没有的话就是普通的结构体<br>所有的structure实现都是头文件.h和.cpp实现操作，具体的测试main函数就不放出了，自行测试</p><a id="more"></a><h1 id="顺序表实现"><a href="#顺序表实现" class="headerlink" title="顺序表实现"></a>顺序表实现</h1><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//sqlist.h</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">ifndef</span> SQLIST</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> SQLIST</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> MaxSize 50</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">char</span> ElemType;</span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> &#123;</span></span><br><span class="line">ElemType data[MaxSize];</span><br><span class="line"><span class="keyword">int</span> length;</span><br><span class="line">&#125; SqList; <span class="comment">/**</span></span><br><span class="line"><span class="comment">*</span></span><br><span class="line"><span class="comment">*</span></span><br><span class="line"><span class="comment">*</span></span><br><span class="line"><span class="comment">**/</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">InitList</span><span class="params">(SqList * &amp;L)</span></span>; <span class="comment">//初始化顺序表</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">CreateList</span><span class="params">(SqList * &amp;L, ElemType a[], <span class="keyword">int</span> n)</span></span>; <span class="comment">//采用尾插法依次插入元素</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">DispList</span><span class="params">(SqList *L)</span></span>; <span class="comment">//打印线性表</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">ListLength</span><span class="params">(SqList *L)</span></span>; <span class="comment">//求线性表长度</span></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">isEmptyList</span><span class="params">(SqList *L)</span></span>; <span class="comment">//判断线性表是否为空表(空表则返回true)</span></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">GetElem</span><span class="params">(SqList *L, <span class="keyword">int</span> n, ElemType &amp;e)</span></span>; <span class="comment">//求线性表某位置的元素值,求得的值返回给e</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">LocateElem</span><span class="params">(SqList *L, ElemType e)</span></span>; <span class="comment">//求某值在线性表中的位置</span></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">InsertList</span><span class="params">(SqList * &amp;L, ElemType e, <span class="keyword">int</span> n)</span></span>; <span class="comment">//在线性表某位置插入元素</span></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">DeleteElem</span><span class="params">(SqList * &amp;L, <span class="keyword">int</span> n)</span></span>; <span class="comment">//删除线性表中某位置元素</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">DestroyList</span><span class="params">(SqList * &amp;L)</span></span>; <span class="comment">//释放线性表</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br></pre></td></tr></table></figure><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//sqlist.cpp</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"sqlist.h"</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;cstdlib&gt;</span></span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">InitList</span><span class="params">(SqList * &amp;L)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">L = (SqList *) <span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(SqList));</span><br><span class="line">L-&gt;length = <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">CreateList</span><span class="params">(SqList * &amp;L, ElemType a[], <span class="keyword">int</span> n)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>;i &lt; n; i++) &#123;</span><br><span class="line">L-&gt;data[i] = *(a+i);</span><br><span class="line">&#125;</span><br><span class="line">L-&gt;length = n;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">DispList</span><span class="params">(SqList *L)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; L-&gt;length; i++) &#123;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span>&lt;&lt; i+<span class="number">1</span> &lt;&lt;<span class="string">". "</span>&lt;&lt;L-&gt;data[i]&lt;&lt;<span class="string">"\n"</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span>&lt;&lt;<span class="string">"Finished!"</span>&lt;&lt;<span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">ListLength</span><span class="params">(SqList *L)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">return</span> L-&gt;length;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">isEmptyList</span><span class="params">(SqList *L)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">return</span> (L-&gt;length == <span class="number">0</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">GetElem</span><span class="params">(SqList *L, <span class="keyword">int</span> n, ElemType &amp;e)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">if</span> (n &lt; <span class="number">1</span> || L-&gt;length &lt; n) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"><span class="keyword">else</span> e = L-&gt;data[--n];</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">LocateElem</span><span class="params">(SqList *L, ElemType e)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">while</span>(i &lt; L-&gt;length &amp;&amp; e != L-&gt;data[i]) i++;</span><br><span class="line"><span class="keyword">if</span> (i &gt;= L-&gt;length) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"><span class="keyword">else</span> <span class="keyword">return</span> i+<span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">InsertList</span><span class="params">(SqList * &amp;L, ElemType e, <span class="keyword">int</span> n)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">if</span> (n &lt; <span class="number">1</span> || L-&gt;length+<span class="number">1</span> &lt; n) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">n--;</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">int</span> j = L-&gt;length; j &gt; n; j--) </span><br><span class="line">L-&gt;data[j] = L-&gt;data[j<span class="number">-1</span>];</span><br><span class="line">L-&gt;data[n] = e;</span><br><span class="line">L-&gt;length++;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">DeleteElem</span><span class="params">(SqList * &amp;L, <span class="keyword">int</span> n)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">if</span> (n &lt; <span class="number">1</span> || L-&gt;length &lt; n) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">n--;</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">int</span> j = n; j &lt; L-&gt;length<span class="number">-1</span>; j++) </span><br><span class="line">L-&gt;data[j] = L-&gt;data[j+<span class="number">1</span>];</span><br><span class="line">L-&gt;length--;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">DestroyList</span><span class="params">(SqList * &amp;L)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="built_in">free</span>(L);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="OOP-队列ADT顺序表实现-非循环"><a href="#OOP-队列ADT顺序表实现-非循环" class="headerlink" title="[OOP]队列ADT顺序表实现(非循环)"></a>[OOP]队列ADT顺序表实现(非循环)</h1><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//SequenceQueue.h</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">ifndef</span> SEQUENCEQUEUE</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> SEQUENCEQUEUE</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">char</span> ElemType;</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">SqQueue</span> &#123;</span> <span class="comment">/**</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment">  *[面向对象实现]队列ADT(顺序表实现)(非循环)</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment">  **/</span></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">  ElemType *data;</span><br><span class="line">  <span class="keyword">int</span> front;</span><br><span class="line">  <span class="keyword">int</span> rear;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">  SqQueue();</span><br><span class="line">  ~SqQueue();</span><br><span class="line">  <span class="function"><span class="keyword">bool</span> <span class="title">isEmptyQueue</span><span class="params">()</span></span>;</span><br><span class="line">  <span class="function"><span class="keyword">void</span> <span class="title">TraverseQueue</span><span class="params">()</span></span>;</span><br><span class="line">  <span class="function"><span class="keyword">int</span> <span class="title">QueueLength</span><span class="params">()</span></span>;</span><br><span class="line">  <span class="function"><span class="keyword">bool</span> <span class="title">GetFront</span><span class="params">(ElemType &amp;e)</span></span>;</span><br><span class="line">  <span class="function"><span class="keyword">bool</span> <span class="title">EnQueue</span><span class="params">(ElemType e)</span></span>;</span><br><span class="line">  <span class="function"><span class="keyword">bool</span> <span class="title">DeQueue</span><span class="params">(ElemType &amp;e)</span></span>;</span><br><span class="line">  <span class="function"><span class="keyword">void</span> <span class="title">CreateQueue</span><span class="params">()</span></span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br></pre></td></tr></table></figure><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//SequenceQueue.cpp</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"SequenceQueue.h"</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> MaxSize = <span class="number">50</span>;</span><br><span class="line"></span><br><span class="line">SqQueue::SqQueue() <span class="comment">//构造函数</span></span><br><span class="line">&#123;</span><br><span class="line">  data = <span class="keyword">new</span> ElemType[MaxSize];</span><br><span class="line">  front = rear = <span class="number">-1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">SqQueue::~SqQueue() <span class="comment">//析构函数</span></span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">delete</span> []data;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">bool</span> SqQueue::isEmptyQueue()</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">return</span> front == rear;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">void</span> SqQueue::TraverseQueue()</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">if</span> (<span class="keyword">this</span>-&gt;isEmptyQueue()) &#123;</span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"==-&gt; Queue is empty. &lt;-=="</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    <span class="keyword">return</span> ;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"\n==-- Now print the elements of the queue. --==\n"</span>;</span><br><span class="line"><span class="keyword">int</span> n = <span class="number">1</span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = front + <span class="number">1</span>; i != rear + <span class="number">1</span>; i++) &#123;</span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; n &lt;&lt; <span class="string">". "</span> &lt;&lt; *(data + i) &lt;&lt; <span class="string">"\t"</span>;</span><br><span class="line"><span class="keyword">if</span> (n%<span class="number">5</span> == <span class="number">0</span>) <span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"\n"</span>;</span><br><span class="line">n++;</span><br><span class="line">&#125; <span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"\n-- Traversal Print Finished! --"</span> &lt;&lt; <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"><span class="keyword">return</span> ;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> SqQueue::QueueLength()</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">return</span> rear - front;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">bool</span> SqQueue::GetFront(ElemType &amp;e)</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">if</span> (<span class="keyword">this</span>-&gt;isEmptyQueue()) &#123;</span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"\n==-&gt; ERROR. Queue is empty. &lt;-=="</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  e = *(data + front + <span class="number">1</span>);</span><br><span class="line">  <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">bool</span> SqQueue::EnQueue(ElemType e)</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">if</span> (rear + <span class="number">1</span> == MaxSize) &#123; <span class="comment">//队列满，上溢</span></span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; <span class="string">"\n==-&gt; ERROR.. Queue is full. &lt;-=="</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">&#125;</span><br><span class="line">  rear++;</span><br><span class="line">  *(data + rear) = e;</span><br><span class="line">  <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">bool</span> SqQueue::DeQueue(ElemType &amp;e)</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">if</span> (<span class="keyword">this</span>-&gt;isEmptyQueue()) &#123;</span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"\n==-&gt; ERROR. Queue is empty. &lt;-=="</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  front++;</span><br><span class="line">  e = *(data + front);</span><br><span class="line">  <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">void</span> SqQueue::CreateQueue()</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">if</span> (data == <span class="literal">NULL</span>) &#123;</span><br><span class="line">  <span class="built_in">cout</span> &lt;&lt; <span class="string">"\n==-- ERROR.Pointer is NULL --=="</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">  <span class="keyword">return</span> ;</span><br><span class="line">&#125;</span><br><span class="line">ElemType tmp;</span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; <span class="string">"\n  ========Now input the data of the Queue========\n"</span>;</span><br><span class="line">  <span class="built_in">cout</span>&lt;&lt;<span class="string">"--If you want to finish inputing, please input \"#\"--\n"</span>;</span><br><span class="line">  <span class="built_in">cout</span> &lt;&lt; <span class="string">"1. "</span>;</span><br><span class="line">  <span class="built_in">cin</span> &gt;&gt; tmp;</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">2</span>; tmp != <span class="string">'#'</span>; i++) &#123; <span class="comment">//结束标志为‘#’</span></span><br><span class="line">  <span class="keyword">if</span> (!<span class="keyword">this</span>-&gt;EnQueue(tmp)) &#123;</span><br><span class="line">  <span class="keyword">break</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="built_in">cout</span> &lt;&lt; i &lt;&lt; <span class="string">". "</span>;</span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; tmp;</span><br><span class="line">  &#125;</span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; <span class="string">"\n==--&lt; Finished input! &gt;--=="</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><h1 id="队列ADT顺序表实现-循环"><a href="#队列ADT顺序表实现-循环" class="headerlink" title="队列ADT顺序表实现(循环)"></a>队列ADT顺序表实现(循环)</h1><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//SequenceQueue.h</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">ifndef</span> SEQUENCEQUEUE</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> SEQUENCEQUEUE</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">char</span> ElemType;</span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">List</span> <span class="title">SqQueue</span>, *<span class="title">ptrSqQueue</span>;</span> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> *队列ADT(顺序表实现)(循环)</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> **/</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">InitQueue</span><span class="params">(ptrSqQueue &amp;Q)</span></span>; <span class="comment">//初始化队列，为队列分配内存，建立空队列</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">FreeQueue</span><span class="params">(ptrSqQueue &amp;Q)</span></span>; <span class="comment">//释放队列内存</span></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">isEmptyQueue</span><span class="params">(ptrSqQueue Q)</span></span>; <span class="comment">//判断队列是否为空，空则返回true</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">TraverseQueue</span><span class="params">(ptrSqQueue Q)</span></span>; <span class="comment">//遍历打印队列元素</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">QueueLength</span><span class="params">(ptrSqQueue Q)</span></span>; <span class="comment">//返回队列元素的个数</span></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">GetFront</span><span class="params">(ptrSqQueue Q, ElemType &amp;e)</span></span>; <span class="comment">//取队头元素，返回给e</span></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">EnQueue</span><span class="params">(ptrSqQueue Q, ElemType e)</span></span>; <span class="comment">//入队</span></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">DeQueue</span><span class="params">(ptrSqQueue Q, ElemType &amp;e)</span></span>; <span class="comment">//出队，删除的队头元素返回给e</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">CreateQueue</span><span class="params">(ptrSqQueue Q)</span></span>; <span class="comment">//交互式创建队列元素</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br></pre></td></tr></table></figure><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//SequenceQueue.cpp</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;cstdlib&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"SequenceQueue.h"</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> MaxSize 50</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">List</span> &#123;</span></span><br><span class="line">ElemType data[MaxSize];</span><br><span class="line"><span class="keyword">int</span> front; <span class="comment">//队头指针</span></span><br><span class="line"><span class="keyword">int</span> rear; <span class="comment">//队尾指针</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">InitQueue</span><span class="params">(ptrSqQueue &amp;Q)</span> <span class="comment">//初始化队列，为队列分配内存，建立空队列</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">Q = (ptrSqQueue)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(SqQueue));</span><br><span class="line">Q-&gt;front = Q-&gt;rear = <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">FreeQueue</span><span class="params">(ptrSqQueue &amp;Q)</span> <span class="comment">//释放队列内存</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="built_in">free</span>(Q);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">isEmptyQueue</span><span class="params">(ptrSqQueue Q)</span> <span class="comment">//判断队列是否为空，空则返回true</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">return</span> Q-&gt;rear == Q-&gt;front;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">TraverseQueue</span><span class="params">(ptrSqQueue Q)</span> <span class="comment">//遍历打印队列元素</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">if</span> (isEmptyQueue(Q)) &#123;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"==-&gt; Queue is empty. &lt;-=="</span> &lt;&lt; <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line">    <span class="keyword">return</span> ;</span><br><span class="line">  &#125;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"\n==-- Now print the elements of the queue. --==\n"</span>;</span><br><span class="line"><span class="keyword">int</span> n = <span class="number">1</span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = (Q-&gt;front + <span class="number">1</span>) % MaxSize; i != Q-&gt;rear + <span class="number">1</span>; ) &#123;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; n &lt;&lt; <span class="string">". "</span> &lt;&lt; Q-&gt;data[i] &lt;&lt; <span class="string">"\t"</span>;</span><br><span class="line"><span class="keyword">if</span> (n%<span class="number">5</span> == <span class="number">0</span>) <span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"\n"</span>;</span><br><span class="line">n++;</span><br><span class="line">i = (i + <span class="number">1</span>) % MaxSize;</span><br><span class="line">&#125; <span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"\n-- Traversal Print Finished! --"</span> &lt;&lt; <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"><span class="keyword">return</span> ;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">QueueLength</span><span class="params">(ptrSqQueue Q)</span> <span class="comment">//返回队列元素的个数</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">return</span> (Q-&gt;rear - Q-&gt;front + MaxSize) % MaxSize;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">GetFront</span><span class="params">(ptrSqQueue Q, ElemType &amp;e)</span> <span class="comment">//取队头元素，返回给e</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">if</span> (isEmptyQueue(Q)) &#123;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"\n==-&gt; ERROR.. Queue is empty. &lt;-=="</span> &lt;&lt; <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">  &#125;</span><br><span class="line">e = Q-&gt;data[(Q-&gt;front+<span class="number">1</span>)%MaxSize];</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">EnQueue</span><span class="params">(ptrSqQueue Q, ElemType e)</span> <span class="comment">//入队</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">if</span> ((Q-&gt;rear+<span class="number">1</span>)%MaxSize == Q-&gt;front) &#123; <span class="comment">//队列满，上溢</span></span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"\n==-&gt; ERROR.. Queue is full. &lt;-=="</span> &lt;&lt; <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">&#125;</span><br><span class="line">Q-&gt;rear = (Q-&gt;rear + <span class="number">1</span>) % MaxSize;</span><br><span class="line">Q-&gt;data[Q-&gt;rear] = e;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">DeQueue</span><span class="params">(ptrSqQueue Q, ElemType &amp;e)</span> <span class="comment">//出队，删除的队头元素返回给e</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">if</span> (isEmptyQueue(Q)) &#123;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"\n==-&gt; ERROR.. Queue is empty. &lt;-=="</span> &lt;&lt; <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">  &#125;</span><br><span class="line">Q-&gt;front = (Q-&gt;front + <span class="number">1</span>) % MaxSize;</span><br><span class="line">e = Q-&gt;data[Q-&gt;front];</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">CreateQueue</span><span class="params">(ptrSqQueue Q)</span> <span class="comment">//交互式创建队列元素</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">if</span> (Q == <span class="literal">NULL</span>) &#123;</span><br><span class="line">  <span class="built_in">std</span>::<span class="built_in">cout</span>&lt;&lt;<span class="string">"\n==-- ERROR.Pointer is NULL --=="</span>&lt;&lt;<span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line">  <span class="keyword">return</span>;</span><br><span class="line">&#125;</span><br><span class="line">ElemType tmp;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"\n  ========Now input the data of the STACK========\n"</span>;</span><br><span class="line">  <span class="built_in">std</span>::<span class="built_in">cout</span>&lt;&lt;<span class="string">"--If you want to finish inputing, please input \"#\"--\n"</span>;</span><br><span class="line">  <span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"1. "</span>;</span><br><span class="line">  <span class="built_in">std</span>::<span class="built_in">cin</span> &gt;&gt; tmp;</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">2</span>; tmp != <span class="string">'#'</span>; i++) &#123; <span class="comment">//结束标志为‘#’</span></span><br><span class="line">  <span class="keyword">if</span> (!EnQueue(Q, tmp)) &#123;</span><br><span class="line">  <span class="keyword">break</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; i &lt;&lt; <span class="string">". "</span>;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cin</span> &gt;&gt; tmp;</span><br><span class="line">  &#125;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"\n==--&lt; Finished input! &gt;--=="</span> &lt;&lt; <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="队列ADT链表实现"><a href="#队列ADT链表实现" class="headerlink" title="队列ADT链表实现"></a>队列ADT链表实现</h1><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//LinkQueue.h</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">ifndef</span> LINKQUEUE</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> LINKQUEUE</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">char</span> ElemType;</span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">node</span> <span class="title">QueueNode</span>, *<span class="title">ptrQueueNode</span>;</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">ptr_of_queue</span> <span class="title">LinkQueue</span>, *<span class="title">ptrLinkQueue</span>;</span><span class="comment">/**</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> *队列ADT(链表实现)</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> **/</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">InitQueue</span><span class="params">(ptrLinkQueue &amp;Q)</span></span>; <span class="comment">//初始化队列，为队列指针分配内存，建立空队</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">FreeQueue</span><span class="params">(ptrLinkQueue &amp;Q)</span></span>; <span class="comment">//释放队列内存</span></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">isEmptyQueue</span><span class="params">(ptrLinkQueue Q)</span></span>; <span class="comment">//判断队列是否为空，空则返回true</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">TraverseQueue</span><span class="params">(ptrLinkQueue Q)</span></span>; <span class="comment">//遍历打印队列元素</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">QueueLength</span><span class="params">(ptrLinkQueue Q)</span></span>; <span class="comment">//返回队列元素的个数</span></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">GetFront</span><span class="params">(ptrLinkQueue Q, ElemType &amp;e)</span></span>; <span class="comment">//取队头元素，返回给e</span></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">EnQueue</span><span class="params">(ptrLinkQueue Q, ElemType e)</span></span>; <span class="comment">//入队</span></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">DeQueue</span><span class="params">(ptrLinkQueue Q, ElemType &amp;e)</span></span>; <span class="comment">//出队，删除的队头元素返回给e</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">CreateQueue</span><span class="params">(ptrLinkQueue Q)</span></span>; <span class="comment">//交互式创建队列元素</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br></pre></td></tr></table></figure><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//LinkQueue.cpp</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;cstdlib&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"LinkQueue.h"</span></span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">node</span> &#123;</span></span><br><span class="line">ElemType data;</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">node</span> *<span class="title">next</span>;</span></span><br><span class="line">&#125;;</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ptr_of_queue</span> &#123;</span></span><br><span class="line">ptrQueueNode front;</span><br><span class="line">ptrQueueNode rear;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">InitQueue</span><span class="params">(ptrLinkQueue &amp;Q)</span> <span class="comment">//初始化队列，为队列指针分配内存，建立空队</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">Q = (ptrLinkQueue)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(LinkQueue));</span><br><span class="line">Q-&gt;front = Q-&gt;rear = <span class="literal">NULL</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">FreeQueue</span><span class="params">(ptrLinkQueue &amp;Q)</span> <span class="comment">//释放队列内存</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">ptrQueueNode p = Q-&gt;front, r;</span><br><span class="line"><span class="keyword">if</span> (p != <span class="literal">NULL</span>) &#123;</span><br><span class="line">r = p-&gt;next;</span><br><span class="line"><span class="keyword">while</span> (r != <span class="literal">NULL</span>) &#123;</span><br><span class="line"><span class="built_in">free</span>(p);</span><br><span class="line">p = r; r = p-&gt;next;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">free</span>(p);</span><br><span class="line"><span class="built_in">free</span>(Q);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">isEmptyQueue</span><span class="params">(ptrLinkQueue Q)</span> <span class="comment">//判断队列是否为空，空则返回true</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">return</span> Q-&gt;rear == <span class="literal">NULL</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">TraverseQueue</span><span class="params">(ptrLinkQueue Q)</span> <span class="comment">//遍历打印队列元素</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">ptrQueueNode p = Q-&gt;front;</span><br><span class="line"><span class="keyword">if</span> (p == <span class="literal">NULL</span>)</span><br><span class="line">&#123;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span>&lt;&lt;<span class="string">"\n==--&gt; The Queue is Empty. &lt;--=="</span>&lt;&lt;<span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"><span class="keyword">return</span> ;</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span>&lt;&lt;<span class="string">"\n==-- Now print the elements of the QUEUE. --==\n"</span>;</span><br><span class="line"><span class="keyword">int</span> i = <span class="number">1</span>;</span><br><span class="line"><span class="keyword">while</span> (p!=<span class="literal">NULL</span>) &#123;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span>&lt;&lt; i &lt;&lt; <span class="string">". "</span> &lt;&lt; p-&gt;data &lt;&lt; <span class="string">"\t"</span>;</span><br><span class="line">p = p-&gt;next;</span><br><span class="line"><span class="keyword">if</span> (i%<span class="number">5</span> == <span class="number">0</span>) <span class="built_in">std</span>::<span class="built_in">cout</span>&lt;&lt;<span class="string">"\n"</span>;</span><br><span class="line">i++;</span><br><span class="line">&#125; <span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"\n-- Traversal Print Finished! --"</span> &lt;&lt; <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"><span class="keyword">return</span> ;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">QueueLength</span><span class="params">(ptrLinkQueue Q)</span> <span class="comment">//返回队列元素的个数</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">int</span> l = <span class="number">0</span>;</span><br><span class="line">ptrQueueNode p = Q-&gt;front;</span><br><span class="line"><span class="keyword">while</span> (p != <span class="literal">NULL</span>) &#123;</span><br><span class="line">l++;</span><br><span class="line">p = p-&gt;next;</span><br><span class="line">&#125; <span class="keyword">return</span> l;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">GetFront</span><span class="params">(ptrLinkQueue Q, ElemType &amp;e)</span> <span class="comment">//取队头元素，返回给e</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">if</span> (isEmptyQueue(Q))</span><br><span class="line">&#123;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span>&lt;&lt;<span class="string">"==--&lt; ERROR.Empty Queue. &gt;--=="</span>&lt;&lt;<span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">&#125;</span><br><span class="line">e = Q-&gt;front-&gt;data;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">EnQueue</span><span class="params">(ptrLinkQueue Q, ElemType e)</span> <span class="comment">//入队</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">if</span> (Q==<span class="literal">NULL</span>)</span><br><span class="line">&#123;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span>&lt;&lt;<span class="string">"--&lt; ERROR!The pointer is NULL. &gt;--"</span>&lt;&lt;<span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">&#125;</span><br><span class="line">ptrQueueNode tmpNode;</span><br><span class="line">tmpNode = (ptrQueueNode)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(QueueNode));</span><br><span class="line">tmpNode-&gt;data = e;</span><br><span class="line">tmpNode-&gt;next = <span class="literal">NULL</span>;</span><br><span class="line"><span class="keyword">if</span> (isEmptyQueue(Q)) Q-&gt;front = Q-&gt;rear = tmpNode;</span><br><span class="line"><span class="keyword">else</span> &#123;</span><br><span class="line">Q-&gt;rear-&gt;next = tmpNode;</span><br><span class="line">Q-&gt;rear = tmpNode;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">DeQueue</span><span class="params">(ptrLinkQueue Q, ElemType &amp;e)</span> <span class="comment">//出队，删除的队头元素返回给e</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">if</span> (Q==<span class="literal">NULL</span>)</span><br><span class="line">&#123;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span>&lt;&lt;<span class="string">"--&lt; ERROR!The pointer is NULL. &gt;--"</span>&lt;&lt;<span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> (isEmptyQueue(Q))</span><br><span class="line">&#123;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span>&lt;&lt;<span class="string">"==--&lt; ERROR.Empty Queue. &gt;--=="</span>&lt;&lt;<span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">&#125;</span><br><span class="line">ptrQueueNode t;</span><br><span class="line">t = Q-&gt;front;</span><br><span class="line"><span class="keyword">if</span> (Q-&gt;front == Q-&gt;rear) Q-&gt;front = Q-&gt;rear = <span class="literal">NULL</span>;</span><br><span class="line"><span class="keyword">else</span> Q-&gt;front = t-&gt;next;</span><br><span class="line">e = t-&gt;data;</span><br><span class="line"><span class="built_in">free</span>(t);</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">CreateQueue</span><span class="params">(ptrLinkQueue Q)</span> <span class="comment">//交互式创建队列元素</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">if</span> (Q==<span class="literal">NULL</span>)</span><br><span class="line">&#123;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span>&lt;&lt;<span class="string">"--&lt; ERROR!The pointer is NULL. &gt;--"</span>&lt;&lt;<span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"><span class="keyword">return</span> ;</span><br><span class="line">&#125;</span><br><span class="line">ElemType tmp;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"\n  ========Now input the data of the QUEUE========\n"</span>;</span><br><span class="line">  <span class="built_in">std</span>::<span class="built_in">cout</span>&lt;&lt;<span class="string">"--If you want to finish inputing, please input \"#\"--\n"</span>;</span><br><span class="line">  <span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"1. "</span>;</span><br><span class="line">  <span class="built_in">std</span>::<span class="built_in">cin</span> &gt;&gt; tmp;</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">2</span>; tmp != <span class="string">'#'</span>; i++) &#123; <span class="comment">//结束标志为‘#’</span></span><br><span class="line">  <span class="keyword">if</span> (!EnQueue(Q, tmp)) <span class="keyword">break</span>;</span><br><span class="line">  <span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; i &lt;&lt; <span class="string">". "</span>;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cin</span> &gt;&gt; tmp;</span><br><span class="line"> &#125;</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">cout</span> &lt;&lt; <span class="string">"\n==--&lt; Finished input! &gt;--=="</span> &lt;&lt; <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --&gt;&lt;p&gt;来源于&lt;em&gt;大一数据结构上机课程的练习&lt;/em&gt;，最近复习数据结构时候做个备份吧感觉当时写的还算很有心&lt;br&gt;有时间慢慢整理吧~&lt;/p&gt;&lt;hr&gt;&lt;p&gt;标注OOP的话就是cpp面向对象实现的，没有的话就是普通的结构体&lt;br&gt;所有的structure实现都是头文件.h和.cpp实现操作，具体的测试main函数就不放出了，自行测试&lt;/p&gt;
    
    </summary>
    
      <category term="Notes" scheme="https://blog8.flyky.org/categories/Notes/"/>
    
      <category term="Data Structure" scheme="https://blog8.flyky.org/categories/Notes/Data-Structure/"/>
    
    
      <category term="note" scheme="https://blog8.flyky.org/tags/note/"/>
    
      <category term="programming" scheme="https://blog8.flyky.org/tags/programming/"/>
    
      <category term="Data Structure" scheme="https://blog8.flyky.org/tags/Data-Structure/"/>
    
  </entry>
  
  <entry>
    <title>koa-multer插件的食用尝试</title>
    <link href="https://blog8.flyky.org/20180707/koa-multer_plugin_taste/"/>
    <id>https://blog8.flyky.org/20180707/koa-multer_plugin_taste/</id>
    <published>2018-07-06T18:00:46.000Z</published>
    <updated>2021-01-26T09:06:13.106Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --><p>学习koa框架时考虑到了一个问题，有关上传文件的实现<br>搜到了koa-multer这个可以直接用在koa的中间件，于是着手尝试食用</p><a id="more"></a><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --&gt;&lt;p&gt;学习koa框架时考虑到了一个问题，有关上传文件的实现&lt;br&gt;搜到了koa-multer这个可以直接用在koa的中间件，于是着手尝试食用&lt;/p&gt;
    
    </summary>
    
      <category term="Tech" scheme="https://blog8.flyky.org/categories/Tech/"/>
    
      <category term="node" scheme="https://blog8.flyky.org/categories/Tech/node/"/>
    
      <category term="koa" scheme="https://blog8.flyky.org/categories/Tech/node/koa/"/>
    
    
      <category term="node" scheme="https://blog8.flyky.org/tags/node/"/>
    
      <category term="koa" scheme="https://blog8.flyky.org/tags/koa/"/>
    
  </entry>
  
  <entry>
    <title>大数据学习笔记| Hadoop - Hadoop伪分布式环境搭建</title>
    <link href="https://blog8.flyky.org/20170928/notes_of_big_data_study-Hadoop-Fdistributed-build/"/>
    <id>https://blog8.flyky.org/20170928/notes_of_big_data_study-Hadoop-Fdistributed-build/</id>
    <published>2017-09-27T17:51:25.000Z</published>
    <updated>2021-01-26T09:06:13.107Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --><h1 id="说说「伪分布式」"><a href="#说说「伪分布式」" class="headerlink" title="说说「伪分布式」"></a>说说「伪分布式」</h1><p>Hadoop的安装配置方式有三种：单机、伪分布式和完全分布式。<br><br><strong>单机模式</strong> 顾名思义，只在一台单机上运行，不需要与其他节点交互，不使用HDFS分布式文件系统，不加载Hadoop的守护进程。当你解压了hadoop的软件包后的默认最小模式，各种配置为空。<br><br><strong>完全分布式</strong> 需要在至少3台机器上配置hadoop节点，真正分布式地完成存储和计算任务。<br><br><strong>伪分布式</strong> 也很好理解，即在单机上搭建分布式系统。虽然是在单机上运行，但是通过配置实现用不同的Java进程模仿分布式运行的各类节点，即在一个机器上，既有namenode也有datanode，既有jobtracker也有tasktracker。既然并没有在多台机器上真正的搭建分布式环境，所以称之为「伪分布式」。<br><br><br></p><h1 id="安装环境"><a href="#安装环境" class="headerlink" title="安装环境"></a>安装环境</h1><p>Hadoop需要安装在Linux环境下（当然macos也可以），无论是物理机linux或是虚拟机Linux均可，发行版本无所谓，我这里&gt;使用的是ubuntu16.04 server,安装的Hadoop版本为2.8.1<br><br></p><a id="more"></a><h1 id="创建用户与修改hostname"><a href="#创建用户与修改hostname" class="headerlink" title="创建用户与修改hostname"></a>创建用户与修改hostname</h1><p><del><em style="color:red">这一步对于伪分布式来说必要性不大，可以省略。如果是完全分布式的话还是有必要的。</em></del></p><h2 id="创建新用户"><a href="#创建新用户" class="headerlink" title="创建新用户"></a>创建新用户</h2><p><em>假设创建一个名为“hadoop”的用户</em></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">useradd -m hadoop -s /bin/bash</span><br></pre></td></tr></table></figure><p>这里稍微解释一下。-m 选项表示在创建用户的同时，新建该用户的主目录（例子中是/home/hadoop目录）；-s选项设置用户<br>登录的shell，例子中使用bash，如果你使用其他shell，如zsh则改为/bin/zsh<br>接着使用passwd命令更改hadoop用户密码</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">passwd hadoop</span><br></pre></td></tr></table></figure><p>输两次密码即可（弱口令也可以，确认使用即可）</p><h2 id="修改Hostname"><a href="#修改Hostname" class="headerlink" title="修改Hostname"></a>修改Hostname</h2><p>修改存放主机名的hostname文件即可<br>需要注意的是，不同的linux发行版本，主机名的配置文件不同<br>ubuntu为 /etc/hostname 文件, centos为 /etc/sysconfig/network 文件<br>修改对应hostname字段即可</p><p><em>这里假设该主机的hostname为Master</em></p><h1 id="jdk安装与配置"><a href="#jdk安装与配置" class="headerlink" title="jdk安装与配置"></a>jdk安装与配置</h1><h2 id="第一步-安装"><a href="#第一步-安装" class="headerlink" title="第一步. 安装"></a>第一步. 安装</h2><h3 id="可以使用软件包管理安装openjdk"><a href="#可以使用软件包管理安装openjdk" class="headerlink" title="可以使用软件包管理安装openjdk"></a>可以使用软件包管理安装openjdk</h3><p>比如Debian系可以使用apt-get，redhat系可以使用yum，arch linux可以使用pacman,yaourt等前端<br>这里以ubuntu举例</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get install openjdk-8-jre</span><br><span class="line">sudo apt-get install openjdk-8-jdk</span><br></pre></td></tr></table></figure><p>具体安装命令请移步链接<a href="http://openjdk.java.net/install/index.html" target="_blank" rel="noopener">http://openjdk.java.net/install/index.html</a></p><h3 id="Oracle官网下载jdk安装"><a href="#Oracle官网下载jdk安装" class="headerlink" title="Oracle官网下载jdk安装"></a>Oracle官网下载jdk安装</h3><p><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" target="_blank" rel="noopener">Java SE Downloads</a><br>在oracle官网里下载对应系统版本的jdk<br><img src="https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/1hadoop-orajdk.webp" alt="1hadoop-orajdk" title="Oracle_jdk-download"></p><h2 id="第二步-配置jdk环境变量"><a href="#第二步-配置jdk环境变量" class="headerlink" title="第二步. 配置jdk环境变量"></a>第二步. 配置jdk环境变量</h2><p>环境变量配置文件可以是/etc/profile 、 ~/.profile 、 ~/.bash_profile等其一均可<br>使用nano、vim等编辑器打开配置文件(注意sudo权限)，在文件末尾添加如下export配置</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">export</span> JAVA_HOME=/usr/lib/java/jdk1.8.0_144</span><br><span class="line"><span class="built_in">export</span> JRE_HOME=<span class="variable">$JAVA_HOME</span>/jre</span><br><span class="line"><span class="built_in">export</span> CLASSPATH=.:<span class="variable">$JAVA_HOME</span>/lib/dt.jar:<span class="variable">$JAVA_HOME</span>/lib/tools.jar</span><br><span class="line"><span class="built_in">export</span> PATH=<span class="variable">$PATH</span>:<span class="variable">$JAVA_HOME</span>/bin:<span class="variable">$JRE_HOME</span>/bin</span><br></pre></td></tr></table></figure><p>注意你的JAVA_HOME的值要改成你所安装释放jdk的根目录（我这里将jdk安装在了/usr/lib/java目录下）<br>如果你是通过软件包管理安装openjdk 默认的安装根目录应该在/usr/lib/jvm/java-8-openjdk-adm64类似的目录位置，自己根据实际情况而变<br><br><br>编辑过profile配置文件之后需要通过.(点）命令或者source命令将配置应用到当前shell环境中</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">.   /etc/profile</span><br></pre></td></tr></table></figure>或者<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">source</span> /etc/profile</span><br></pre></td></tr></table></figure><p>结束后可以尝试执行java和javac命令，看看是否配置成功<br><br></p><h1 id="SSH-server密钥对登录配置-（所谓的免密登录）"><a href="#SSH-server密钥对登录配置-（所谓的免密登录）" class="headerlink" title="SSH server密钥对登录配置 （所谓的免密登录）"></a>SSH server密钥对登录配置 （所谓的免密登录）</h1><p>这一步是为了集群所在主机的安全性。。。。。<br><br>好吧其实果然还是因为，免密登录会很方便啊，否则每次hadoop登录都要输密码，一输就是要输好几次，会疯的！ 不过安全性确实很重要~<br><br></p><h2 id="安装ssh-server（sshd）服务"><a href="#安装ssh-server（sshd）服务" class="headerlink" title="安装ssh server（sshd）服务"></a>安装ssh server（sshd）服务</h2><p>因为大部分linux发行版，ssh client都是装好的,所以只需要安装server即可(执行一下ssh命令 如果提示找不到命令之类的错误那就是没有client啊~)<br><br>毋庸置疑使用软件包管理前端进行安装，这里同openjdk的安装，我使用的ubuntu使用apt-get命令安装openssh-server，其他的发行版本视自身情况而定。<br></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"> sudo apt-get install openssh-server</span><br><span class="line"></span><br><span class="line"><span class="comment">#如果没有client则执行以下命令安装openssh-client</span></span><br><span class="line"> sudo apt-get install openssh-client</span><br></pre></td></tr></table></figure><h2 id="生成公私钥并配置免密登录"><a href="#生成公私钥并配置免密登录" class="headerlink" title="生成公私钥并配置免密登录"></a>生成公私钥并配置免密登录</h2><p>使用ssh-keygen命令生成密钥对</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">ssh-keygen -t rsa </span><br><span class="line"><span class="comment">#或者</span></span><br><span class="line">ssh-keygen -t dsa</span><br></pre></td></tr></table></figure><p>之后一直回车（默认）即可<br><br><br>操作结束后会在~/.ssh目录下生成一对public-private key pair<br>id_rsa，id_rsa.pub或者id_dsa，id_dsa.pub ，前者私钥 后者公钥</p><div class="note success"><p>公钥与私钥的关系大概可以这样描述<br>假设A免密登录B（即B为被登陆端）<br>B主机的<code>~/.ssh</code>目录下必须有名为<code>authorized_keys</code>（可以更改sshd的配置文件更改该文件名）的公钥列表文件，里面一行表示一个公钥，只要有这个公钥列表里的某个公钥的对应私钥，就可以通过这个私钥来登录B主机，而如果对应的私钥在A主机的<code>~/.ssh</code>目录里，就可以直接免密登录<br>A主机通过对应的私钥可以免密登录B主机，可以将对应的公钥内容添加进B主机的<code>authorized_keys</code>文件，或者ssh命令的 -i 选项设定可以使用的对应私钥</p></div><p>接下来将pub公钥内容添加到被登陆主机的 ~/.ssh 目录即可<br>因为这里伪分布式是自己登录自己，所以直接改名为authorized_keys即可</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cat id_dsa.pub &gt;&gt; ~/.ssh/authorized_keys</span><br></pre></td></tr></table></figure><p>哦差点忘了 看看你公钥文件和.ssh目录的权限</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#.ssh目录权限700</span></span><br><span class="line"> chmod 700 -R ~/.ssh</span><br><span class="line"><span class="comment">#公钥列表文件600</span></span><br><span class="line"> chmod 600 authorized_keys</span><br></pre></td></tr></table></figure><p>此时使用</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh localhost</span><br></pre></td></tr></table></figure>命令，不需要密码便可以登陆了<p></p><h1 id="Hadoop安装与配置"><a href="#Hadoop安装与配置" class="headerlink" title="Hadoop安装与配置"></a>Hadoop安装与配置</h1><h2 id="Hadoop的安装"><a href="#Hadoop的安装" class="headerlink" title="Hadoop的安装"></a>Hadoop的安装</h2><p><img src="%5B/images/2hadoop-officialsite.png%5D(https://flyky1m-1251689806.cos.ap-guangzhou.myqcloud.com/blog8/2hadoop-officialsite.webp)" alt="2hadoop-officialsite" title="Apache Hadoop Official Site"><a href="http://hadoop.apache.org" target="_blank" rel="noopener">Hadoop官网</a>下载hadoop release binary包<br>将binary包解压到你所要安装hadoop的路径目录（本例将hadoop释放到/usr/local目录下）</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo tar -zxvf hadoop-2.8.1.tar.gz -C /usr/<span class="built_in">local</span></span><br></pre></td></tr></table></figure><p><strong><em>建议将解压后的hadoop-2.8.1目录重命名为hadoop，以方便操作</em></strong><br>解压完之后的hadoop命令已经可以使用,使用hadoop version命令查看当前hadoop版本</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/usr/<span class="built_in">local</span>/hadoop/bin/hadoop version</span><br></pre></td></tr></table></figure><p>此时的Hadoop便是最小单机模式，因为并没有对节点等进行配置</p><p><strong>在这里要将解压的hadoop目录的权限更改，更改所有者为当前用户，否则之后的一些操作可能会出现权限问题</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> /usr/<span class="built_in">local</span></span><br><span class="line">sudo chown -R hadoop:hadoop hadoop</span><br></pre></td></tr></table></figure><p>执行ls -l之后可以看到hadoop的目录变为了当前用户（本例中为hadoop用户）</p><p>为了方便使用hadoop等命令，建议将hadoop/bin目录添加到系统环境变量PATH中（过程同配置jdk环境变量）<br>配置系统配置文件（/etc/profile、<del>/.bashrc、</del>/.profile等均可）<br>添加下列语句</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">export</span> HADOOP_HOME=/usr/<span class="built_in">local</span>/hadoop</span><br><span class="line"><span class="built_in">export</span> PATH=<span class="variable">$HADOOP_HOME</span>/bin:<span class="variable">$HADOOP_HOME</span></span><br></pre></td></tr></table></figure><p>保存退出编辑器后使用.(点命令)或source命令将更改应用到当前shell</p><h2 id="Hadoop集群配置（伪分布式）"><a href="#Hadoop集群配置（伪分布式）" class="headerlink" title="Hadoop集群配置（伪分布式）"></a>Hadoop集群配置（伪分布式）</h2><p>我们需要配置hadoop的配置文件来搭建伪分布式环境<br>Hadoop的配置文件存放在hadoop/etc/hadoop/目录下</p><p>需要配置的配置文件如下</p><ol><li><p>hadoop-env.sh<br>在该配置文件中，建议修改其中JAVA_HOME项为jdk安装的绝对地址</p></li><li><p>core-site.xml<br>在该配置文件中，主要需要配置两个配置项<br><strong>fs.defaultFS和hadoop.tmp.dir</strong></p><p>编辑器打开配置文件后会发现一对configuration标签，在该标签内添加如下配置</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">configuration</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- 从这里开始配置 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">name</span>&gt;</span>fs.defaultFS<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">value</span>&gt;</span>hdfs://master:9000<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">name</span>&gt;</span>hadoop.tmp.dir<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">value</span>&gt;</span>file:/usr/local/hadoop/tmp<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- 配置结束 --&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">configuration</span>&gt;</span></span><br></pre></td></tr></table></figure><hr><div class="note warning"><p><strong style="color:red;font-size:1.5em">关于以下xml配置文件的配置说明</strong><br>下面的配置基本都是xml文件，配置项均配置在configuration标签内的property标签<br>property标签内，配置项名称（键）括在name标签内，配置的值括在value标签内，具体如下</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">configuration</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">name</span>&gt;</span>###<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>###<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">configuration</span>&gt;</span></span><br><span class="line">        </span><br></pre></td></tr></table></figure>以下的配置项，基本的配置项会将xml直接贴出以供参考（复制）方便食用；其他的配置项会以<span style="background-color:#06F;color:#fff;font-weight:2px;margin:0 2px;padding:1px 3px">name：value</span>键值对的形式贴出，如有用到可以直接套进以上的“模板”食用</div></li><li><p>hdfs-site.xml</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">configuration</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- 从这里开始配置 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">name</span>&gt;</span>dfs.namenode.secondary.http-address<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">value</span>&gt;</span>master:50090<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">name</span>&gt;</span>dfs.replication<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">value</span>&gt;</span>1<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">name</span>&gt;</span>dfs.namenode.name.dir<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">value</span>&gt;</span>file:/usr/local/hadoop/tmp/dfs/name<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">name</span>&gt;</span>dfs.datanode.data.dir<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">value</span>&gt;</span>file:/usr/local/hadoop/tmp/dfs/data<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- 配置结束 --&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">configuration</span>&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>mapred-site.xml (template)<br>在目录下并无mapred-site.xml文件，但是奇怪的是有一个mapred-site.xml.template的模板？文件<br>于是我们将mapred-site.xml.template复制成mapred-site.xml再在该文件内进行配置</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">configuration</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- 从这里开始配置 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">name</span>&gt;</span>mapreduce.framework.name<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">value</span>&gt;</span>yarn<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">name</span>&gt;</span>mapreduce.jobhistory.address<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">value</span>&gt;</span>10020<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">name</span>&gt;</span>mapreduce.jobhistory.webapp.address<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">value</span>&gt;</span>19888<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- 配置结束 --&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">configuration</span>&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>yarn-site.xml</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">configuration</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- 从这里开始配置 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">name</span>&gt;</span>yarn.resourcemanager.hostname<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">value</span>&gt;</span>Master<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">name</span>&gt;</span>yarn.nodemanager.aux-services<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">value</span>&gt;</span>mapreduce_shuffle<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- 配置结束 --&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">configuration</span>&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>slaves<br><del>嘛，因为是伪分布式，这个就不需要配置了</del></p></li></ol><h2 id="格式化Namenode"><a href="#格式化Namenode" class="headerlink" title="格式化Namenode"></a>格式化Namenode</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hdfs namenode -format</span><br></pre></td></tr></table></figure><p>格式化namenode成功的话，会看到 “successfully formatted” 和 “Exitting with status 0” 的提示，若为 “Exitting with status 1” 或抛出异常则是出错，检查配置文件后需要删除tmp目录并重新格式化</p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --&gt;&lt;h1 id=&quot;说说「伪分布式」&quot;&gt;&lt;a href=&quot;#说说「伪分布式」&quot; class=&quot;headerlink&quot; title=&quot;说说「伪分布式」&quot;&gt;&lt;/a&gt;说说「伪分布式」&lt;/h1&gt;&lt;p&gt;Hadoop的安装配置方式有三种：单机、伪分布式和完全分布式。&lt;br&gt;&lt;br&gt;&lt;strong&gt;单机模式&lt;/strong&gt; 顾名思义，只在一台单机上运行，不需要与其他节点交互，不使用HDFS分布式文件系统，不加载Hadoop的守护进程。当你解压了hadoop的软件包后的默认最小模式，各种配置为空。&lt;br&gt;&lt;br&gt;&lt;strong&gt;完全分布式&lt;/strong&gt; 需要在至少3台机器上配置hadoop节点，真正分布式地完成存储和计算任务。&lt;br&gt;&lt;br&gt;&lt;strong&gt;伪分布式&lt;/strong&gt; 也很好理解，即在单机上搭建分布式系统。虽然是在单机上运行，但是通过配置实现用不同的Java进程模仿分布式运行的各类节点，即在一个机器上，既有namenode也有datanode，既有jobtracker也有tasktracker。既然并没有在多台机器上真正的搭建分布式环境，所以称之为「伪分布式」。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;h1 id=&quot;安装环境&quot;&gt;&lt;a href=&quot;#安装环境&quot; class=&quot;headerlink&quot; title=&quot;安装环境&quot;&gt;&lt;/a&gt;安装环境&lt;/h1&gt;&lt;p&gt;Hadoop需要安装在Linux环境下（当然macos也可以），无论是物理机linux或是虚拟机Linux均可，发行版本无所谓，我这里&amp;gt;使用的是ubuntu16.04 server,安装的Hadoop版本为2.8.1&lt;br&gt;&lt;br&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="Tech" scheme="https://blog8.flyky.org/categories/Tech/"/>
    
      <category term="BigData" scheme="https://blog8.flyky.org/categories/Tech/BigData/"/>
    
      <category term="Hadoop" scheme="https://blog8.flyky.org/categories/Tech/BigData/Hadoop/"/>
    
    
      <category term="note" scheme="https://blog8.flyky.org/tags/note/"/>
    
      <category term="hadoop" scheme="https://blog8.flyky.org/tags/hadoop/"/>
    
      <category term="bigdata" scheme="https://blog8.flyky.org/tags/bigdata/"/>
    
  </entry>
  
  <entry>
    <title>大数据学习笔记| Hadoop - Hadoop概述</title>
    <link href="https://blog8.flyky.org/20170927/notes_of_big_data_study-HadoopAbstract/"/>
    <id>https://blog8.flyky.org/20170927/notes_of_big_data_study-HadoopAbstract/</id>
    <published>2017-09-26T16:48:52.000Z</published>
    <updated>2021-01-26T09:06:13.107Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --><p>Hadoop作为Apache的一个顶级项目，开源实现了Google的MapReduce、GFS(Google File System)、Bigtable等核心技术，成为目前大数据技术领域的核心软件平台，围绕着hadoop的一系列工具促使了hadoop生态圈的迅速发展</p><p>随着web和移动互联网的高速发展，人们创造出的数据量越来越庞大，面对这些海量的数据和信息，如何存储如何处理，如何提取出用户想要了解的有价值的信息，这些问题的产生和解决，成为了大数据时代的重要的发展线索。<br>随着云计算的发展，大量的数据存储在了云端，人们寻求着高效存储与处理信息，并且低成本的解决方案。Hadoop的发展与应用无疑是诸多数据发掘者的不二之选。</p><a id="more"></a><p><strong>Hadoop是以HDFS（Hadoop Distributed File System）和MapReduce为核心，以及一些支持Hadoop的其他子项目的通用工具组成的分布式计算系统。</strong>主要用于海量数据的高效存储、管理和分析。HDFS具有高容错性、高伸缩性等优点，使得Hadoop可以分布式的部署在价格低廉的硬件设备上；而MapReduce分布式计算框架可以充分利用hadoop集群的威力高速运算和解析数据，无需了解分布式底层细节。这种结构实现了存储于计算的高度耦合，十分有利于面向数据的系统架构，因此已经成为大数据技术领域的标准。</p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --&gt;&lt;p&gt;Hadoop作为Apache的一个顶级项目，开源实现了Google的MapReduce、GFS(Google File System)、Bigtable等核心技术，成为目前大数据技术领域的核心软件平台，围绕着hadoop的一系列工具促使了hadoop生态圈的迅速发展&lt;/p&gt;&lt;p&gt;随着web和移动互联网的高速发展，人们创造出的数据量越来越庞大，面对这些海量的数据和信息，如何存储如何处理，如何提取出用户想要了解的有价值的信息，这些问题的产生和解决，成为了大数据时代的重要的发展线索。&lt;br&gt;随着云计算的发展，大量的数据存储在了云端，人们寻求着高效存储与处理信息，并且低成本的解决方案。Hadoop的发展与应用无疑是诸多数据发掘者的不二之选。&lt;/p&gt;
    
    </summary>
    
      <category term="Tech" scheme="https://blog8.flyky.org/categories/Tech/"/>
    
      <category term="BigData" scheme="https://blog8.flyky.org/categories/Tech/BigData/"/>
    
      <category term="Hadoop" scheme="https://blog8.flyky.org/categories/Tech/BigData/Hadoop/"/>
    
    
      <category term="note" scheme="https://blog8.flyky.org/tags/note/"/>
    
      <category term="hadoop" scheme="https://blog8.flyky.org/tags/hadoop/"/>
    
      <category term="bigdata" scheme="https://blog8.flyky.org/tags/bigdata/"/>
    
  </entry>
  
  <entry>
    <title>我的博客尝试</title>
    <link href="https://blog8.flyky.org/20170922/try_my_blog/"/>
    <id>https://blog8.flyky.org/20170922/try_my_blog/</id>
    <published>2017-09-21T17:38:50.000Z</published>
    <updated>2021-01-26T09:06:13.108Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --><p>Welcome to my blog space~<br>嘛一直就有做个博客的打算，之前站点只上线了简陋的『实验站』，本来打算自己来搭建博客框架，不过果然没有这个闲心，还是用别人成熟的开源框架吧。用了hexo纯粹是因为想用node<br><strong>这边就记一记写hexo博客的一些tips吧</strong></p><a id="more"></a><h1 id="手动截断文章（设置「阅读全文」）"><a href="#手动截断文章（设置「阅读全文」）" class="headerlink" title="手动截断文章（设置「阅读全文」）"></a>手动截断文章（设置「阅读全文」）</h1><p>直接在需要截断的位置添加 <code>&lt;!-- more --&gt;</code>标签即可</p><h1 id="加密博文"><a href="#加密博文" class="headerlink" title="加密博文"></a>加密博文</h1><h2 id="安装配置加密插件"><a href="#安装配置加密插件" class="headerlink" title="安装配置加密插件"></a>安装配置加密插件</h2><ul><li>首先安装加密插件<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install hexo-blog-encrypt</span><br></pre></td></tr></table></figure></li><li>然后在项目根目录下的 <code>_config.yml</code>文件里添加下面配置<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Security</span></span><br><span class="line"><span class="comment">##</span></span><br><span class="line"><span class="attr">encrypt:</span></span><br><span class="line"><span class="attr">    enable:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure>这样就可以使用加密插件了<h2 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h2>在需要加密的文章头部写入password<figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">---</span><br><span class="line">title: ~ frp内网穿透配置 ~</span><br><span class="line">date: 2018-12-06 19:07:02</span><br><span class="line">password: 0123456789</span><br><span class="line">abstract: Welcome to my blog, enter password to read.</span><br><span class="line">message: 该博文暂未完成，完成后将开放.</span><br><span class="line">---</span><br></pre></td></tr></table></figure></li></ul><p><em>这样就需要密码访问了</em></p><h1 id="压缩博文静态资源"><a href="#压缩博文静态资源" class="headerlink" title="压缩博文静态资源"></a>压缩博文静态资源</h1><h2 id="使用hexo-neat插件"><a href="#使用hexo-neat插件" class="headerlink" title="使用hexo-neat插件"></a>使用hexo-neat插件</h2><blockquote><p><a href="https://blog.csdn.net/lewky_liu/article/details/82432003" target="_blank" rel="noopener">使用hexo-neat插件压缩页面静态资源</a></p></blockquote><h2 id="使用gulp"><a href="#使用gulp" class="headerlink" title="使用gulp"></a>使用gulp</h2><ul><li>首先在项目根目录执行<code>npm install gulp -g</code> 安装gulp<br>安装好后执行<code>gulp -v</code>看一下gulp工具版本，当前版本是4，（因为gulp3和4在配置文件里的写法有写不同，可能会踩坑）</li><li>接下来在项目里安装4个模块，根目录执行<code>npm install gulp-htmlclean gulp-htmlmin gulp-minify-css gulp-uglify --save</code><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">gulp-imagemin@6.1.1</span><br><span class="line">gulp-htmlmin@5.0.1</span><br><span class="line">gulp-minify-css@1.2.4</span><br><span class="line">gulp-htmlclean@2.7.22</span><br><span class="line">gulp-uglify@3.0.2</span><br></pre></td></tr></table></figure></li></ul><ul><li><p>然后在项目根目录添加<code>gulpfile.js</code>文件，内容为</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line">  <span class="keyword">var</span> gulp = <span class="built_in">require</span>(<span class="string">'gulp'</span>);</span><br><span class="line"><span class="keyword">var</span> minifycss = <span class="built_in">require</span>(<span class="string">'gulp-minify-css'</span>);</span><br><span class="line"><span class="keyword">var</span> uglify = <span class="built_in">require</span>(<span class="string">'gulp-uglify'</span>);</span><br><span class="line"><span class="keyword">var</span> htmlmin = <span class="built_in">require</span>(<span class="string">'gulp-htmlmin'</span>);</span><br><span class="line"><span class="keyword">var</span> htmlclean = <span class="built_in">require</span>(<span class="string">'gulp-htmlclean'</span>);</span><br><span class="line"><span class="keyword">var</span> imagemin = <span class="built_in">require</span>(<span class="string">'gulp-imagemin'</span>);</span><br><span class="line"> </span><br><span class="line"><span class="comment">// 压缩html</span></span><br><span class="line">gulp.task(<span class="string">'minify-html'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> gulp.src(<span class="string">'./public/**/*.html'</span>)</span><br><span class="line">        .pipe(htmlclean())</span><br><span class="line">        .pipe(htmlmin(&#123;</span><br><span class="line">            removeComments: <span class="literal">true</span>,</span><br><span class="line">            minifyJS: <span class="literal">true</span>,</span><br><span class="line">            minifyCSS: <span class="literal">true</span>,</span><br><span class="line">            minifyURLs: <span class="literal">true</span>,</span><br><span class="line">        &#125;))</span><br><span class="line">        .pipe(gulp.dest(<span class="string">'./public'</span>))</span><br><span class="line">&#125;);</span><br><span class="line"><span class="comment">// 压缩css</span></span><br><span class="line">gulp.task(<span class="string">'minify-css'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> gulp.src(<span class="string">'./public/**/*.css'</span>)</span><br><span class="line">        .pipe(minifycss(&#123;</span><br><span class="line">            compatibility: <span class="string">'ie8'</span></span><br><span class="line">        &#125;))</span><br><span class="line">        .pipe(gulp.dest(<span class="string">'./public'</span>));</span><br><span class="line">&#125;);</span><br><span class="line"><span class="comment">// 压缩js</span></span><br><span class="line">gulp.task(<span class="string">'minify-js'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> gulp.src(<span class="string">'./public/js/**/*.js'</span>)</span><br><span class="line">        .pipe(uglify())</span><br><span class="line">        .pipe(gulp.dest(<span class="string">'./public'</span>));</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">//4.0以前的写法 </span></span><br><span class="line"><span class="comment">//gulp.task('default', [</span></span><br><span class="line">  <span class="comment">//  'minify-html', 'minify-css', 'minify-js'</span></span><br><span class="line"><span class="comment">//]);</span></span><br><span class="line"><span class="comment">//4.0以后的写法</span></span><br><span class="line"><span class="comment">// 执行 gulp 命令时执行的任务</span></span><br><span class="line">gulp.task(<span class="string">'default'</span>,gulp.series(gulp.parallel(<span class="string">'minify-html'</span>,<span class="string">'minify-css'</span>,<span class="string">'minify-js'</span>)));</span><br><span class="line">  </span><br></pre></td></tr></table></figure></li><li><p>之后每次生成部署的时候直接<code>hexo clean</code>，<code>hexo g &amp;&amp; gulp</code>， <code>hexo d</code>三部即可</p></li></ul><h1 id="相关博客教程"><a href="#相关博客教程" class="headerlink" title="相关博客教程"></a>相关博客教程</h1><p>懒得写了，直接上一些不错的链接吧</p><ul><li><a href="http://yearito.cn/categories/%E6%8A%80%E6%9C%AF/%E5%8D%9A%E5%AE%A2/" target="_blank" rel="noopener">http://yearito.cn/categories/技术/博客/</a></li><li><a href="http://www.cduyzh.com/hexo-settings-3/" target="_blank" rel="noopener">hexo搭建个人免费博客——自定义页面样式一</a></li></ul><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      &lt;!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --&gt;&lt;p&gt;Welcome to my blog space~&lt;br&gt;嘛一直就有做个博客的打算，之前站点只上线了简陋的『实验站』，本来打算自己来搭建博客框架，不过果然没有这个闲心，还是用别人成熟的开源框架吧。用了hexo纯粹是因为想用node&lt;br&gt;&lt;strong&gt;这边就记一记写hexo博客的一些tips吧&lt;/strong&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="Tech" scheme="https://blog8.flyky.org/categories/Tech/"/>
    
      <category term="hexo" scheme="https://blog8.flyky.org/categories/Tech/hexo/"/>
    
    
      <category term="hexo" scheme="https://blog8.flyky.org/tags/hexo/"/>
    
      <category term="memo" scheme="https://blog8.flyky.org/tags/memo/"/>
    
  </entry>
  
  <entry>
    <title>Hello World</title>
    <link href="https://blog8.flyky.org/20170922/hello-world/"/>
    <id>https://blog8.flyky.org/20170922/hello-world/</id>
    <published>2017-09-21T16:00:00.000Z</published>
    <updated>2021-01-26T09:06:13.106Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><!-- build time:Thu Jan 28 2021 10:51:38 GMT+0800 (GMT+08:00) --><p>Welcome to <a href="https://hexo.io/" target="_blank" rel="noopener">Hexo</a>! This is your very first post. Check <a href="https://hexo.io/docs/" target="_blank" rel="noopener">documentation</a> for more info. If you get any problems when using Hexo, you can find the answer in <a href="https://hexo.io/docs/troubleshooting.html" target="_blank" rel="noopener">troubleshooting</a> or you can ask me on <a href="https://github.com/hexojs/hexo/issues" target="_blank" rel="noopener">GitHub</a>.</p><h2 id="Quick-Start"><a href="#Quick-Start" class="headerlink" title="Quick Start"></a>Quick Start</h2><h3 id="Create-a-new-post"><a href="#Create-a-new-post" class="headerlink" title="Create a new post"></a>Create a new post</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo new <span class="string">"My New Post"</span></span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/writing.html" target="_blank" rel="noopener">Writing</a></p><h3 id="Run-server"><a href="#Run-server" class="headerlink" title="Run server"></a>Run server</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo server</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/server.html" target="_blank" rel="noopener">Server</a></p><h3 id="Generate-static-files"><a href="#Generate-static-files" class="headerlink" title="Generate static files"></a>Generate static files</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo generate</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/generating.html" target="_blank" rel="noopener">Generating</a></p><h3 id="Deploy-to-remote-sites"><a href="#Deploy-to-remote-sites" class="headerlink" title="Deploy to remote sites"></a>Deploy to remote sites</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo deploy</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/deployment.html" target="_blank" rel="noopener">Deployment</a></p><!-- rebuild by neat -->]]></content>
    
    <summary type="html">
    
      
      
        &lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;\assets\css\APlayer.min.css&quot;&gt;&lt;script src=&quot;\assets\js\APlayer.min.js&quot; cla
      
    
    </summary>
    
    
  </entry>
  
</feed>
