<?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: Ivo Karaneshev</title>
    <description>The latest articles on DEV Community by Ivo Karaneshev (@ivokara).</description>
    <link>https://dev.to/ivokara</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%2F1174084%2F7c9c8708-7365-4d85-aaf1-8725fe895ef2.jpeg</url>
      <title>DEV Community: Ivo Karaneshev</title>
      <link>https://dev.to/ivokara</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ivokara"/>
    <language>en</language>
    <item>
      <title>Appending environment variables to PATH the easy way (Linux)</title>
      <dc:creator>Ivo Karaneshev</dc:creator>
      <pubDate>Wed, 04 Oct 2023 18:12:44 +0000</pubDate>
      <link>https://dev.to/ivokara/appending-environment-variables-to-path-the-easy-way-linux-jjb</link>
      <guid>https://dev.to/ivokara/appending-environment-variables-to-path-the-easy-way-linux-jjb</guid>
      <description>&lt;h2&gt;
  
  
  Appending to PATH variable
&lt;/h2&gt;

&lt;p&gt;In Linux, you have seen something like this&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;export &lt;/span&gt;&lt;span class="nv"&gt;SOME_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;
&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SOME_ENV&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which append the env variable value to &lt;code&gt;PATH&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It is really annoying to do this on the command line. So Linux guys suggest putting this in the &lt;code&gt;~/.bashrc&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Excellent. &lt;/p&gt;

&lt;p&gt;But it can become a real mess quickly because there is all other important stuff in &lt;code&gt;.bashrc&lt;/code&gt;. &lt;br&gt;&lt;br&gt;
I don't feel it right to have everything bash-related bumped into one file.&lt;/p&gt;
&lt;h2&gt;
  
  
  Quick fix
&lt;/h2&gt;

&lt;p&gt;So I decided to move all of my configured env variables to a separate file instead of messing things up in &lt;code&gt;.bashrc&lt;/code&gt;.&lt;br&gt;
I called it &lt;code&gt;.bash_envs&lt;/code&gt; and placed it in my home directory (where &lt;code&gt;.bashrc&lt;/code&gt; is located).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I also separated bash functions and aliases into &lt;br&gt;
&lt;code&gt;.bash_functions&lt;/code&gt; and &lt;code&gt;.bash_aliases&lt;/code&gt; respectively with the same idea in mind&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In order to work properly, &lt;code&gt;.bashrc&lt;/code&gt; needs to know about and execute the &lt;code&gt;.bash_envs&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;So to accomplish this I wrote the following code in &lt;code&gt;.bashrc&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="c"&gt;#Exported env definitions.&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; ~/.bash_envs  &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
    &lt;span class="nb"&gt;.&lt;/span&gt; ~/.bash_envs
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also &lt;code&gt;.bash_envs&lt;/code&gt; file needs to be executable so I typed a quick:&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;chmod&lt;/span&gt; +x .bash_envs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the content of &lt;code&gt;.bash_envs&lt;/code&gt; includes something like this:&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="c"&gt;#!/bin/bash&lt;/span&gt;
...

&lt;span class="c"&gt;# java&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;JAVA_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/usr/lib/jvm/java-21-openjdk-amd64"&lt;/span&gt;
&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$JAVA_HOME&lt;/span&gt;&lt;span class="s2"&gt;/bin:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# pnpm &lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PNPM_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.local/share/pnpm"&lt;/span&gt;
&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PNPM_HOME&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Perfect.&lt;/p&gt;

&lt;p&gt;But to be honest, it is really annoying to type &lt;code&gt;PATH=...&lt;/code&gt; every time an env variable is exported.&lt;/p&gt;

&lt;p&gt;So I came up with a better idea.&lt;/p&gt;

&lt;h2&gt;
  
  
  The improvement
&lt;/h2&gt;

&lt;p&gt;If I could somehow store the required paths in something like an array, then join the items with a colon symbol (&lt;code&gt;:&lt;/code&gt;), and finally append it to &lt;code&gt;PATH&lt;/code&gt;? &lt;/p&gt;

&lt;p&gt;Wait a second, there are arrays in &lt;code&gt;bash&lt;/code&gt; and I could do something like this:&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="nv"&gt;path_envs&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;
    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$JAVA_HOME&lt;/span&gt;&lt;span class="s2"&gt;/bin"&lt;/span&gt;
    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PNPM_HOME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    ...
&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But actually, I think it's better to &lt;em&gt;append&lt;/em&gt; every item immediately after the env variable &lt;code&gt;export&lt;/code&gt;, because otherwise you can easily miss an item and you have to manually check if everything is as you expect.&lt;/p&gt;

&lt;p&gt;Then the code should become something like this:&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="nv"&gt;path_envs&lt;/span&gt;&lt;span class="o"&gt;=()&lt;/span&gt; &lt;span class="c"&gt;# defining an empty array&lt;/span&gt;

&lt;span class="c"&gt;# java&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;JAVA_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/usr/lib/jvm/java-21-openjdk-amd64"&lt;/span&gt;
path_envs+&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$JAVA_HOME&lt;/span&gt;&lt;span class="s2"&gt;/bin"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c"&gt;# appending java path to array&lt;/span&gt;

&lt;span class="c"&gt;# pnpm&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PNPM_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.local/share/pnpm"&lt;/span&gt;
path_envs+&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PNPM_HOME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c"&gt;# appending pnpm path to array&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So far so good. But how to actually join items with a colon &lt;code&gt;:&lt;/code&gt;? &lt;/p&gt;

&lt;p&gt;There are plenty of solutions but the easiest one I found was this:&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="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt; &lt;span class="nv"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;":"&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;path_envs&lt;/span&gt;&lt;span class="p"&gt;[*]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't worry I will explain step by step the above code snippet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Explanation
&lt;/h3&gt;

&lt;h4&gt;
  
  
  $( Dollar Single Parentheses )
&lt;/h4&gt;

&lt;p&gt;So the &lt;code&gt;$( ... )&lt;/code&gt; parentheses part means that everything inside will be executed in a &lt;em&gt;subshell&lt;/em&gt; and the result will be returned as a string.&lt;/p&gt;

&lt;p&gt;For example:&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;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hello, my name is &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt; &lt;span class="nb"&gt;whoami&lt;/span&gt; &lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="c"&gt;# =&amp;gt; "Hello, my name is ivo"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Internal Field Separator (IFS)
&lt;/h4&gt;

&lt;p&gt;The content inside the paratheses is more interesting. The first part (before the semicolon &lt;code&gt;;&lt;/code&gt;) sets the special variable &lt;strong&gt;Internal Field Separator&lt;/strong&gt; (&lt;code&gt;IFS&lt;/code&gt;) with a value of colon &lt;code&gt;:&lt;/code&gt;. &lt;br&gt;
This in short means it treats &lt;code&gt;:&lt;/code&gt; as a separator between words/items in a string instead of whitespace which is the default.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;More detailed information with examples about &lt;code&gt;IFS&lt;/code&gt; can be found &lt;a href="https://www.baeldung.com/linux/ifs-shell-variable"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The second part just prints the &lt;code&gt;path_envs&lt;/code&gt; array of its items separated by &lt;code&gt;IFS&lt;/code&gt;. One notable detail is that &lt;code&gt;path_envs[*]&lt;/code&gt; is used instead of &lt;code&gt;path_env[@]&lt;/code&gt; for expanding the array, because &lt;code&gt;[*]&lt;/code&gt; returns a single shell-word with all of the elements of the array separated by &lt;code&gt;IFS&lt;/code&gt; (as we need), while &lt;code&gt;[@]&lt;/code&gt; leads to each element of the array being treated as a separate shell-word.&lt;/p&gt;

&lt;p&gt;As a result, the subshell should return something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/usr/lib/jvm/java-21-openjdk-amd64:/home/ivo/.local/share/pnpm...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Final result
&lt;/h3&gt;

&lt;p&gt;All of that is finally concatenated with the old value of &lt;code&gt;PATH&lt;/code&gt; and simply that was the work we should do.&lt;/p&gt;

&lt;p&gt;In the end, my &lt;code&gt;.bash_envs&lt;/code&gt; file looked something like this:&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="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="nv"&gt;path_envs&lt;/span&gt;&lt;span class="o"&gt;=()&lt;/span&gt;

&lt;span class="c"&gt;# java&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;JAVA_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/usr/lib/jvm/java-21-openjdk-amd64"&lt;/span&gt;
path_envs+&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$JAVA_HOME&lt;/span&gt;&lt;span class="s2"&gt;/bin"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# pnpm&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PNPM_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.local/share/pnpm"&lt;/span&gt;
path_envs+&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PNPM_HOME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# adding path_envs to PATH&lt;/span&gt;
&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt; &lt;span class="nv"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;":"&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;path_envs&lt;/span&gt;&lt;span class="p"&gt;[*]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>bash</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
