<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: dunkbing</title>
    <description>The latest articles on DEV Community by dunkbing (@dunkbing).</description>
    <link>https://dev.to/dunkbing</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F549114%2F2551d52a-1b13-4dab-893e-6fd078c3f715.jpg</url>
      <title>DEV Community: dunkbing</title>
      <link>https://dev.to/dunkbing</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dunkbing"/>
    <language>en</language>
    <item>
      <title>A Minimal Note-Taking System with Vim, fzf, and Git</title>
      <dc:creator>dunkbing</dc:creator>
      <pubDate>Sun, 14 Dec 2025 05:47:26 +0000</pubDate>
      <link>https://dev.to/dunkbing/a-minimal-note-taking-system-with-vim-fzf-and-git-4deo</link>
      <guid>https://dev.to/dunkbing/a-minimal-note-taking-system-with-vim-fzf-and-git-4deo</guid>
      <description>&lt;p&gt;I wanted to share a simple note-taking workflow that's fast, works offline, and doesn't lock me into any platform. Here's a ~80 line &lt;a href="https://github.com/dunkbing/dunkbing/blob/main/note" rel="noopener noreferrer"&gt;bash script&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Setup
&lt;/h2&gt;

&lt;p&gt;Notes live in &lt;code&gt;~/notes&lt;/code&gt; as plain markdown files. That's it. No database, no app, no subscription.&lt;/p&gt;

&lt;h2&gt;
  
  
  Daily Notes
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;note              &lt;span class="c"&gt;# opens ~/notes/2024-12-14.md&lt;/span&gt;
note ideas        &lt;span class="c"&gt;# opens ~/notes/ideas.md&lt;/span&gt;
note work/standup &lt;span class="c"&gt;# opens ~/notes/work/standup.md&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The script creates parent directories automatically, so organizing by project or topic is effortless.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding Things
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;note &lt;span class="nt"&gt;-l&lt;/span&gt;           &lt;span class="c"&gt;# list all notes, sorted by recent&lt;/span&gt;
note &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"keyword"&lt;/span&gt; &lt;span class="c"&gt;# search content across all notes&lt;/span&gt;
note &lt;span class="nt"&gt;-t&lt;/span&gt;           &lt;span class="c"&gt;# find all unchecked todos&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fizf6nylfsxd417imjh5c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fizf6nylfsxd417imjh5c.png" alt="list" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F42yacqbjxszomiv81hhw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F42yacqbjxszomiv81hhw.png" alt="todo" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All powered by &lt;code&gt;fzf&lt;/code&gt; with preview. I can fuzzy-find through hundreds of notes instantly and jump to the exact line.&lt;/p&gt;

&lt;h2&gt;
  
  
  Syncing
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;note &lt;span class="nb"&gt;sync&lt;/span&gt;           &lt;span class="c"&gt;# sync with git&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First run initializes the repo and asks for a remote URL. After that, it pulls, commits changes with a timestamp, and pushes. Simple backup and multi-device sync.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Works
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Speed&lt;/strong&gt;: vim opens instantly. no electron, no loading screens (or you can choose whatever editor you want).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portable&lt;/strong&gt;: plain text works everywhere, forever.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Searchable&lt;/strong&gt;: grep + fzf.&lt;/li&gt;
&lt;li&gt;Git history is free time travel.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No vendor lock-in&lt;/strong&gt;: your notes are just files.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>note</category>
      <category>markdown</category>
      <category>vim</category>
    </item>
    <item>
      <title>Using rclone and launchd to sync data to Google Drive on MacOS</title>
      <dc:creator>dunkbing</dc:creator>
      <pubDate>Thu, 31 Oct 2024 14:39:41 +0000</pubDate>
      <link>https://dev.to/dunkbing/using-rclone-and-launchd-to-sync-data-to-google-drive-on-macos-150j</link>
      <guid>https://dev.to/dunkbing/using-rclone-and-launchd-to-sync-data-to-google-drive-on-macos-150j</guid>
      <description>&lt;p&gt;Rclone is an open-source tool that we can copy our files or store on various cloud storage providers.&lt;/p&gt;

&lt;p&gt;In this post, I'll use Rclone to sync data on MacOS with rclone + launchd (Mac daemons manager). You may ask why not just use built-in cloud sync? It's because I've been using Google Drive for a long time to back up my data and photos, and the Google Drive desktop app lacks flexibility in file exclusion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;I'm on Mac, so I'll use &lt;code&gt;brew&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;rclone
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To use Rclone, you need to configure it first, granting it access to the cloud service of your choice. These are the configuration process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Open your terminal and run the following command to initiate the configuration setup:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rclone config
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The configuration will prompt you to create a new remote connection. Choose option &lt;code&gt;n&lt;/code&gt; for a new remote.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnxfwza5przde9wwzt7lk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnxfwza5przde9wwzt7lk.png" alt="new-config" width="241" height="135"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Next, you'll be prompted to name your remote connection. Give it a descriptive name, such as "Google Drive" or any name you prefer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select the number corresponding to the cloud storage provider you want to use. It's 18 for my case. (You can refer to the &lt;a href="https://rclone.org/docs/" rel="noopener noreferrer"&gt;official RClone documentation&lt;/a&gt; for specific details on each provider.)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdh7abuhygis7b1nnmdy4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdh7abuhygis7b1nnmdy4.png" alt="select-storage" width="381" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Leave the client ID and secret empty when prompted, and choose y to allow RClone to use the Google Drive API without these credentials.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The browser will automatically open and authenticate RClone with the remote.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F72bw9unxt5tha7gmkzll.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F72bw9unxt5tha7gmkzll.png" alt="authenticate-rclone" width="800" height="682"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Confirm your settings and the remote connection should be successfully configured.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, you have set up &lt;strong&gt;rclone&lt;/strong&gt; to access your cloud storage. You can repeat these steps if you want to configure additional remotes for different cloud providers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Syncing Data with &lt;strong&gt;rclone&lt;/strong&gt; and Launchd
&lt;/h2&gt;

&lt;p&gt;Now, let's move on to syncing data using RClone and scheduling it with Launchd:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a file named 'exclude-file.txt' to specify the files that you want to ignore from syncing. Mine looks like this.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8l3mkt1ftut6rp8vcthy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8l3mkt1ftut6rp8vcthy.png" alt="exclude-file" width="404" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a simple bash script to sync your data. Let's call it &lt;code&gt;sync.sh&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

rclone &lt;span class="nb"&gt;sync&lt;/span&gt; &lt;span class="nt"&gt;--config&lt;/span&gt; ~/path/to/secure/location/rclone.conf /path/to/local/folder remote:destination/folder
rclone bisync &lt;span class="nt"&gt;--progress&lt;/span&gt; &lt;span class="nt"&gt;--exclude-from&lt;/span&gt; ~/.config/rclone/exclude-file.txt &lt;span class="nt"&gt;--resync&lt;/span&gt; &lt;span class="nt"&gt;--verbose&lt;/span&gt; /path/to/local/folder remote:destination/folder
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Replace &lt;code&gt;/path/to/local/folder&lt;/code&gt; with the path to the local folder you want to sync and &lt;code&gt;remote:destination/folder&lt;/code&gt; with the remote destination on your cloud storage.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Make the script executable:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x sync.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now, let's schedule the sync using Launchd. Create a new Launchd plist file, for example, &lt;code&gt;com.example.rclone-sync.plist&lt;/code&gt;. Use a text editor to add the following content:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;plist&lt;/span&gt; &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;"1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;Label&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;com.example.rclone-sync&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;Program&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;/path/to/your/sync.sh&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;RunAtLoad&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;StartInterval&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;integer&amp;gt;&lt;/span&gt;3600&lt;span class="nt"&gt;&amp;lt;/integer&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plist&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Replace &lt;code&gt;/path/to/your/sync.sh&lt;/code&gt; with the actual path to your &lt;code&gt;sync.sh&lt;/code&gt; script.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Move the Launchd plist file to the appropriate directory:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mv &lt;/span&gt;com.example.rclone-sync.plist ~/Library/LaunchAgents/
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Load the Launchd job:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;launchctl load ~/Library/LaunchAgents/com.example.rclone-sync.plist
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, your data will be automatically synced at the specified intervals using RClone and Launchd.&lt;/p&gt;

</description>
      <category>google</category>
      <category>cli</category>
      <category>productivity</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Create a simple web app with Deno's Fresh</title>
      <dc:creator>dunkbing</dc:creator>
      <pubDate>Sat, 11 Nov 2023 09:54:06 +0000</pubDate>
      <link>https://dev.to/dunkbing/create-a-simple-web-app-with-denos-fresh-pg5</link>
      <guid>https://dev.to/dunkbing/create-a-simple-web-app-with-denos-fresh-pg5</guid>
      <description>&lt;p&gt;Hi everyone! In this post, I'll guide you through creating a simple website using the Fresh framework and explore its various features.&lt;/p&gt;

&lt;p&gt;Fresh is a full-stack JavaScript framework built on Deno. It's easy to set up and comes with cool features like quick rendering, no build step, built-in Typescript support, and island architecture (partial hydration).&lt;/p&gt;

&lt;h3&gt;
  
  
  What Am I Building?
&lt;/h3&gt;

&lt;p&gt;I'm creating a straightforward speech-to-text web app using the Google Translate API. Check out the live demo app &lt;a href="https://text2audio.cc" rel="noopener noreferrer"&gt;here&lt;/a&gt;. You can find the complete code for this tutorial in my GitHub &lt;a href="https://github.com/dunkbing/text2audio" rel="noopener noreferrer"&gt;repository&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pre-requisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Deno 1.3x&lt;/li&gt;
&lt;li&gt;Familiarity with React and TypeScript&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Creating a New Fresh App
&lt;/h3&gt;

&lt;p&gt;Run the following commands to generate a new Fresh application:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

deno run &lt;span class="nt"&gt;-A&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; https://fresh.deno.dev text2audio
&lt;span class="nb"&gt;cd &lt;/span&gt;text2audio
deno task start


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Visit localhost:8080 to explore your new Fresh app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqnlrxe5smzak2uru6gzt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqnlrxe5smzak2uru6gzt.png" alt="new-fresh-app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The project you create will include three main folders:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;routes:&lt;/strong&gt; Handles routing, similar to frameworks like Next.js. Each file corresponds to a route or pattern, and each folder represents a sub-route. Routes can have handlers to manage the verb and define actions like rendering or returning a response.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;static:&lt;/strong&gt; Stores static assets resolved using "/" in HTML templates and CSS files. Caching can be managed using assets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;islands:&lt;/strong&gt; Contains interactive islands in your project. Each file's name corresponds to the defined island. The code within this folder can run on both the client and server.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Writing the Frontend and the API
&lt;/h3&gt;

&lt;p&gt;Let's implement a Text Form and an API endpoint:&lt;/p&gt;

&lt;p&gt;1) &lt;strong&gt;Text Form:&lt;/strong&gt; Utilizes a POST form to submit to the &lt;code&gt;/audio&lt;/code&gt; API to generate audio. Check out the code here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjb6s1lwz2zvxtaf1z56c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjb6s1lwz2zvxtaf1z56c.png" alt="text-form"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2) &lt;strong&gt;API:&lt;/strong&gt; Creates an API endpoint &lt;code&gt;/api/audio&lt;/code&gt; with a POST request to generate audio from text. View the code here.&lt;/p&gt;

&lt;p&gt;Additionally, I use DenoKV to store the total generated audio, which looks like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

   &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;increaseTotalAudio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;voicesEntry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;kv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;voicesEntryKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
       &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentTotal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;voicesEntry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;kv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;voicesEntryKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentTotal&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;increaseTotalAudio error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;For storing and serving audio files, I use Cloudflare R2, an S3-compatible storage service.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deployments
&lt;/h3&gt;

&lt;p&gt;The site is deployed with Deno Deploy, linking your Git repository to a Deno project on Deploy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq9gnts9grnok0yo0x7b2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq9gnts9grnok0yo0x7b2.png" alt="deno-deploy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alternatively, you can use Docker with the provided Dockerfile.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;p&gt;Fresh excels at boosting performance, as verified through PageSpeed Insights, generating a comprehensive report with all tested metrics.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9af8nvfyvnapyxxxeoe8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9af8nvfyvnapyxxxeoe8.png" alt="page-speed"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Fresh is an interesting framework, targeting monolithic applications, especially those combining frontend and backend with robust SSR. Despite some limitations, Fresh shows promise for a bright future. I hope you find this post helpful!&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>deno</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Managing My Resume with Git: A Version Control Approach</title>
      <dc:creator>dunkbing</dc:creator>
      <pubDate>Sun, 05 Nov 2023 11:39:44 +0000</pubDate>
      <link>https://dev.to/dunkbing/managing-my-resume-with-git-a-version-control-approach-7hk</link>
      <guid>https://dev.to/dunkbing/managing-my-resume-with-git-a-version-control-approach-7hk</guid>
      <description>&lt;p&gt;In today's dynamic job market, maintaining an up-to-date and organized resume is crucial. However, it can be a challenging task without the right tools. In this post, I'll share with you how I manage my resume with Git, Github Actions, Makefile, and branching strategies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Use Git for Your Resume?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiwheren5f0l5hph2vp5h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiwheren5f0l5hph2vp5h.png" alt="My repo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Version Control&lt;/strong&gt;: Git allows you to maintain different versions of your resume over time. This means you can keep a history of changes and easily switch between different versions, such as a general resume, one tailored for a specific job application, and more.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Collaboration&lt;/strong&gt;: If you're working with others on a project or sharing your resume for feedback, Git makes collaboration a breeze. You can collaborate with others and merge changes seamlessly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Backup and Safety&lt;/strong&gt;: Git not only tracks changes but also serves as a backup system. Your resume is stored securely, and you can retrieve previous versions if needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Streamlined Workflow&lt;/strong&gt;: Git simplifies the process of creating, editing, and formatting your resume. You can use plain text files (Markdown, for instance) and generate different formats (PDF, DOCX) when needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting Up Git for Resume Management
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Create a Git Repository&lt;/strong&gt;: Start by creating a Git repository for your resume. This can be done with a simple &lt;code&gt;git init&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Resume File&lt;/strong&gt;: Save your resume in a text format (Markdown is a popular choice). This makes it easy to track changes and keep it under version control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Versioning&lt;/strong&gt;: Each time you make an update, commit the changes with a descriptive message. For example: "Updated skills section" or "Added new project experience."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Branches&lt;/strong&gt;: Consider using branches to manage different versions of your resume. Create branches for specific job applications, skills variations, or different styles.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Makefile for Resume Management&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;A Makefile can simplify the process of converting your Markdown resume to different formats (PDF, DOCX) using Pandoc. Here's my sample Makefile:&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="c"&gt;# Convert Markdown (resume.md) to DOCX and PDF&lt;br&gt;
&lt;/span&gt;&lt;br&gt;
&lt;span class="nv"&gt;RESUME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; resume.md&lt;br&gt;
&lt;span class="nv"&gt;OUTPUT_DIR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; output&lt;/p&gt;

&lt;p&gt;&lt;span class="nl"&gt;all&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;docx pdf&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="nl"&gt;docx&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;br&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;OUTPUT_DIR&lt;span class="p"&gt;)&lt;/span&gt;&lt;br&gt;
    pandoc &lt;span class="p"&gt;$(&lt;/span&gt;RESUME&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;OUTPUT_DIR&lt;span class="p"&gt;)&lt;/span&gt;/resume.docx&lt;/p&gt;

&lt;p&gt;&lt;span class="nl"&gt;pdf&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;br&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;OUTPUT_DIR&lt;span class="p"&gt;)&lt;/span&gt;&lt;br&gt;
    pandoc &lt;span class="p"&gt;$(&lt;/span&gt;RESUME&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;OUTPUT_DIR&lt;span class="p"&gt;)&lt;/span&gt;/resume.pdf&lt;/p&gt;

&lt;p&gt;&lt;span class="nl"&gt;clean&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;br&gt;
    &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;OUTPUT_DIR&lt;span class="p"&gt;)&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="nl"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;all docx pdf clean&lt;/span&gt;&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Benefits of Using Markdown&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;Markdown is a lightweight markup language that is easy to read and write. It's an excellent choice for managing your resume with Git. Here's why:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simplicity&lt;/strong&gt;: Markdown is a plain text format that's easy to edit and understand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portability&lt;/strong&gt;: Markdown files can be converted to various formats (PDF, DOCX, HTML) using tools like Pandoc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency&lt;/strong&gt;: Markdown ensures your resume looks consistent across different devices and platforms.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Generating Different Formats
&lt;/h3&gt;

&lt;p&gt;With Git and Markdown, you can generate different formats of your resume as needed. Tools like Pandoc or online services like GitHub Actions can help you automatically build PDF, DOCX, and other formats from your Markdown source.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8g6fcnx8r6aexprmjcd7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8g6fcnx8r6aexprmjcd7.png" alt="Github Action for generating pdf"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Branching Strategies
&lt;/h3&gt;

&lt;p&gt;To effectively manage different versions of your resume, consider using branching strategies. Here are a few ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Main Branch&lt;/strong&gt;: Use the master branch for your general resume.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feature Branches&lt;/strong&gt;: Create feature branches for specific job applications or tailored versions of your resume.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Styling Branches&lt;/strong&gt;: Experiment with different styling and formatting in dedicated branches.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2iwrmm6d60qagzco2gql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2iwrmm6d60qagzco2gql.png" alt="Resume branches"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Collaboration and Sharing
&lt;/h3&gt;

&lt;p&gt;If you're working with others on your resume or seeking feedback, Git simplifies the process. You can use platforms like GitHub or GitLab to host your resume repository and collaborate with colleagues or peers. Others can suggest changes, and you can easily review and incorporate their feedback.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Managing your resume with Git not only simplifies the process but also makes it more efficient and organized. You can maintain a history of changes, collaborate with others, and generate different formats with ease. Plus, it's a great way to ensure your resume is always up-to-date and ready for the next career opportunity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/dunkbing/dunkbing" rel="noopener noreferrer"&gt;This is the GitHub Repository of my Resume&lt;/a&gt;&lt;br&gt;
If you have any thoughts or suggestions on how to improve my resume, please give me a comment below. Whether it's about the content, formatting, or anything else :)&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>githubactions</category>
      <category>markdown</category>
    </item>
    <item>
      <title>Basic process management in Linux</title>
      <dc:creator>dunkbing</dc:creator>
      <pubDate>Sat, 06 May 2023 19:26:28 +0000</pubDate>
      <link>https://dev.to/dunkbing/basic-process-management-in-linux-39bg</link>
      <guid>https://dev.to/dunkbing/basic-process-management-in-linux-39bg</guid>
      <description>&lt;h2&gt;
  
  
  What is a Process in Unix/Linux?
&lt;/h2&gt;

&lt;p&gt;One of the notable features of Unix/Linux is the ability to run multiple programs simultaneously. The Operating System sees each executable entity it controls as a process. A program can consist of multiple processes combined. For the Operating System, processes work together to share the CPU processing speed, and use shared memory, and other system resources. Processes are scheduled in a round-robin manner by the Operating System.&lt;/p&gt;

&lt;p&gt;As a system programmer, system administrator, or DevOps, most of your time will be spent working on Unix/Linux systems. Commands are used to interact with the operating system when working on Unix/Linux. Each command on Unix/Linux when executed will run a process or a group of processes. Therefore, understanding processes and the skills to manage and use processes on Unix/Linux systems is essential. In this article, I will introduce you to the basic knowledge and skills to manage processes on Unix/Linux systems.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frkjap4dwnavb3kbxam9o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frkjap4dwnavb3kbxam9o.png" alt="Linux processes" width="300" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Terminologies
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PID&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each process has a unique PID (Process Identify) throughout the system at the time the process is running.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PPID&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each process has a parent process with the identification of PPID (Parent process ID). Child processes are usually started by parent processes. A parent process can have multiple child processes, but a child process can have only one parent process.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;init&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;strong&gt;init&lt;/strong&gt; process is the first process started after you select the Operating System in the boot loader. In the process tree, the init process is the parent process of other processes. The init process has the following characteristics: + PID = 1 + Cannot kill the init process.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;kill&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When a process stops running, it dies. When you want to kill a process, you need to kill it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;daemon&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A daemon process is a background process. These processes are started when the system is booted up and will continue to run indefinitely.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;zombie&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A zombie is a leftover part of a process that has stopped working but has not been cleaned up. And, yes, zombie means zombie, meaning that process has died and you cannot "kill" it again. Programs that leave zombie processes after exiting mean that the program was poorly programmed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic process management in Linux
&lt;/h2&gt;

&lt;p&gt;=====================================&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;$$ và $PPID&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some shell environment variables contain information about processes. The variable &lt;code&gt;$$&lt;/code&gt; holds your current process ID and &lt;code&gt;$PPID&lt;/code&gt; holds the PID of the parent process. In fact, &lt;code&gt;$$&lt;/code&gt; is a shell parameter and not a variable, you cannot assign a value to it. Below, I use the &lt;code&gt;echo&lt;/code&gt; command to display the values of &lt;code&gt;$$&lt;/code&gt; and &lt;code&gt;$PPID&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; $ echo $$ $PPID
2024173 1946762
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;pidof&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the &lt;code&gt;pidof&lt;/code&gt; command, you can search for all process IDs by name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;pidof nginx
1978170 1978169 1978168 1978167 538
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;parent and child&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Processes have parent-child relationships. Every process has a parent process. When starting a new shell, you can use echo to verify that the previous pid is the &lt;code&gt;ppid&lt;/code&gt; of the new shell. The above child process has become the parent process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;bash
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$$&lt;/span&gt; &lt;span class="nv"&gt;$PPID&lt;/span&gt;
2041129 2024173
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter &lt;code&gt;exit&lt;/code&gt; to end the current process and see the values of &lt;code&gt;$$&lt;/code&gt; and &lt;code&gt;$PPID&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;bash
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$$&lt;/span&gt; &lt;span class="nv"&gt;$PPID&lt;/span&gt;
2045905 1946762
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$$&lt;/span&gt; &lt;span class="nv"&gt;$PPID&lt;/span&gt;
2046134 1946762
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;fork và exec&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A process starts another process in two stages. First, the process creates a copy (fork) of itself, exactly like it. Then, the forked process performs an execution (exec) to replace the forked process with the child process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$$&lt;/span&gt;
2046315
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;bash
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$$&lt;/span&gt; &lt;span class="nv"&gt;$PPID&lt;/span&gt;
2046471 2046315
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;exec&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the &lt;code&gt;exec&lt;/code&gt; command, you can execute a process without creating a new process. In the example below, the Korn shell (ksh) is launched and being replaced by a bash shell using the &lt;code&gt;exec&lt;/code&gt; command. The PID of the bash shell is also the same as the PID of the Korn shell. Exiting the child bash shell will bring me back to the parent bash shell, not back to the Korn shell (no longer exists).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$$&lt;/span&gt;
2024173 &lt;span class="c"&gt;# PID of bash&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;ksh
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$$&lt;/span&gt; &lt;span class="nv"&gt;$PPID&lt;/span&gt;
2040691 2024173
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;exit
exit&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$$&lt;/span&gt;
2024173
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ps&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the most common tools on Linux to view processes is &lt;code&gt;ps&lt;/code&gt;. The following example shows the parent-child relationship between three bash processes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$$&lt;/span&gt; &lt;span class="nv"&gt;$PPID&lt;/span&gt;
2047247 2047214
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;bash
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$$&lt;/span&gt; &lt;span class="nv"&gt;$PPID&lt;/span&gt;
2047837 2047247
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;bash
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$$&lt;/span&gt; &lt;span class="nv"&gt;$PPID&lt;/span&gt;
2047904 2047837
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;ps &lt;span class="nt"&gt;-fx&lt;/span&gt;
    PID     TTY      STAT   TIME COMMAND
    2047214 ?        Ss     0:00  &lt;span class="se"&gt;\_&lt;/span&gt; sshd: root@pts/44
    2047247 pts/44   Ss     0:00  |   &lt;span class="se"&gt;\_&lt;/span&gt; &lt;span class="nt"&gt;-bash&lt;/span&gt;
    2047837 pts/44   S      0:00  |       &lt;span class="se"&gt;\_&lt;/span&gt; bash
    2047904 pts/44   S      0:00  |           &lt;span class="se"&gt;\_&lt;/span&gt; bash
    2047977 pts/44   R+     0:00  |               &lt;span class="se"&gt;\_&lt;/span&gt; ps &lt;span class="nt"&gt;-fx&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;exit
exit&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;ps &lt;span class="nt"&gt;-fx&lt;/span&gt;
    PID     TTY      STAT   TIME COMMAND
    2047214 ?        Ss     0:00  &lt;span class="se"&gt;\_&lt;/span&gt; sshd: root@pts/44
    2047247 pts/44   Ss     0:00  |   &lt;span class="se"&gt;\_&lt;/span&gt; &lt;span class="nt"&gt;-bash&lt;/span&gt;
    2047837 pts/44   S      0:00  |       &lt;span class="se"&gt;\_&lt;/span&gt; bash
    2048248 pts/44   R+     0:00  |           &lt;span class="se"&gt;\_&lt;/span&gt; ps &lt;span class="nt"&gt;-fx&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;exit
exit&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;ps &lt;span class="nt"&gt;-fx&lt;/span&gt;
    PID     TTY      STAT   TIME COMMAND
    2047214 ?        Ss     0:00  &lt;span class="se"&gt;\_&lt;/span&gt; sshd: root@pts/44
    2047247 pts/44   Ss     0:00  |   &lt;span class="se"&gt;\_&lt;/span&gt; &lt;span class="nt"&gt;-bash&lt;/span&gt;
    2048522 pts/44   R+     0:00  |       &lt;span class="se"&gt;\_&lt;/span&gt; ps &lt;span class="nt"&gt;-fx&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Linux, &lt;code&gt;ps -fax&lt;/code&gt; is a commonly used command. On Solaris, &lt;code&gt;ps -ef&lt;/code&gt; (which also works on Linux) is more popular. Here is a sample output from the ps -fax command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;ps &lt;span class="nt"&gt;-fax&lt;/span&gt;
PID TTY STAT TIME COMMAND
1 ? S 0:00 init &lt;span class="o"&gt;[&lt;/span&gt;5]
...
2046788 ?        Ss     0:00  &lt;span class="se"&gt;\_&lt;/span&gt; sshd: &lt;span class="o"&gt;[&lt;/span&gt;accepted]
2046789 ?        S      0:00  |   &lt;span class="se"&gt;\_&lt;/span&gt; sshd: &lt;span class="o"&gt;[&lt;/span&gt;net]
2047214 ?        Ss     0:00  &lt;span class="se"&gt;\_&lt;/span&gt; sshd: root@pts/44
2047247 pts/44   Ss     0:00      &lt;span class="se"&gt;\_&lt;/span&gt; &lt;span class="nt"&gt;-bash&lt;/span&gt;
2047273 pts/44   R+     0:00          &lt;span class="se"&gt;\_&lt;/span&gt; ps &lt;span class="nt"&gt;-fax&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;pgrep&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Just like &lt;code&gt;ps -C&lt;/code&gt;, you can utilize &lt;code&gt;pgrep&lt;/code&gt; to find a process by its command name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sleep &lt;/span&gt;1000 &amp;amp;
&lt;span class="o"&gt;[&lt;/span&gt;1] 2048730
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;pgrep &lt;span class="nb"&gt;sleep
&lt;/span&gt;2048730
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;ps &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="nb"&gt;sleep
    &lt;/span&gt;PID TTY          TIME CMD
2048730 pts/44   00:00:00 &lt;span class="nb"&gt;sleep&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also list the command name of a process with &lt;code&gt;pgrep&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;pgrep &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nb"&gt;sleep
&lt;/span&gt;2048730 &lt;span class="nb"&gt;sleep&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;top&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A popular and perhaps familiar tool for Linux users is &lt;code&gt;top&lt;/code&gt;. The tool can show a table of currently running processes in real-time, as well as the CPU and memory usage of the system. it also provides many different options that allow you to sort processes by CPU, usage, or other attributes. Additionally, you can kill processes with &lt;code&gt;top&lt;/code&gt;. Overall, I think this is an important tool that is both intuitive and easy to use for Linux system administrators in general.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F33rs2qvohsx47zgi973v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F33rs2qvohsx47zgi973v.png" alt="top" width="800" height="703"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The main parameters for the top command are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-h&lt;/code&gt; - Display the current version&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-c&lt;/code&gt; - This parameter toggles the command column state from showing command names to program names and vice versa&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-d&lt;/code&gt; - Specify the delay time when refreshing the screen&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-o&lt;/code&gt; - Sort by a named field&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-p&lt;/code&gt; - Display only processes with specified IDs&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-u&lt;/code&gt; - Display only processes of a specified user&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-i&lt;/code&gt; - Do not display idle tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Additionally, while &lt;code&gt;top&lt;/code&gt; is running, you can enable and disable many features, change the display by pressing relevant keys. The &lt;code&gt;top&lt;/code&gt; command has some additional parameters, you can learn more about them by using the &lt;code&gt;man top&lt;/code&gt; command on the command line.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Above, I have just shared some basic skills and frequently used commands to manage processes on Unix/Linux operating systems.&lt;/p&gt;

&lt;p&gt;Thank you for reading!&lt;/p&gt;

</description>
      <category>linux</category>
      <category>systems</category>
    </item>
    <item>
      <title>Terminal chat application</title>
      <dc:creator>dunkbing</dc:creator>
      <pubDate>Sun, 28 Aug 2022 19:56:34 +0000</pubDate>
      <link>https://dev.to/dunkbing/terminal-chat-application-pp1</link>
      <guid>https://dev.to/dunkbing/terminal-chat-application-pp1</guid>
      <description>&lt;h3&gt;
  
  
  Overview of My Submission
&lt;/h3&gt;

&lt;p&gt;A very simple chat application inside the terminal. The app uses the pubsub to publish the messages to other channel, implemented using Golang which is the programing language that I recently learn.&lt;/p&gt;

&lt;h3&gt;
  
  
  Submission Category:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Wacky Wildcards&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Language Used
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Go 1.18 for developing the app.&lt;/li&gt;
&lt;li&gt;Use the bubbletea framework for making the terminal ui.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Link to Code
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/dunkbing"&gt;
        dunkbing
      &lt;/a&gt; / &lt;a href="https://github.com/dunkbing/tchat"&gt;
        tchat
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A simple chatapp with Golang and Redis Pub/Sub
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Terminal chat application&lt;/h1&gt;
&lt;p&gt;A simple chat application inside the terminal with Golang and Redis Pub/Sub.&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/dunkbing/tchatscreenshots/1.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--77crpMDJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/dunkbing/tchatscreenshots/1.png" alt=""&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/dunkbing/tchatscreenshots/2.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Okpv1vAa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/dunkbing/tchatscreenshots/2.png" alt=""&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/dunkbing/tchatscreenshots/3.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--874Gg_4E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/dunkbing/tchatscreenshots/3.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
How it works&lt;/h2&gt;
&lt;h3&gt;
How the data is stored:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The chat data is stored as keys
&lt;ul&gt;
&lt;li&gt;For each channel contents, the &lt;code&gt;channel:&lt;/code&gt; is  the prefix key, followed by the channel name.&lt;/li&gt;
&lt;li&gt;For each message contents, the &lt;code&gt;message:&lt;/code&gt; is the prefix key, followed by the &lt;code&gt;channel-name&lt;/code&gt; and the &lt;code&gt;message-data&lt;/code&gt; in json format.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
How the data is accessed:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Here is the sample code to access the channel's messages with Go Redis:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight highlight-source-go notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;# &lt;span class="pl-s1"&gt;Get&lt;/span&gt; &lt;span class="pl-s1"&gt;the&lt;/span&gt; &lt;span class="pl-s1"&gt;channel&lt;/span&gt;'s &lt;span class="pl-s1"&gt;messages&lt;/span&gt;
&lt;span class="pl-s1"&gt;ctx&lt;/span&gt; &lt;span class="pl-c1"&gt;:=&lt;/span&gt; &lt;span class="pl-s1"&gt;context&lt;/span&gt;.&lt;span class="pl-en"&gt;Background&lt;/span&gt;()
&lt;span class="pl-s1"&gt;iter&lt;/span&gt; &lt;span class="pl-c1"&gt;:=&lt;/span&gt; &lt;span class="pl-s1"&gt;redis&lt;/span&gt;.&lt;span class="pl-c1"&gt;Client&lt;/span&gt;.&lt;span class="pl-en"&gt;Scan&lt;/span&gt;(&lt;span class="pl-s1"&gt;ctx&lt;/span&gt;, &lt;span class="pl-c1"&gt;0&lt;/span&gt;, &lt;span class="pl-s1"&gt;fmt&lt;/span&gt;.&lt;span class="pl-en"&gt;Sprintf&lt;/span&gt;(&lt;span class="pl-s"&gt;"%s%s*"&lt;/span&gt;, &lt;span class="pl-s1"&gt;messagePrefix&lt;/span&gt;, &lt;span class="pl-s1"&gt;m&lt;/span&gt;.&lt;span class="pl-c1"&gt;channel&lt;/span&gt;), &lt;span class="pl-c1"&gt;0&lt;/span&gt;).&lt;span class="pl-en"&gt;Iterator&lt;/span&gt;()  
&lt;span class="pl-k"&gt;var&lt;/span&gt; &lt;span class="pl-s1"&gt;messages&lt;/span&gt; []&lt;span class="pl-smi"&gt;string&lt;/span&gt;  
&lt;span class="pl-k"&gt;for&lt;/span&gt; &lt;span class="pl-s1"&gt;iter&lt;/span&gt;.&lt;span class="pl-en"&gt;Next&lt;/span&gt;(&lt;span class="pl-s1"&gt;ctx&lt;/span&gt;) {  
   &lt;span class="pl-s1"&gt;rawMsg&lt;/span&gt; &lt;span class="pl-c1"&gt;:=&lt;/span&gt; &lt;span class="pl-s1"&gt;iter&lt;/span&gt;.&lt;span class="pl-en"&gt;Val&lt;/span&gt;()  
   &lt;span class="pl-s1"&gt;rawMsg&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;strings&lt;/span&gt;.&lt;span class="pl-en"&gt;Replace&lt;/span&gt;(&lt;span class="pl-s1"&gt;rawMsg&lt;/span&gt;, &lt;span class="pl-s1"&gt;fmt&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/dunkbing/tchat"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  Additional Resources / Info
&lt;/h3&gt;

&lt;p&gt;None&lt;/p&gt;

&lt;h3&gt;
  
  
  Collaborators
&lt;/h3&gt;

&lt;p&gt;&lt;a class="mentioned-user" href="https://dev.to/dunkbing"&gt;@dunkbing&lt;/a&gt;&lt;/p&gt;




</description>
      <category>redishackathon</category>
      <category>redis</category>
      <category>go</category>
    </item>
  </channel>
</rss>
