<?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>Forem: Rizky Zhang</title>
    <description>The latest articles on Forem by Rizky Zhang (@rizkyzhang).</description>
    <link>https://forem.com/rizkyzhang</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%2F549333%2F1a7edf67-2680-4f29-a39f-447dd9eafc81.jpeg</url>
      <title>Forem: Rizky Zhang</title>
      <link>https://forem.com/rizkyzhang</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/rizkyzhang"/>
    <language>en</language>
    <item>
      <title>Golang sqlx PostgreSQL Get Last Inserted Row ID</title>
      <dc:creator>Rizky Zhang</dc:creator>
      <pubDate>Mon, 28 Nov 2022 13:15:04 +0000</pubDate>
      <link>https://forem.com/rizkyzhang/golang-sqlx-postgresql-get-last-inserted-row-id-291k</link>
      <guid>https://forem.com/rizkyzhang/golang-sqlx-postgresql-get-last-inserted-row-id-291k</guid>
      <description>&lt;p&gt;Sometime after inserting a row, we might need to get the id usually for creating referenced table with foreign key of id. We can try to use &lt;code&gt;db.NamedExec&lt;/code&gt; or &lt;code&gt;db.Exec&lt;/code&gt; to do the operation since it will return a &lt;code&gt;sql.Result&lt;/code&gt; interface which have &lt;code&gt;LastInsertId()&lt;/code&gt; method inside it. The problem since we are using PostgreSQL with &lt;code&gt;pgx&lt;/code&gt; driver, this method is not supported as stated in the documentation: &lt;strong&gt;In MySQL, for instance, LastInsertId() will be available on inserts with an auto-increment key, but in PostgreSQL, this information can only be retrieved from a normal row cursor by using the RETURNING clause.&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The workaround is to take advantage of &lt;code&gt;RETURNING&lt;/code&gt; clause that returns the updated row and combine it with &lt;code&gt;db.GetContext&lt;/code&gt; or &lt;code&gt;db.QueryRowx&lt;/code&gt; to get the query result, I will use &lt;code&gt;db.GetContext&lt;/code&gt; here.&lt;/p&gt;

&lt;p&gt;For example, we have a &lt;code&gt;productPayload&lt;/code&gt; struct that we are going to insert.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;productPayload&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;UID&lt;/span&gt;         &lt;span class="kt"&gt;string&lt;/span&gt;                  &lt;span class="s"&gt;`db:"uid" json:"uid"`&lt;/span&gt;
    &lt;span class="n"&gt;Name&lt;/span&gt;        &lt;span class="kt"&gt;string&lt;/span&gt;                  &lt;span class="s"&gt;`db:"name" json:"name"`&lt;/span&gt;
    &lt;span class="n"&gt;Slug&lt;/span&gt;        &lt;span class="kt"&gt;string&lt;/span&gt;                  &lt;span class="s"&gt;`db:"slug" json:"slug"`&lt;/span&gt;
    &lt;span class="n"&gt;SKU&lt;/span&gt;         &lt;span class="kt"&gt;string&lt;/span&gt;                  &lt;span class="s"&gt;`db:"sku" json:"sku"`&lt;/span&gt;
    &lt;span class="n"&gt;Description&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;                  &lt;span class="s"&gt;`db:"description" json:"description"`&lt;/span&gt;
    &lt;span class="n"&gt;Image&lt;/span&gt;       &lt;span class="kt"&gt;string&lt;/span&gt;                  &lt;span class="s"&gt;`db:"image" json:"image"`&lt;/span&gt;

    &lt;span class="n"&gt;CreatedAt&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Time&lt;/span&gt; &lt;span class="s"&gt;`db:"created_at" json:"created_at"`&lt;/span&gt;
    &lt;span class="n"&gt;UpdatedAt&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Time&lt;/span&gt; &lt;span class="s"&gt;`db:"updated_at" json:"updated_at"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here is the full code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BindNamed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`
    INSERT INTO products (uid, name, slug, sku, description, image, created_at, updated_at)
    VALUES (:uid, :name, :slug, :sku, :description, :image, :created_at, :updated_at)
    RETURNING id;
    `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;productPayload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;productID&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;
&lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;productID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The usage of &lt;code&gt;db.BindNamed&lt;/code&gt; is optional, I use it because I want to convert my &lt;code&gt;productPayload&lt;/code&gt; struct into slice of positioned arguments, so I don't need to manually pass it to the &lt;code&gt;db.GetContext&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I hope this article is useful for you, if it is please share it with your friends, thank you so much for reading to the end and see you in the next article!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Fix TP-Link TL-WN722N Not Working on Linux</title>
      <dc:creator>Rizky Zhang</dc:creator>
      <pubDate>Wed, 10 Aug 2022 15:27:09 +0000</pubDate>
      <link>https://forem.com/rizkyzhang/fix-tp-link-tl-wn722n-not-working-on-linux-4fl1</link>
      <guid>https://forem.com/rizkyzhang/fix-tp-link-tl-wn722n-not-working-on-linux-4fl1</guid>
      <description>&lt;p&gt;This issue has been bugging me since last year. It started when I am still running Linux Mint, suddenly after an update, my wireless adapter stop working suddenly. I try to find a way to fix it on Google, but did not found any working solutions. Because I am quite busy at that time, I simply used USB tethering to get around it, and soon forget about the problem.&lt;/p&gt;

&lt;p&gt;Early this year, I decided to try MX Linux because it seems to be more lightweight and stable (once a year release compared to monthly release which mean less crash) than Linux Mint. I did notice the performance is noticeably better, and I never have a crash or bug anymore after update, overall it is very stable, but the wireless adapter problem still persist, so clearly the problem is not the OS.&lt;/p&gt;

&lt;p&gt;Tonight I remembered about the issue and because I am still curious about it, I decided to research about the issues again with a fresh approach. The first thing I do is running &lt;code&gt;lsusb&lt;/code&gt; command on the terminal after I connected my wireless adapter. This is the output:&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%2F0rj0fhfx22r8emsutnqt.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%2F0rj0fhfx22r8emsutnqt.png" alt=" lsusb output" width="706" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Gotcha! I found the needed driver version for my wireless adapter which is &lt;code&gt;RTL8188EUS&lt;/code&gt;. I then run &lt;code&gt;lsmod | grep 8188&lt;/code&gt; to check whether the driver is loaded or not on the kernel, turn out it is not installed yet.&lt;/p&gt;

&lt;p&gt;After a brief google search for the driver, I found it on &lt;a href="https://github.com/aircrack-ng/rtl8188eus" rel="noopener noreferrer"&gt;https://github.com/aircrack-ng/rtl8188eus&lt;/a&gt;. I tried the instruction there, but sadly it still doesn't work. Suddenly I got an idea to try this command &lt;code&gt;echo "blacklist r8188eu" | sudo tee /etc/modprobe.d/r8188eu.conf&lt;/code&gt; and restart the computer. Finally, it's working! To spare you from wasting time like me, I will give you the precise step here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Connect your wireless adapter&lt;/li&gt;
&lt;li&gt;Open your terminal and run &lt;code&gt;lsusb&lt;/code&gt; to find your driver model, if it is not the same as mine, you can modify this tutorial by searching the driver model that match yours on Google and modify the last command to &lt;code&gt;echo "blacklist &amp;lt;driver-model&amp;gt;" | sudo tee/etc/modprobe.d/&amp;lt;driver-model&amp;gt;.conf&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Disconnect your wireless adapter and connect to internet with USB tethering from your phone&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sudo apt-get install mokutil &amp;amp;&amp;amp; mokutil --sb-state&lt;/code&gt;, if it output &lt;code&gt;SecureBoot disabled&lt;/code&gt; you can proceed to the next step, otherwise you need to turn off the secure boot option from the BIOS because it can possibly interfere with the driver installation&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git clone https://github.com/aircrack-ng/rtl8188eus&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cd rtl8188eus&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;make &amp;amp;&amp;amp; sudo make install&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;echo "blacklist r8188eu" | sudo tee /etc/modprobe.d/r8188eu.conf&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Restart computer&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Important note: you might need to repeat the steps again after updating your Linux because the driver might got replaced.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I hope my article is useful to you, see you in the next article!&lt;/p&gt;

</description>
      <category>linux</category>
      <category>todayilearned</category>
      <category>tutorial</category>
      <category>wifi</category>
    </item>
    <item>
      <title>Setup Multiple SSH Keys for Multiple GitHub Accounts</title>
      <dc:creator>Rizky Zhang</dc:creator>
      <pubDate>Wed, 10 Aug 2022 15:26:50 +0000</pubDate>
      <link>https://forem.com/rizkyzhang/setup-multiple-ssh-keys-for-multiple-github-accounts-393l</link>
      <guid>https://forem.com/rizkyzhang/setup-multiple-ssh-keys-for-multiple-github-accounts-393l</guid>
      <description>&lt;p&gt;Imagine this scenario, you have 3 GitHub accounts, each have their own purposes. Account A for full time work, account B for portfolio projects and account C for personal projects. Whenever you are going to switch between repo in different accounts, you will need to use a different SSH keys for each account.&lt;/p&gt;

&lt;p&gt;Changing SSH config every time you are switching is not good use of your time. Now you might start to think it is possible to have multiple SSH keys for each account and let SSH automatically manage it? Yeah, it is possible, but it can be quite tricky because there is a gotcha which I will explain further in this article.&lt;/p&gt;

&lt;p&gt;I am assuming you are running Linux and already have OpenSSH installed. For Mac, you should be fine. For Windows, you need to have git bash installed or WSL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating SSH keys
&lt;/h2&gt;

&lt;p&gt;The first thing we need to do is to create a SSH key for each account.&lt;br&gt;
Go to your terminal and run each command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;ssh&lt;/span&gt;-&lt;span class="n"&gt;keygen&lt;/span&gt; -&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="n"&gt;rsa&lt;/span&gt; -&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="m"&gt;4096&lt;/span&gt; -&lt;span class="n"&gt;f&lt;/span&gt; ~/.&lt;span class="n"&gt;ssh&lt;/span&gt;/&lt;span class="n"&gt;id_rsa_fulltime&lt;/span&gt; -&lt;span class="n"&gt;C&lt;/span&gt; &lt;span class="s2"&gt;"fulltime@mail.com"&lt;/span&gt;
&lt;span class="n"&gt;ssh&lt;/span&gt;-&lt;span class="n"&gt;keygen&lt;/span&gt; -&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="n"&gt;rsa&lt;/span&gt; -&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="m"&gt;4096&lt;/span&gt; -&lt;span class="n"&gt;f&lt;/span&gt; ~/.&lt;span class="n"&gt;ssh&lt;/span&gt;/&lt;span class="n"&gt;id_rsa_portfolio&lt;/span&gt; -&lt;span class="n"&gt;C&lt;/span&gt; &lt;span class="s2"&gt;"portfolio@mail.com"&lt;/span&gt;
&lt;span class="n"&gt;ssh&lt;/span&gt;-&lt;span class="n"&gt;keygen&lt;/span&gt; -&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="n"&gt;rsa&lt;/span&gt; -&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="m"&gt;4096&lt;/span&gt; -&lt;span class="n"&gt;f&lt;/span&gt; ~/.&lt;span class="n"&gt;ssh&lt;/span&gt;/&lt;span class="n"&gt;id_rsa_personal&lt;/span&gt; -&lt;span class="n"&gt;C&lt;/span&gt; &lt;span class="s2"&gt;"personal@mail.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first command is going to create a SSH key for full time account that are connected with the specified Github email: &lt;a href="mailto:fulltime@mail.com"&gt;fulltime@mail.com&lt;/a&gt; and save it into the specified path: &lt;code&gt;~/.ssh/id_rsa_fulltime&lt;/code&gt;.&lt;br&gt;
The second and third commands do the same thing respectively for portfolio account and personal account.&lt;/p&gt;
&lt;h2&gt;
  
  
  Adding SSH Keys Into SSH Authentication Agent
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;ssh&lt;/span&gt;-&lt;span class="n"&gt;add&lt;/span&gt; ~/.&lt;span class="n"&gt;ssh&lt;/span&gt;/&lt;span class="n"&gt;id_rsa_fulltime&lt;/span&gt;
&lt;span class="n"&gt;ssh&lt;/span&gt;-&lt;span class="n"&gt;add&lt;/span&gt; ~/.&lt;span class="n"&gt;ssh&lt;/span&gt;/&lt;span class="n"&gt;id_rsa_portfolio&lt;/span&gt;
&lt;span class="n"&gt;ssh&lt;/span&gt;-&lt;span class="n"&gt;add&lt;/span&gt; ~/.&lt;span class="n"&gt;ssh&lt;/span&gt;/&lt;span class="n"&gt;id_rsa_personal&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Creating SSH Config File
&lt;/h2&gt;

&lt;p&gt;Now you need to go to &lt;code&gt;~/.ssh&lt;/code&gt; and create a file named &lt;code&gt;config&lt;/code&gt; inside it. Open it with vim or other text editor and add the following configurations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;Host&lt;/span&gt; *
&lt;span class="n"&gt;AddKeysToAgent&lt;/span&gt; &lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;IdentitiesOnly&lt;/span&gt; &lt;span class="n"&gt;yes&lt;/span&gt;

&lt;span class="n"&gt;Host&lt;/span&gt; &lt;span class="n"&gt;github&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;-&lt;span class="n"&gt;fulltime&lt;/span&gt;
&lt;span class="n"&gt;HostName&lt;/span&gt; &lt;span class="n"&gt;github&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="n"&gt;IdentityFile&lt;/span&gt; ~/.&lt;span class="n"&gt;ssh&lt;/span&gt;/&lt;span class="n"&gt;id_rsa_fulltime&lt;/span&gt;

&lt;span class="n"&gt;Host&lt;/span&gt; &lt;span class="n"&gt;github&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;-&lt;span class="n"&gt;portfolio&lt;/span&gt;
&lt;span class="n"&gt;HostName&lt;/span&gt; &lt;span class="n"&gt;github&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="n"&gt;IdentityFile&lt;/span&gt; ~/.&lt;span class="n"&gt;ssh&lt;/span&gt;/&lt;span class="n"&gt;id_rsa_portfolio&lt;/span&gt;

&lt;span class="n"&gt;Host&lt;/span&gt; &lt;span class="n"&gt;github&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;-&lt;span class="n"&gt;personal&lt;/span&gt;
&lt;span class="n"&gt;HostName&lt;/span&gt; &lt;span class="n"&gt;github&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="n"&gt;IdentityFile&lt;/span&gt; ~/.&lt;span class="n"&gt;ssh&lt;/span&gt;/&lt;span class="n"&gt;id_rsa_personal&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Host *&lt;/code&gt; means the config will be applied to every host, not only &lt;code&gt;github.com-prefix&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;AddKeysToAgent&lt;/code&gt; tells SSH to remember your passphrase, so you don't need to enter it every time, only on every new login session.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;IdentitiesOnly&lt;/code&gt; is the gotcha I mean earlier. Let's say you are currently authenticated with fulltime account, and you want to switch to personal account. If you did not specify it, &lt;strong&gt;SSH will continue to use the first authenticated SSH key even though we have already specified different SSH key for each account&lt;/strong&gt;, in this case it will continue to use fulltime SSH key for each account.&lt;/p&gt;

&lt;p&gt;The postfix (eg -personal) after &lt;code&gt;github.com&lt;/code&gt; is used to identify different SSH keys, you can name it whatever you like but it should be unique, usually I named it the context in which the GitHub account is used for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Setup
&lt;/h2&gt;

&lt;p&gt;If you already have an existing cloned repo from GitHub, you need to go the repo directory and edit &lt;code&gt;.git/config&lt;/code&gt; file to append identifier postfix to the github.com hostname.&lt;/p&gt;

&lt;p&gt;For example, you already clone a repo named &lt;code&gt;personal-project&lt;/code&gt; from your personal account, to connect the correct SSH key to the repo you have to append this postfix &lt;code&gt;-personal&lt;/code&gt; to the &lt;code&gt;github.com&lt;/code&gt; hostname.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;remote&lt;/span&gt; &lt;span class="s2"&gt;"origin"&lt;/span&gt;]
&lt;span class="n"&gt;url&lt;/span&gt; = &lt;span class="n"&gt;git&lt;/span&gt;@&lt;span class="n"&gt;github&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;-&lt;span class="n"&gt;personal&lt;/span&gt;:&lt;span class="n"&gt;personal&lt;/span&gt;-&lt;span class="n"&gt;account&lt;/span&gt;/&lt;span class="n"&gt;personal&lt;/span&gt;-&lt;span class="n"&gt;project&lt;/span&gt;.&lt;span class="n"&gt;git&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to clone a new repo. Simply append the identifier postfix to the &lt;code&gt;github.com&lt;/code&gt; hostname of the clone url.&lt;br&gt;
&lt;code&gt;git clone git@github.com-personal:personal-account/personal-project.git&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After that, you will need to set up Github username and email for the repo by running these commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config user.name &lt;span class="s2"&gt;"personal-account"&lt;/span&gt;
git config user.email &lt;span class="s2"&gt;"personal@mail.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Additional config if SSH still keep asking for passphrase (optional)
&lt;/h2&gt;

&lt;p&gt;I encounter this problem recently and was so confused at first, luckily I found a &lt;a href="https://junyonglee.me/ssh/How-to-permanently-add-private-key-passphrase-to-ssh-agent/" rel="noopener noreferrer"&gt;blog post&lt;/a&gt; which explains how to fix this issue using &lt;code&gt;keychain&lt;/code&gt; library. &lt;code&gt;keychain&lt;/code&gt; library is used to&lt;br&gt;
store SSH passphrase for one login session, so you only need to enter passphrase one time per login session.&lt;/p&gt;

&lt;p&gt;First install the library if you haven't installed it:&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="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;keychain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add this to the start of your shell config, &lt;code&gt;.zshrc&lt;/code&gt; if you are using zsh or &lt;code&gt;.bashrc&lt;/code&gt; if you are using bash.&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="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; Linux &lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
  /usr/bin/keychain &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.ssh/id_rsa_personal
  /usr/bin/keychain &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.ssh/id_rsa_portfolio
  /usr/bin/keychain &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.ssh/id_rsa_fulltime
&lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.keychain/&lt;span class="nv"&gt;$HOST&lt;/span&gt;&lt;span class="nt"&gt;-sh&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;/usr/bin/keychain&lt;/code&gt; command will prompt for ssh passphrase for every login session and save it to &lt;code&gt;$HOME/.keychain/$HOST-sh&lt;/code&gt;, in this case because we have 3 keys, it will be prompted 3 times.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: complete SSH keys automation!
&lt;/h2&gt;

&lt;p&gt;Currently we still need to append identifier postfix to the &lt;code&gt;github.com&lt;/code&gt; hostname every time we clone a new repo so SSH know which key to be used.&lt;/p&gt;

&lt;p&gt;This can be very repetitive and prone to typo. Is it possible to only specify the postfix only once? Yes, it is possible with the help &lt;code&gt;.gitconfig&lt;/code&gt;. With this solution you also don't need to set email and username anymore.&lt;/p&gt;

&lt;p&gt;For example, you have a personal SSH key and a directory named personal which contains repositories, you want it to use personal SSH key automatically. Here's the step to make it automatic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a &lt;code&gt;.gitconfig&lt;/code&gt; in the root of personal directory.&lt;/li&gt;
&lt;li&gt;Specify email, username and identifier postfix in below format.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;user&lt;/span&gt;]
  &lt;span class="n"&gt;email&lt;/span&gt; = &lt;span class="n"&gt;test&lt;/span&gt;@&lt;span class="n"&gt;gmail&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt; = &lt;span class="n"&gt;test&lt;/span&gt;

[&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="s2"&gt;"git@github.com-personal"&lt;/span&gt;]
  &lt;span class="n"&gt;insteadOf&lt;/span&gt; = &lt;span class="n"&gt;git&lt;/span&gt;@&lt;span class="n"&gt;github&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a global &lt;code&gt;.gitconfig&lt;/code&gt; in your home directory to tell SSH which local &lt;code&gt;.gitconfig&lt;/code&gt; to use for personal directory by specifying the path.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;includeif&lt;/span&gt; &lt;span class="s2"&gt;"gitdir:~/Projects/personal/"&lt;/span&gt;]
  &lt;span class="n"&gt;path&lt;/span&gt; = ~/&lt;span class="n"&gt;Projects&lt;/span&gt;/&lt;span class="n"&gt;personal&lt;/span&gt;/.&lt;span class="n"&gt;gitconfig&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now try to clone a repository, SSH will automatically choose the correct SSH key.&lt;/p&gt;

&lt;p&gt;Congratulations, you have successfully setup multiple SSH keys.&lt;/p&gt;

&lt;p&gt;See you in the next article!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ssh</category>
      <category>git</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
