<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="iframe.php?url=https%3A%2F%2Fblog.awesee.cn%2Ffeed.xml" rel="self" type="application/atom+xml" /><link href="iframe.php?url=https%3A%2F%2Fblog.awesee.cn%2F" rel="alternate" type="text/html" /><updated>2024-08-19T18:58:19+08:00</updated><id>https://blog.awesee.cn/feed.xml</id><title type="html">我的知识学习记录</title><subtitle>学会记录学习，提高学习效率</subtitle><author><name>Shuo</name></author><entry><title type="html">终极Web服务器-Caddy</title><link href="iframe.php?url=https%3A%2F%2Fblog.awesee.cn%2Flinux%2Fweb-server-caddy%2F" rel="alternate" type="text/html" title="终极Web服务器-Caddy" /><published>2023-03-25T15:04:05+08:00</published><updated>2023-03-25T15:04:05+08:00</updated><id>https://blog.awesee.cn/linux/web-server-caddy</id><content type="html" xml:base="https://blog.awesee.cn/linux/web-server-caddy/"><![CDATA[<h2 id="背景">背景</h2>

<p>现在的Nginx是一款非常流行的Web服务器，我们经常用它来做静态资源托管或反向代理。最近发现了一款全新的Web服务器Caddy，GitHub Star 46.9k+ 。试用了一下 Caddy，发现它使用起来比Nginx优雅多了，功能也很强，简单介绍一下然后推荐给大家！</p>

<p><img src="iframe.php?url=https%3A%2F%2Fawesee.github.io%2Fassets%2Fimages%2Fposts%2F20230325_caddy.png" alt="file" /></p>

<h2 id="简介">简介</h2>

<p>Caddy是一款功能强大，可扩展的平台，可以为您的站点、服务和应用程序提供服务，通常用做Web服务器或代理，采用Go语言编写。Caddy有下面这些开箱即用的特性:</p>

<ul>
  <li>全自动支持HTTP/2协议，无需任何配置。</li>
  <li>Caddy 使用 Let’s Encrypt 让你的站点全自动变成HTTPS，无需任何配置。</li>
  <li>合理使用多核，得益于Go的特性。</li>
  <li>完全支持IPv6环境。</li>
  <li>Caddy 对WebSockets有很好的支持。</li>
  <li>自动把Markdown转成 HTML。</li>
  <li>Caddy 对log格式的定义很容易。</li>
  <li>易于部署 得益于Go的特性，Caddy只是一个小小的二进制文件，没有依赖，很好部署。</li>
  <li>得益于Go的跨平台特性，Caddy很容易的支持了三大主流系统：Windows、 Linux、Mac。</li>
</ul>

<h2 id="安装">安装</h2>

<p>Linux 或 Mac 一键安装命令</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-sS</span> https://webi.sh/caddy | sh
</code></pre></div></div>

<p>Linux 系统还可以通过执行DNF或YUM命令安装</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dnf <span class="nb">install </span>caddy <span class="nt">-y</span>
</code></pre></div></div>

<p>Mac 系统可以通过Homebrew安装</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>brew <span class="nb">install </span>caddy
</code></pre></div></div>

<p>Windows 系统可以通过Chocolatey安装</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>choco <span class="nb">install </span>caddy
</code></pre></div></div>

<p>更多安装方式详见官网安装教程：<a href="iframe.php?url=https%3A%2F%2Fcaddyserver.com%2Fdocs%2Finstall">https://caddyserver.com/docs/install</a></p>

<h2 id="搭建静态文件服务">搭建静态文件服务</h2>

<p>创建 <code class="language-plaintext highlighter-rouge">/etc/caddy/Caddyfile</code> 文件，编写以下内容：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 第一个静态网站</span>
awesee.cn, www.awesee.cn, m.awesee.cn <span class="o">{</span>
	<span class="c"># 设置网站根目录</span>
	root <span class="k">*</span> /home/shuo/www/blog.awesee.cn
	file_server
<span class="o">}</span>
</code></pre></div></div>

<p>通过 <code class="language-plaintext highlighter-rouge">systemctl</code> 启动Caddy服务</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>systemctl start  caddy
</code></pre></div></div>

<p>打开浏览器，就可以看到部署的静态网站了。</p>

<p>搭建多个静态网站。</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 第一个静态网站</span>
awesee.cn, www.awesee.cn, m.awesee.cn <span class="o">{</span>
	<span class="c"># 设置网站根目录</span>
	root <span class="k">*</span> /home/shuo/www/blog.awesee.cn
	file_server
<span class="o">}</span>

<span class="c"># 第二个静态网站</span>
avatar.awesee.cn <span class="o">{</span>
	root <span class="k">*</span> /home/shuo/www/vue-color-avatar/dist
	file_server
<span class="o">}</span>
</code></pre></div></div>

<h2 id="反向代理服务">反向代理服务</h2>

<p>修改 <code class="language-plaintext highlighter-rouge">/etc/caddy/Caddyfile</code> 文件，添加以下内容：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 第一个静态网站</span>
awesee.cn, www.awesee.cn, m.awesee.cn <span class="o">{</span>
	<span class="c"># 设置网站根目录</span>
	root <span class="k">*</span> /home/shuo/www/blog.awesee.cn
	file_server
<span class="o">}</span>

<span class="c"># 第二个静态网站</span>
avatar.awesee.cn <span class="o">{</span>
	root <span class="k">*</span> /home/shuo/www/vue-color-avatar/dist
	file_server
<span class="o">}</span>

<span class="c"># 反向代理服务</span>
proxy.awesee.cn <span class="o">{</span>
	<span class="c"># 要代理的本机端口</span>
	reverse_proxy :32080
<span class="o">}</span>
</code></pre></div></div>

<p>通过 <code class="language-plaintext highlighter-rouge">systemctl</code> 重启Caddy服务</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>systemctl restart  caddy
</code></pre></div></div>

<p>到此完成了静态网站的搭建及反向代理服务实现，并且你的站点全自动变成HTTPS，无需任何配置。更多使用方法详见官方文档。</p>

<p><a href="iframe.php?url=https%3A%2F%2Fcaddyserver.com%2Fdocs%2F">https://caddyserver.com/docs/</a></p>]]></content><author><name>Shuo</name></author><category term="Linux" /><category term="Linux" /><category term="Web" /><summary type="html"><![CDATA[背景]]></summary></entry><entry><title type="html">常见问题解答</title><link href="iframe.php?url=https%3A%2F%2Fblog.awesee.cn%2Fguide%2Ffrequently-asked-questions%2F" rel="alternate" type="text/html" title="常见问题解答" /><published>2023-01-02T15:04:05+08:00</published><updated>2023-01-02T15:04:05+08:00</updated><id>https://blog.awesee.cn/guide/frequently-asked-questions</id><content type="html" xml:base="https://blog.awesee.cn/guide/frequently-asked-questions/"><![CDATA[<h2 id="检测目标计算机上端口运行服务的状态">检测目标计算机上端口运行服务的状态</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 指定端口</span>
<span class="nv">$ </span>nc <span class="nt">-zv</span> host.example.com 80
<span class="c"># 范围端口</span>
<span class="nv">$ </span>nc <span class="nt">-zv</span> host.example.com 21-23
</code></pre></div></div>

<h2 id="搜索包含指定内容的文件">搜索包含指定内容的文件</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 方法一</span>
<span class="nv">$ </span><span class="nb">grep</span> <span class="s2">"指定内容"</span> <span class="nt">-rl</span> /path/to/dir
<span class="c"># 方法二</span>
<span class="nv">$ </span>find /path/to/dir <span class="nt">-type</span> f <span class="o">[</span><span class="nt">-maxdepth</span> n] <span class="o">[</span><span class="nt">-mindepth</span> n] <span class="nt">-print0</span> |xargs <span class="nt">-0</span> <span class="nb">grep</span> <span class="s2">"指定内容"</span>  
</code></pre></div></div>

<h2 id="创建指定大小不占磁盘空间的文件">创建指定大小，不占磁盘空间的文件</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">dd </span><span class="k">if</span><span class="o">=</span>/dev/null <span class="nv">of</span><span class="o">=</span>/path/to/file <span class="o">[</span><span class="nv">bs</span><span class="o">=</span>1024] <span class="nv">count</span><span class="o">=</span>0 <span class="nv">seek</span><span class="o">=</span>20000000
</code></pre></div></div>

<h2 id="镜像网站">镜像网站</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>wget <span class="nt">--mirror</span> <span class="nt">--convert-links</span> <span class="nt">--adjust-extension</span> <span class="nt">--page-requisites</span> <span class="nt">--no-parent</span> https://www.example.com
</code></pre></div></div>

<h2 id="获取图片详细信息">获取图片详细信息</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>identify <span class="nt">-verbose</span> example.jpg
</code></pre></div></div>

<h2 id="视频无损压缩">视频无损压缩</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>ffmpeg <span class="nt">-i</span> <span class="k">in</span>.mp4 <span class="o">[</span><span class="nt">-crf</span> 18] <span class="o">[</span><span class="nt">-vf</span> <span class="nv">scale</span><span class="o">=</span><span class="nt">-1</span>:1080] out.mp4
</code></pre></div></div>

<h2 id="m3u8-download">M3U8 Download</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>ffmpeg <span class="nt">-i</span> https://example.com/index.m3u8 <span class="nt">-c</span> copy out.mp4
</code></pre></div></div>

<h2 id="视频转图片">视频转图片</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>ffmpeg <span class="nt">-i</span> <span class="k">in</span>.mp4 <span class="nt">-r</span> 30 <span class="o">[</span><span class="nt">-t</span> 60 <span class="nt">-s</span> 3480x2160] out/%4d.jpg 
</code></pre></div></div>

<h2 id="图片转视频">图片转视频</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>ffmpeg <span class="nt">-i</span> out/%4d.jpg <span class="nt">-r</span> 30 out.mp4
</code></pre></div></div>

<h2 id="mac-允许任何来源">Mac 允许任何来源</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>spctl <span class="nt">--master-disable</span>
</code></pre></div></div>

<h2 id="计算机常见术语及缩写">计算机常见术语及缩写</h2>

<p><a href="iframe.php?url=https%3A%2F%2Fawesee.github.io%2Fguide-abbreviations">Abbreviations</a></p>

<h2 id="what-does-el5-el6-and-el7-mean">What does el5, el6, and el7 mean?</h2>

<p>EL is short for Red Hat Enterprise Linux (EL).</p>

<ul>
  <li>EL5 is the download for Red Hat 5.x, CentOS 5.x, CloudLinux 5.x.</li>
  <li>EL6 is the download for Red Hat 6.x, CentOS 6.x, and CloudLinux 6.x.</li>
  <li>EL7 is the download for Red Hat 7.x, CentOS 7.x, and CloudLinux 7.x.</li>
</ul>

<h2 id="the-netrc-file">The .netrc file</h2>

<p><a href="iframe.php?url=https%3A%2F%2Flinux.die.net%2Fman%2F5%2Fnetrc">netrc, .netrc</a> - user configuration for ftp</p>]]></content><author><name>Shuo</name></author><category term="Guide" /><category term="Guide" /><summary type="html"><![CDATA[检测目标计算机上端口运行服务的状态 # 指定端口 $ nc -zv host.example.com 80 # 范围端口 $ nc -zv host.example.com 21-23]]></summary></entry><entry><title type="html">检查单词是否为句中其他单词的前缀</title><link href="iframe.php?url=https%3A%2F%2Fblog.awesee.cn%2Fproblems%2Fcheck-if-a-word-occurs-as-a-prefix-of-any-word-in-a-sentence%2F" rel="alternate" type="text/html" title="检查单词是否为句中其他单词的前缀" /><published>2019-12-26T21:30:00+08:00</published><updated>2019-12-26T21:30:00+08:00</updated><id>https://blog.awesee.cn/problems/check-if-a-word-occurs-as-a-prefix-of-any-word-in-a-sentence</id><content type="html" xml:base="https://blog.awesee.cn/problems/check-if-a-word-occurs-as-a-prefix-of-any-word-in-a-sentence/"><![CDATA[<h2 id="1455-检查单词是否为句中其他单词的前缀-easy">1455. 检查单词是否为句中其他单词的前缀 (Easy)</h2>

<p>给你一个字符串 <code>sentence</code> 作为句子并指定检索词为 <code>searchWord</code> ，其中句子由若干用 <strong>单个空格</strong> 分隔的单词组成。</p>

<p>请你检查检索词 <code>searchWord</code> 是否为句子 <code>sentence</code> 中任意单词的前缀。</p>

<ul>
	<li>如果 <code>searchWord</code> 是某一个单词的前缀，则返回句子 <code>sentence</code> 中该单词所对应的下标（<strong>下标从 1 开始</strong>）。</li>
	<li>如果 <code>searchWord</code> 是多个单词的前缀，则返回匹配的第一个单词的下标（<strong>最小下标</strong>）。</li>
	<li>如果 <code>searchWord</code> 不是任何单词的前缀，则返回 <strong>-1 </strong>。</li>
</ul>

<p>字符串 <code>S</code> 的 <strong>前缀</strong> 是 <code>S</code> 的任何前导连续子字符串。</p>

<p> </p>

<p><strong>示例 1：</strong></p>

<pre>
<strong>输入：</strong>sentence = "i love eating burger", searchWord = "burg"
<strong>输出：</strong>4
<strong>解释：</strong>"burg" 是 "burger" 的前缀，而 "burger" 是句子中第 4 个单词。</pre>

<p><strong>示例 2：</strong></p>

<pre>
<strong>输入：</strong>sentence = "this problem is an easy problem", searchWord = "pro"
<strong>输出：</strong>2
<strong>解释：</strong>"pro" 是 "problem" 的前缀，而 "problem" 是句子中第 2 个也是第 6 个单词，但是应该返回最小下标 2 。
</pre>

<p><strong>示例 3：</strong></p>

<pre>
<strong>输入：</strong>sentence = "i am tired", searchWord = "you"
<strong>输出：</strong>-1
<strong>解释：</strong>"you" 不是句子中任何单词的前缀。
</pre>

<p><strong>示例 4：</strong></p>

<pre>
<strong>输入：</strong>sentence = "i use triple pillow", searchWord = "pill"
<strong>输出：</strong>4
</pre>

<p><strong>示例 5：</strong></p>

<pre>
<strong>输入：</strong>sentence = "hello from the other side", searchWord = "they"
<strong>输出：</strong>-1
</pre>

<p> </p>

<p><strong>提示：</strong></p>

<ul>
	<li><code>1 &lt;= sentence.length &lt;= 100</code></li>
	<li><code>1 &lt;= searchWord.length &lt;= 10</code></li>
	<li><code>sentence</code> 由小写英文字母和空格组成。</li>
	<li><code>searchWord</code> 由小写英文字母组成。</li>
	<li>前缀就是紧密附着于词根的语素，中间不能插入其它成分，并且它的位置是固定的——-位于词根之前。（引用自 <a href="iframe.php?url=https%3A%2F%2Fbaike.baidu.com%2Fitem%2F%25E5%2589%258D%25E7%25BC%2580" target="_blank">前缀_百度百科</a> ）</li>
</ul>

<h3 id="相关话题">相关话题</h3>
<p>[<a href="iframe.php?url=https%3A%2F%2Fgithub.com%2Fawesee%2Fleetcode%2Ftree%2Fmain%2Ftag%2Fstring%2FREADME.md">字符串</a>]
  [<a href="iframe.php?url=https%3A%2F%2Fgithub.com%2Fawesee%2Fleetcode%2Ftree%2Fmain%2Ftag%2Fstring-matching%2FREADME.md">字符串匹配</a>]</p>

<hr />

<h2 id="解法"><a href="iframe.php?url=https%3A%2F%2Fgithub.com%2Fawesee%2Fleetcode%2Ftree%2Fmain%2Fproblems%2Fcheck-if-a-word-occurs-as-a-prefix-of-any-word-in-a-sentence">解法</a></h2>]]></content><author><name>Shuo</name></author><category term="Leetcode" /><category term="String" /><category term="String Matching" /><summary type="html"><![CDATA[1455. 检查单词是否为句中其他单词的前缀 (Easy)]]></summary></entry><entry><title type="html">旅行终点站</title><link href="iframe.php?url=https%3A%2F%2Fblog.awesee.cn%2Fproblems%2Fdestination-city%2F" rel="alternate" type="text/html" title="旅行终点站" /><published>2019-12-07T21:30:00+08:00</published><updated>2019-12-07T21:30:00+08:00</updated><id>https://blog.awesee.cn/problems/destination-city</id><content type="html" xml:base="https://blog.awesee.cn/problems/destination-city/"><![CDATA[<h2 id="1436-旅行终点站-easy">1436. 旅行终点站 (Easy)</h2>

<p>给你一份旅游线路图，该线路图中的旅行线路用数组 <code>paths</code> 表示，其中 <code>paths[i] = [cityA<sub>i</sub>, cityB<sub>i</sub>]</code> 表示该线路将会从 <code>cityA<sub>i</sub></code> 直接前往 <code>cityB<sub>i</sub></code> 。请你找出这次旅行的终点站，即没有任何可以通往其他城市的线路的城市<em>。</em></p>

<p>题目数据保证线路图会形成一条不存在循环的线路，因此只会有一个旅行终点站。</p>

<p>&nbsp;</p>

<p><strong>示例 1：</strong></p>

<pre><strong>输入：</strong>paths = [[&quot;London&quot;,&quot;New York&quot;],[&quot;New York&quot;,&quot;Lima&quot;],[&quot;Lima&quot;,&quot;Sao Paulo&quot;]]
<strong>输出：</strong>&quot;Sao Paulo&quot; 
<strong>解释：</strong>从 &quot;London&quot; 出发，最后抵达终点站 &quot;Sao Paulo&quot; 。本次旅行的路线是 &quot;London&quot; -&gt; &quot;New York&quot; -&gt; &quot;Lima&quot; -&gt; &quot;Sao Paulo&quot; 。
</pre>

<p><strong>示例 2：</strong></p>

<pre><strong>输入：</strong>paths = [[&quot;B&quot;,&quot;C&quot;],[&quot;D&quot;,&quot;B&quot;],[&quot;C&quot;,&quot;A&quot;]]
<strong>输出：</strong>&quot;A&quot;
<strong>解释：</strong>所有可能的线路是：
&quot;D&quot; -&gt; &quot;B&quot; -&gt; &quot;C&quot; -&gt; &quot;A&quot;.&nbsp;
&quot;B&quot; -&gt; &quot;C&quot; -&gt; &quot;A&quot;.&nbsp;
&quot;C&quot; -&gt; &quot;A&quot;.&nbsp;
&quot;A&quot;.&nbsp;
显然，旅行终点站是 &quot;A&quot; 。
</pre>

<p><strong>示例 3：</strong></p>

<pre><strong>输入：</strong>paths = [[&quot;A&quot;,&quot;Z&quot;]]
<strong>输出：</strong>&quot;Z&quot;
</pre>

<p>&nbsp;</p>

<p><strong>提示：</strong></p>

<ul>
	<li><code>1 &lt;= paths.length &lt;= 100</code></li>
	<li><code>paths[i].length == 2</code></li>
	<li><code>1 &lt;=&nbsp;cityA<sub>i</sub>.length,&nbsp;cityB<sub>i</sub>.length &lt;= 10</code></li>
	<li><code>cityA<sub>i&nbsp;</sub>!=&nbsp;cityB<sub>i</sub></code></li>
	<li>所有字符串均由大小写英文字母和空格字符组成。</li>
</ul>

<h3 id="相关话题">相关话题</h3>
<p>[<a href="iframe.php?url=https%3A%2F%2Fgithub.com%2Fawesee%2Fleetcode%2Ftree%2Fmain%2Ftag%2Fhash-table%2FREADME.md">哈希表</a>]
  [<a href="iframe.php?url=https%3A%2F%2Fgithub.com%2Fawesee%2Fleetcode%2Ftree%2Fmain%2Ftag%2Fstring%2FREADME.md">字符串</a>]</p>

<hr />

<h2 id="解法"><a href="iframe.php?url=https%3A%2F%2Fgithub.com%2Fawesee%2Fleetcode%2Ftree%2Fmain%2Fproblems%2Fdestination-city">解法</a></h2>]]></content><author><name>Shuo</name></author><category term="Leetcode" /><category term="Hash Table" /><category term="String" /><summary type="html"><![CDATA[1436. 旅行终点站 (Easy)]]></summary></entry><entry><title type="html">Ticker or Sleep</title><link href="iframe.php?url=https%3A%2F%2Fblog.awesee.cn%2Fticker-or-sleep%2F" rel="alternate" type="text/html" title="Ticker or Sleep" /><published>2019-11-30T18:30:00+08:00</published><updated>2019-11-30T18:30:00+08:00</updated><id>https://blog.awesee.cn/ticker-or-sleep</id><content type="html" xml:base="https://blog.awesee.cn/ticker-or-sleep/"><![CDATA[<p>Go编程中，经常会遇到周期性处理任务的需求，下面以每秒打印一次当前时间为例介绍实现方式及区别</p>

<h3 id="方法一ticker">方法一（Ticker）</h3>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">func</span> <span class="n">PrintNow</span><span class="p">()</span> <span class="p">{</span>
	<span class="n">t</span> <span class="o">:=</span> <span class="n">time</span><span class="o">.</span><span class="n">NewTicker</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">Second</span><span class="p">)</span>
	<span class="k">for</span> <span class="k">range</span> <span class="n">t</span><span class="o">.</span><span class="n">C</span> <span class="p">{</span>
		<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">Now</span><span class="p">())</span>
	<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="方法二sleep">方法二（Sleep）</h3>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">func</span> <span class="n">PrintNow</span><span class="p">()</span> <span class="p">{</span>
	<span class="k">for</span> <span class="p">{</span>
		<span class="n">time</span><span class="o">.</span><span class="n">Sleep</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">Second</span><span class="p">)</span>
		<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">Now</span><span class="p">())</span>
	<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>以上2种方法都可以实现每秒打印一次当前时间，但是2种方式有很大区别。</p>

<p>cpu：方法一cpu占用大于方法二，因为方法一会有一个单独的协程用于定时向chan写入当前时间。</p>

<p>执行时间：方法一小于方法二，实际上方法二并不是每秒打印一次当前时间，
间隔时间其实还包含打印当前时间的执行时间。如果把<code class="language-plaintext highlighter-rouge">fmt.Println(time.Now())</code>改为</p>
<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">func</span><span class="p">()</span> <span class="p">{</span>
	<span class="n">time</span><span class="o">.</span><span class="n">Sleep</span><span class="p">(</span><span class="m">500</span> <span class="o">*</span> <span class="n">time</span><span class="o">.</span><span class="n">Millisecond</span><span class="p">)</span>
	<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">Now</span><span class="p">())</span>
<span class="p">}()</span>
</code></pre></div></div>
<p>结果就很明显，方法一是每秒打印一次当前时间，方法二是每1.5秒打印一次当前时间</p>

<p>方法一是两个协程并发执行，方法二是一个协程串行执行</p>]]></content><author><name>Shuo</name></author><category term="Go" /><category term="Go" /><category term="Guide" /><summary type="html"><![CDATA[Go编程中，经常会遇到周期性处理任务的需求，下面以每秒打印一次当前时间为例介绍实现方式及区别]]></summary></entry><entry><title type="html">分割字符串的最大得分</title><link href="iframe.php?url=https%3A%2F%2Fblog.awesee.cn%2Fproblems%2Fmaximum-score-after-splitting-a-string%2F" rel="alternate" type="text/html" title="分割字符串的最大得分" /><published>2019-11-23T21:30:00+08:00</published><updated>2019-11-23T21:30:00+08:00</updated><id>https://blog.awesee.cn/problems/maximum-score-after-splitting-a-string</id><content type="html" xml:base="https://blog.awesee.cn/problems/maximum-score-after-splitting-a-string/"><![CDATA[<h2 id="1422-分割字符串的最大得分-easy">1422. 分割字符串的最大得分 (Easy)</h2>

<p>给你一个由若干 0 和 1 组成的字符串 <code>s</code> ，请你计算并返回将该字符串分割成两个 <strong>非空</strong> 子字符串（即&nbsp;<strong>左</strong> 子字符串和 <strong>右</strong> 子字符串）所能获得的最大得分。</p>

<p>「分割字符串的得分」为 <strong>左</strong> 子字符串中 <strong>0</strong> 的数量加上 <strong>右</strong> 子字符串中 <strong>1</strong> 的数量。</p>

<p>&nbsp;</p>

<p><strong>示例 1：</strong></p>

<pre><strong>输入：</strong>s = &quot;011101&quot;
<strong>输出：</strong>5 
<strong>解释：</strong>
将字符串 s 划分为两个非空子字符串的可行方案有：
左子字符串 = &quot;0&quot; 且 右子字符串 = &quot;11101&quot;，得分 = 1 + 4 = 5 
左子字符串 = &quot;01&quot; 且 右子字符串 = &quot;1101&quot;，得分 = 1 + 3 = 4 
左子字符串 = &quot;011&quot; 且 右子字符串 = &quot;101&quot;，得分 = 1 + 2 = 3 
左子字符串 = &quot;0111&quot; 且 右子字符串 = &quot;01&quot;，得分 = 1 + 1 = 2 
左子字符串 = &quot;01110&quot; 且 右子字符串 = &quot;1&quot;，得分 = 2 + 1 = 3
</pre>

<p><strong>示例 2：</strong></p>

<pre><strong>输入：</strong>s = &quot;00111&quot;
<strong>输出：</strong>5
<strong>解释：</strong>当 左子字符串 = &quot;00&quot; 且 右子字符串 = &quot;111&quot; 时，我们得到最大得分 = 2 + 3 = 5
</pre>

<p><strong>示例 3：</strong></p>

<pre><strong>输入：</strong>s = &quot;1111&quot;
<strong>输出：</strong>3
</pre>

<p>&nbsp;</p>

<p><strong>提示：</strong></p>

<ul>
	<li><code>2 &lt;= s.length &lt;= 500</code></li>
	<li>字符串 <code>s</code> 仅由字符 <code>&#39;0&#39;</code> 和 <code>&#39;1&#39;</code> 组成。</li>
</ul>

<h3 id="相关话题">相关话题</h3>
<p>[<a href="iframe.php?url=https%3A%2F%2Fgithub.com%2Fawesee%2Fleetcode%2Ftree%2Fmain%2Ftag%2Fstring%2FREADME.md">字符串</a>]</p>

<hr />

<h2 id="解法"><a href="iframe.php?url=https%3A%2F%2Fgithub.com%2Fawesee%2Fleetcode%2Ftree%2Fmain%2Fproblems%2Fmaximum-score-after-splitting-a-string">解法</a></h2>]]></content><author><name>Shuo</name></author><category term="Leetcode" /><category term="String" /><summary type="html"><![CDATA[1422. 分割字符串的最大得分 (Easy)]]></summary></entry><entry><title type="html">重新格式化字符串</title><link href="iframe.php?url=https%3A%2F%2Fblog.awesee.cn%2Fproblems%2Freformat-the-string%2F" rel="alternate" type="text/html" title="重新格式化字符串" /><published>2019-11-18T21:30:00+08:00</published><updated>2019-11-18T21:30:00+08:00</updated><id>https://blog.awesee.cn/problems/reformat-the-string</id><content type="html" xml:base="https://blog.awesee.cn/problems/reformat-the-string/"><![CDATA[<h2 id="1417-重新格式化字符串-easy">1417. 重新格式化字符串 (Easy)</h2>

<p>给你一个混合了数字和字母的字符串 <code>s</code>，其中的字母均为小写英文字母。</p>

<p>请你将该字符串重新格式化，使得任意两个相邻字符的类型都不同。也就是说，字母后面应该跟着数字，而数字后面应该跟着字母。</p>

<p>请你返回 <strong>重新格式化后</strong> 的字符串；如果无法按要求重新格式化，则返回一个 <strong>空字符串</strong> 。</p>

<p>&nbsp;</p>

<p><strong>示例 1：</strong></p>

<pre><strong>输入：</strong>s = &quot;a0b1c2&quot;
<strong>输出：</strong>&quot;0a1b2c&quot;
<strong>解释：</strong>&quot;0a1b2c&quot; 中任意两个相邻字符的类型都不同。 &quot;a0b1c2&quot;, &quot;0a1b2c&quot;, &quot;0c2a1b&quot; 也是满足题目要求的答案。
</pre>

<p><strong>示例 2：</strong></p>

<pre><strong>输入：</strong>s = &quot;leetcode&quot;
<strong>输出：</strong>&quot;&quot;
<strong>解释：</strong>&quot;leetcode&quot; 中只有字母，所以无法满足重新格式化的条件。
</pre>

<p><strong>示例 3：</strong></p>

<pre><strong>输入：</strong>s = &quot;1229857369&quot;
<strong>输出：</strong>&quot;&quot;
<strong>解释：</strong>&quot;1229857369&quot; 中只有数字，所以无法满足重新格式化的条件。
</pre>

<p><strong>示例 4：</strong></p>

<pre><strong>输入：</strong>s = &quot;covid2019&quot;
<strong>输出：</strong>&quot;c2o0v1i9d&quot;
</pre>

<p><strong>示例 5：</strong></p>

<pre><strong>输入：</strong>s = &quot;ab123&quot;
<strong>输出：</strong>&quot;1a2b3&quot;
</pre>

<p>&nbsp;</p>

<p><strong>提示：</strong></p>

<ul>
	<li><code>1 &lt;= s.length &lt;= 500</code></li>
	<li><code>s</code> 仅由小写英文字母和/或数字组成。</li>
</ul>

<h3 id="相关话题">相关话题</h3>
<p>[<a href="iframe.php?url=https%3A%2F%2Fgithub.com%2Fawesee%2Fleetcode%2Ftree%2Fmaster%2Ftag%2Fstring%2FREADME.md">字符串</a>]</p>

<hr />

<h2 id="解法"><a href="iframe.php?url=https%3A%2F%2Fgithub.com%2Fawesee%2Fleetcode%2Ftree%2Fmaster%2Fproblems%2Freformat-the-string">解法</a></h2>]]></content><author><name>Shuo</name></author><category term="Leetcode" /><category term="String" /><summary type="html"><![CDATA[1417. 重新格式化字符串 (Easy)]]></summary></entry><entry><title type="html">数组中的字符串匹配</title><link href="iframe.php?url=https%3A%2F%2Fblog.awesee.cn%2Fproblems%2Fstring-matching-in-an-array%2F" rel="alternate" type="text/html" title="数组中的字符串匹配" /><published>2019-11-09T21:30:00+08:00</published><updated>2019-11-09T21:30:00+08:00</updated><id>https://blog.awesee.cn/problems/string-matching-in-an-array</id><content type="html" xml:base="https://blog.awesee.cn/problems/string-matching-in-an-array/"><![CDATA[<h2 id="1408-数组中的字符串匹配-easy">1408. 数组中的字符串匹配 (Easy)</h2>

<p>给你一个字符串数组 <code>words</code> ，数组中的每个字符串都可以看作是一个单词。请你按 <strong>任意</strong> 顺序返回 <code>words</code> 中是其他单词的子字符串的所有单词。</p>

<p>如果你可以删除 <code>words[j]</code>&nbsp;最左侧和/或最右侧的若干字符得到 <code>word[i]</code> ，那么字符串 <code>words[i]</code> 就是 <code>words[j]</code> 的一个子字符串。</p>

<p>&nbsp;</p>

<p><strong>示例 1：</strong></p>

<pre><strong>输入：</strong>words = [&quot;mass&quot;,&quot;as&quot;,&quot;hero&quot;,&quot;superhero&quot;]
<strong>输出：</strong>[&quot;as&quot;,&quot;hero&quot;]
<strong>解释：</strong>&quot;as&quot; 是 &quot;mass&quot; 的子字符串，&quot;hero&quot; 是 &quot;superhero&quot; 的子字符串。
[&quot;hero&quot;,&quot;as&quot;] 也是有效的答案。
</pre>

<p><strong>示例 2：</strong></p>

<pre><strong>输入：</strong>words = [&quot;leetcode&quot;,&quot;et&quot;,&quot;code&quot;]
<strong>输出：</strong>[&quot;et&quot;,&quot;code&quot;]
<strong>解释：</strong>&quot;et&quot; 和 &quot;code&quot; 都是 &quot;leetcode&quot; 的子字符串。
</pre>

<p><strong>示例 3：</strong></p>

<pre><strong>输入：</strong>words = [&quot;blue&quot;,&quot;green&quot;,&quot;bu&quot;]
<strong>输出：</strong>[]
</pre>

<p>&nbsp;</p>

<p><strong>提示：</strong></p>

<ul>
	<li><code>1 &lt;= words.length &lt;= 100</code></li>
	<li><code>1 &lt;= words[i].length &lt;= 30</code></li>
	<li><code>words[i]</code> 仅包含小写英文字母。</li>
	<li>题目数据 <strong>保证</strong> 每个 <code>words[i]</code> 都是独一无二的。</li>
</ul>

<h3 id="相关话题">相关话题</h3>
<p>[<a href="iframe.php?url=https%3A%2F%2Fgithub.com%2Fawesee%2Fleetcode%2Ftree%2Fmain%2Ftag%2Fstring%2FREADME.md">字符串</a>]
  [<a href="iframe.php?url=https%3A%2F%2Fgithub.com%2Fawesee%2Fleetcode%2Ftree%2Fmain%2Ftag%2Fstring-matching%2FREADME.md">字符串匹配</a>]</p>

<hr />

<h2 id="解法"><a href="iframe.php?url=https%3A%2F%2Fgithub.com%2Fawesee%2Fleetcode%2Ftree%2Fmain%2Fproblems%2Fstring-matching-in-an-array">解法</a></h2>]]></content><author><name>Shuo</name></author><category term="Leetcode" /><category term="String" /><category term="String Matching" /><summary type="html"><![CDATA[1408. 数组中的字符串匹配 (Easy)]]></summary></entry><entry><title type="html">Go系统命令管道操作</title><link href="iframe.php?url=https%3A%2F%2Fblog.awesee.cn%2Fgo-cmd-pipe%2F" rel="alternate" type="text/html" title="Go系统命令管道操作" /><published>2019-09-05T12:30:00+08:00</published><updated>2019-09-05T12:30:00+08:00</updated><id>https://blog.awesee.cn/go-cmd-pipe</id><content type="html" xml:base="https://blog.awesee.cn/go-cmd-pipe/"><![CDATA[<p>go 执行系统命令时不能直接使用管道符 <code class="language-plaintext highlighter-rouge">|</code></p>

<h2 id="实现方法如下">实现方法如下：</h2>

<h3 id="方法一同步">方法一（同步）</h3>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">func</span> <span class="n">sync</span><span class="p">()</span> <span class="p">{</span>
	<span class="n">cmd1</span> <span class="o">:=</span> <span class="n">exec</span><span class="o">.</span><span class="n">Command</span><span class="p">(</span><span class="s">"ls"</span><span class="p">,</span> <span class="s">"."</span><span class="p">)</span>
	<span class="n">cmd2</span> <span class="o">:=</span> <span class="n">exec</span><span class="o">.</span><span class="n">Command</span><span class="p">(</span><span class="s">"grep"</span><span class="p">,</span> <span class="s">"go"</span><span class="p">)</span>
	<span class="n">cmd2</span><span class="o">.</span><span class="n">Stdout</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">Stdout</span>
	<span class="n">in</span><span class="p">,</span> <span class="n">_</span> <span class="o">:=</span> <span class="n">cmd2</span><span class="o">.</span><span class="n">StdinPipe</span><span class="p">()</span>
	<span class="n">cmd1</span><span class="o">.</span><span class="n">Stdout</span> <span class="o">=</span> <span class="n">in</span>
	<span class="n">cmd2</span><span class="o">.</span><span class="n">Start</span><span class="p">()</span>
	<span class="n">cmd1</span><span class="o">.</span><span class="n">Run</span><span class="p">()</span>
	<span class="n">in</span><span class="o">.</span><span class="n">Close</span><span class="p">()</span>
	<span class="n">cmd2</span><span class="o">.</span><span class="n">Wait</span><span class="p">()</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="方法二异步">方法二（异步）</h3>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">func</span> <span class="n">async</span><span class="p">()</span> <span class="p">{</span>
	<span class="n">cmd1</span> <span class="o">:=</span> <span class="n">exec</span><span class="o">.</span><span class="n">Command</span><span class="p">(</span><span class="s">"ls"</span><span class="p">,</span> <span class="s">"."</span><span class="p">)</span>
	<span class="n">cmd2</span> <span class="o">:=</span> <span class="n">exec</span><span class="o">.</span><span class="n">Command</span><span class="p">(</span><span class="s">"grep"</span><span class="p">,</span> <span class="s">"go"</span><span class="p">)</span>
	<span class="n">cmd2</span><span class="o">.</span><span class="n">Stdout</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">Stdout</span>
	<span class="n">out</span><span class="p">,</span> <span class="n">_</span> <span class="o">:=</span> <span class="n">cmd1</span><span class="o">.</span><span class="n">StdoutPipe</span><span class="p">()</span>
	<span class="n">in</span><span class="p">,</span> <span class="n">_</span> <span class="o">:=</span> <span class="n">cmd2</span><span class="o">.</span><span class="n">StdinPipe</span><span class="p">()</span>
	<span class="k">go</span> <span class="k">func</span><span class="p">()</span> <span class="p">{</span>
		<span class="k">defer</span> <span class="k">func</span><span class="p">()</span> <span class="p">{</span>
			<span class="n">out</span><span class="o">.</span><span class="n">Close</span><span class="p">()</span>
			<span class="n">in</span><span class="o">.</span><span class="n">Close</span><span class="p">()</span>
		<span class="p">}()</span>
		<span class="n">io</span><span class="o">.</span><span class="n">Copy</span><span class="p">(</span><span class="n">in</span><span class="p">,</span> <span class="n">out</span><span class="p">)</span>
	<span class="p">}()</span>
	<span class="n">cmd1</span><span class="o">.</span><span class="n">Run</span><span class="p">()</span>
	<span class="n">cmd2</span><span class="o">.</span><span class="n">Run</span><span class="p">()</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="方法三串联">方法三（串联）</h3>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">func</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
	<span class="n">cmd1</span> <span class="o">:=</span> <span class="n">exec</span><span class="o">.</span><span class="n">Command</span><span class="p">(</span><span class="s">"ls"</span><span class="p">,</span> <span class="s">"."</span><span class="p">)</span>
	<span class="n">cmd2</span> <span class="o">:=</span> <span class="n">exec</span><span class="o">.</span><span class="n">Command</span><span class="p">(</span><span class="s">"grep"</span><span class="p">,</span> <span class="s">"go"</span><span class="p">)</span>
	<span class="n">cmd3</span> <span class="o">:=</span> <span class="n">exec</span><span class="o">.</span><span class="n">Command</span><span class="p">(</span><span class="s">"grep"</span><span class="p">,</span> <span class="s">"main"</span><span class="p">)</span>
	<span class="n">cmd3</span><span class="o">.</span><span class="n">Stdout</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">Stdout</span>
	<span class="n">pipe</span><span class="p">(</span><span class="n">cmd1</span><span class="p">,</span> <span class="n">cmd2</span><span class="p">,</span> <span class="n">cmd3</span><span class="p">)</span>
	<span class="n">cmd1</span><span class="o">.</span><span class="n">Run</span><span class="p">()</span>
	<span class="n">cmd2</span><span class="o">.</span><span class="n">Run</span><span class="p">()</span>
	<span class="n">cmd3</span><span class="o">.</span><span class="n">Run</span><span class="p">()</span>
<span class="p">}</span>

<span class="k">func</span> <span class="n">pipe</span><span class="p">(</span><span class="n">cmds</span> <span class="o">...*</span><span class="n">exec</span><span class="o">.</span><span class="n">Cmd</span><span class="p">)</span> <span class="p">{</span>
	<span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">cmd</span> <span class="o">:=</span> <span class="k">range</span> <span class="n">cmds</span><span class="p">[</span><span class="m">1</span><span class="o">:</span><span class="p">]</span> <span class="p">{</span>
		<span class="n">out</span><span class="p">,</span> <span class="n">_</span> <span class="o">:=</span> <span class="n">cmds</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">StdoutPipe</span><span class="p">()</span>
		<span class="n">in</span><span class="p">,</span> <span class="n">_</span> <span class="o">:=</span> <span class="n">cmd</span><span class="o">.</span><span class="n">StdinPipe</span><span class="p">()</span>
		<span class="k">go</span> <span class="k">func</span><span class="p">()</span> <span class="p">{</span>
			<span class="k">defer</span> <span class="k">func</span><span class="p">()</span> <span class="p">{</span>
				<span class="n">out</span><span class="o">.</span><span class="n">Close</span><span class="p">()</span>
				<span class="n">in</span><span class="o">.</span><span class="n">Close</span><span class="p">()</span>
			<span class="p">}()</span>
			<span class="n">io</span><span class="o">.</span><span class="n">Copy</span><span class="p">(</span><span class="n">in</span><span class="p">,</span> <span class="n">out</span><span class="p">)</span>
		<span class="p">}()</span>
	<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>]]></content><author><name>Shuo</name></author><category term="Go" /><category term="Go" /><category term="Guide" /><summary type="html"><![CDATA[go 执行系统命令时不能直接使用管道符 |]]></summary></entry><entry><title type="html">systemd 服务</title><link href="iframe.php?url=https%3A%2F%2Fblog.awesee.cn%2Flinux%2Fmanage-services-using-systemctl-in-linux%2F" rel="alternate" type="text/html" title="systemd 服务" /><published>2019-05-12T09:30:00+08:00</published><updated>2019-05-12T09:30:00+08:00</updated><id>https://blog.awesee.cn/linux/manage-services-using-systemctl-in-linux</id><content type="html" xml:base="https://blog.awesee.cn/linux/manage-services-using-systemctl-in-linux/"><![CDATA[<p>systemd 是一个 Linux 系统基础组件的集合，提供了一个系统和服务管理器，运行为 PID 1 并负责启动其它程序。
功能包括：支持并行化任务；同时采用 socket 式与 D-Bus 总线式激活服务；按需启动守护进程（daemon）；
利用 Linux 的 cgroups 监视进程；支持快照和系统恢复；维护挂载点和自动挂载点；各服务间基于依赖关系进行精密控制。
systemd 支持 SysV 和 LSB 初始脚本，可以替代 sysvinit。
除此之外，功能还包括日志进程、控制基础系统配置，维护登陆用户列表以及系统账户、运行时目录和设置，可以运行容器和虚拟机，
可以简单的管理网络配置、网络时间同步、日志转发和名称解析等。</p>

<h3 id="systemd-简介">systemd 简介</h3>
<p>首先 systemd 是一个用户空间的程序，属于应用程序，不属于 Linux 内核范畴。
systemd 是 Linux 系统中最新的初始化系统（init），它主要的设计目标是克服 sysvinit 固有的缺点，提高系统的启动速度。</p>

<p>Linux内核加载启动后，用户空间的第一个进程就是初始化进程，这个程序的物理文件约定位于/sbin/init，
当然也可以通过传递内核参数来让内核启动指定的程序。这个进程的特点是进程号为1，代表第一个运行的用户空间进程。
不同发行版采用了不同的启动程序，主要有以下几种主流选择：</p>

<ol>
  <li>以 Ubuntu 为代表的 Linux 发行版采用 upstart</li>
  <li>CentOS7.0 版本之前的 System V init</li>
  <li>CentOS7.0 版本的 systemd</li>
</ol>

<p>systemd 架构图:
<img src="iframe.php?url=https%3A%2F%2Fawesee.github.io%2Fassets%2Fimages%2Fposts%2F20190512093000.png" alt="file" /></p>

<h3 id="systemd-基本使用">systemd 基本使用</h3>

<p>查看当前安装的版本</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>systemctl <span class="nt">--version</span>

systemd 219
+PAM +AUDIT +SELINUX +IMA <span class="nt">-APPARMOR</span> +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 <span class="nt">-SECCOMP</span> +BLKID +ELFUTILS +KMOD +IDN
</code></pre></div></div>

<p>分析系统状态</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>systemctl status
</code></pre></div></div>

<p>输出激活的单元</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>systemctl 
或
<span class="nv">$ </span>systemctl list-units
</code></pre></div></div>

<p>输出运行失败的单元</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>systemctl <span class="nt">--failed</span>
</code></pre></div></div>

<p>所有可用的单元文件存放在 /usr/lib/systemd/system/ 和 /etc/systemd/system/ 目录（后者优先级更高）。查看所有已安装服务：</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>systemctl list-unit-files
</code></pre></div></div>

<h3 id="系统管理">系统管理</h3>
<p>systemd 并不是一个命令，而是一组命令，涉及到系统管理的方方面面。</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 重启系统</span>
<span class="nv">$ </span><span class="nb">sudo </span>systemctl reboot

<span class="c"># 关闭系统，切断电源</span>
<span class="nv">$ </span><span class="nb">sudo </span>systemctl poweroff

<span class="c"># CPU停止工作</span>
<span class="nv">$ </span><span class="nb">sudo </span>systemctl halt

<span class="c"># 暂停系统</span>
<span class="nv">$ </span><span class="nb">sudo </span>systemctl <span class="nb">suspend</span>

<span class="c"># 让系统进入冬眠状态</span>
<span class="nv">$ </span><span class="nb">sudo </span>systemctl hibernate

<span class="c"># 让系统进入交互式休眠状态</span>
<span class="nv">$ </span><span class="nb">sudo </span>systemctl hybrid-sleep

<span class="c"># 启动进入救援状态（单用户状态）</span>
<span class="nv">$ </span><span class="nb">sudo </span>systemctl rescue
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">systemd-analyze</code> 命令用于查看启动耗时</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 查看启动耗时</span>
<span class="nv">$ </span>systemd-analyze                                                                                       

<span class="c"># 查看每个服务的启动耗时</span>
<span class="nv">$ </span>systemd-analyze blame

<span class="c"># 显示瀑布状的启动过程流</span>
<span class="nv">$ </span>systemd-analyze critical-chain

<span class="c"># 显示指定服务的启动流</span>
<span class="nv">$ </span>systemd-analyze critical-chain atd.service
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">hostnamectl</code> 命令用于查看当前主机的信息</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 显示当前主机的信息</span>
<span class="nv">$ </span>hostnamectl

<span class="c"># 设置主机名。</span>
<span class="nv">$ </span><span class="nb">sudo </span>hostnamectl set-hostname awesee
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">localectl</code> 命令用于查看本地化设置</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 查看本地化设置</span>
<span class="nv">$ </span>localectl

<span class="c"># 设置本地化参数。</span>
<span class="nv">$ </span><span class="nb">sudo </span>localectl set-locale <span class="nv">LANG</span><span class="o">=</span>zh_CN.utf8
<span class="nv">$ </span><span class="nb">sudo </span>localectl set-keymap zh_CN
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">timedatectl</code> 命令用于查看当前时区设置</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 查看当前时区设置</span>
<span class="nv">$ </span>timedatectl

<span class="c"># 显示所有可用的时区</span>
<span class="nv">$ </span>timedatectl list-timezones                                                                                   

<span class="c"># 设置当前时区</span>
<span class="nv">$ </span><span class="nb">sudo </span>timedatectl set-timezone Asia/Shanghai
<span class="nv">$ </span><span class="nb">sudo </span>timedatectl set-time YYYY-MM-DD
<span class="nv">$ </span><span class="nb">sudo </span>timedatectl set-time HH:MM:SS
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">loginctl</code> 命令用于查看当前登录的用户</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 列出当前session</span>
<span class="nv">$ </span>loginctl list-sessions

<span class="c"># 列出当前登录用户</span>
<span class="nv">$ </span>loginctl list-users

<span class="c"># 列出显示指定用户的信息</span>
<span class="nv">$ </span>loginctl show-user shuo
</code></pre></div></div>

<h3 id="systemd-unit">systemd unit</h3>
<p>对于开发者来说，工作量最大的部分应该是编写配置单元文件，定义所需要的单元。</p>

<p>systemd unit 类型</p>

<table>
  <thead>
    <tr>
      <th>Unit Type</th>
      <th>File Extension</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Service unit</td>
      <td><code class="language-plaintext highlighter-rouge">.service</code></td>
      <td>服务类</td>
    </tr>
    <tr>
      <td>Target unit</td>
      <td><code class="language-plaintext highlighter-rouge">.target</code></td>
      <td>一个 unit 服务组，用于模拟实现运行级别</td>
    </tr>
    <tr>
      <td>Automount unit</td>
      <td><code class="language-plaintext highlighter-rouge">.automount</code></td>
      <td>文件系统自动挂载点</td>
    </tr>
    <tr>
      <td>Device unit</td>
      <td><code class="language-plaintext highlighter-rouge">.device</code></td>
      <td>内核识别的设备文件</td>
    </tr>
    <tr>
      <td>Mount unit</td>
      <td><code class="language-plaintext highlighter-rouge">.mount</code></td>
      <td>文件系统挂载点</td>
    </tr>
    <tr>
      <td>Path unit</td>
      <td><code class="language-plaintext highlighter-rouge">.path</code></td>
      <td>文件或目录</td>
    </tr>
    <tr>
      <td>Scope unit</td>
      <td><code class="language-plaintext highlighter-rouge">.scope</code></td>
      <td>外部创建的进程</td>
    </tr>
    <tr>
      <td>Slice unit</td>
      <td><code class="language-plaintext highlighter-rouge">.slice</code></td>
      <td>A group of hierarchically organized units that manage system processes.</td>
    </tr>
    <tr>
      <td>Snapshot unit</td>
      <td><code class="language-plaintext highlighter-rouge">.snapshot</code></td>
      <td>系统快照</td>
    </tr>
    <tr>
      <td>Socket unit</td>
      <td><code class="language-plaintext highlighter-rouge">.socket</code></td>
      <td>套接字</td>
    </tr>
    <tr>
      <td>Swap unit</td>
      <td><code class="language-plaintext highlighter-rouge">.swap</code></td>
      <td>标识 swap 设备</td>
    </tr>
    <tr>
      <td>Timer unit</td>
      <td><code class="language-plaintext highlighter-rouge">.timer</code></td>
      <td>systemd 的计时器</td>
    </tr>
  </tbody>
</table>

<p>unit 文件保存位置</p>

<table>
  <thead>
    <tr>
      <th>Directory</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>/usr/lib/systemd/system/</td>
      <td>RPM 包安装时分发的 unit 文件</td>
    </tr>
    <tr>
      <td>/run/systemd/system/</td>
      <td>systemd 运行时创建的文件</td>
    </tr>
    <tr>
      <td>/etc/systemd/system/</td>
      <td>systemctl enable 创建的 unit 文件</td>
    </tr>
  </tbody>
</table>

<h3 id="管理系统服务">管理系统服务</h3>
<p>systemd 的主要命令行工具是  <code class="language-plaintext highlighter-rouge">systemctl</code> 。</p>

<p>多数管理员应该都已经非常熟悉系统服务和 init 系统的管理，比如 service、chkconfig 以及 telinit 命令的使用。
systemd 也完成同样的管理任务，只是命令工具 systemctl 的语法有所不同而已。</p>

<p>systemd 命令和 sysvinit 命令对比:</p>

<table>
  <thead>
    <tr>
      <th>service</th>
      <th>systemctl</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>service name start</td>
      <td>systemctl start name.service</td>
      <td>启动服务</td>
    </tr>
    <tr>
      <td>service name stop</td>
      <td>systemctl stop name.service</td>
      <td>停止服务</td>
    </tr>
    <tr>
      <td>service name restart</td>
      <td>systemctl restart name.service</td>
      <td>重启服务（没启动的服务会启动）</td>
    </tr>
    <tr>
      <td>service namecondrestart</td>
      <td>systemctl try-restart name.service</td>
      <td>只重启正在运行的服务</td>
    </tr>
    <tr>
      <td>service name reload</td>
      <td>systemctl reload name.service</td>
      <td>重载配置文件</td>
    </tr>
    <tr>
      <td>service name status</td>
      <td>systemctl status name.service</td>
      <td>检查服务状态</td>
    </tr>
    <tr>
      <td>service name status</td>
      <td>systemctl is-active name.service</td>
      <td>检查服务是否启动</td>
    </tr>
    <tr>
      <td>service –status-all</td>
      <td>systemctl list-units –type service –all</td>
      <td>显示所有的服务状态</td>
    </tr>
  </tbody>
</table>

<p>chkconfig 和 systemctl 命令对比:</p>

<table>
  <thead>
    <tr>
      <th>chkconfig</th>
      <th>systemctl</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>chkconfig name on</td>
      <td>systemctl enable name.service</td>
      <td>启用开机自启服务</td>
    </tr>
    <tr>
      <td>chkconfig name off</td>
      <td>systemctl disable name.service</td>
      <td>停用自启服务</td>
    </tr>
    <tr>
      <td>chkconfig –list name</td>
      <td>systemctl status name.service</td>
      <td>检查服务状态</td>
    </tr>
    <tr>
      <td>chkconfig –list name</td>
      <td>systemctl is-enabled name.service</td>
      <td>查看服务是否自启</td>
    </tr>
    <tr>
      <td>chkconfig –list</td>
      <td>systemctl list-unit-files –type service</td>
      <td>查看所有服务</td>
    </tr>
    <tr>
      <td>chkconfig –list</td>
      <td>systemctl list-dependencies –after</td>
      <td>列出在指定服务之前启动的服务（依赖）</td>
    </tr>
    <tr>
      <td>chkconfig –list</td>
      <td>systemctl list-dependencies –before</td>
      <td>列出在指定服务之后启动的服务（被依赖）</td>
    </tr>
  </tbody>
</table>

<hr />
<h3 id="参考资料">参考资料</h3>

<ol>
  <li>
    <p><a href="iframe.php?url=https%3A%2F%2Fwiki.archlinux.org%2Findex.php%2Fsystemd">systemd - ArchWiki</a></p>
  </li>
  <li>
    <p><a href="iframe.php?url=https%3A%2F%2Flinux.cn%2Farticle-5926-1.html">systemctl 命令完全指南</a></p>
  </li>
</ol>]]></content><author><name>Shuo</name></author><category term="Linux" /><category term="Tool" /><summary type="html"><![CDATA[systemd 是一个 Linux 系统基础组件的集合，提供了一个系统和服务管理器，运行为 PID 1 并负责启动其它程序。 功能包括：支持并行化任务；同时采用 socket 式与 D-Bus 总线式激活服务；按需启动守护进程（daemon）； 利用 Linux 的 cgroups 监视进程；支持快照和系统恢复；维护挂载点和自动挂载点；各服务间基于依赖关系进行精密控制。 systemd 支持 SysV 和 LSB 初始脚本，可以替代 sysvinit。 除此之外，功能还包括日志进程、控制基础系统配置，维护登陆用户列表以及系统账户、运行时目录和设置，可以运行容器和虚拟机， 可以简单的管理网络配置、网络时间同步、日志转发和名称解析等。]]></summary></entry></feed>