Create an account


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
LINUX Bash Variables: Environmental and Otherwise

#1
Bash Variables: Environmental and Otherwise

<div style="margin: 5px 5% 10px 5%;"><img src="http://www.sickgaming.net/blog/wp-content/uploads/2018/12/bash-variables-environmental-and-otherwise.jpg" width="1439" height="716" title="" alt="" /></div><div><div><img src="http://www.sickgaming.net/blog/wp-content/uploads/2018/12/bash-variables-environmental-and-otherwise.jpg" class="ff-og-image-inserted" /></div>
<p>Bash variables, including those pesky <i>environment variables</i>, have been popped up several times in previous articles, and it’s high time you get to know them better and how they can help you.</p>
<p>So, open your terminal window and let’s get started.</p>
<h3>Environment Variables</h3>
<p>Consider <code>HOME</code>. Apart from the cozy place where you lay down your hat, in Linux it is a variable that contains the path to the current user’s home directory. Try this:</p>
<pre>
echo $HOME
</pre>
<p>This will show the path to your home directory, usually <i>/home/</i>.</p>
<p>As the name indicates, variables can change according to the context. Indeed, each user on a Linux system will have a <code>HOME</code> variable containing a different value. You can also change the value of a variable by hand:</p>
<pre>
HOME=/home/&lt;<i>your username</i>&gt;/Documents
</pre>
<p>will make <code>HOME</code> point to your <i>Documents/</i> folder.</p>
<p>There are three things to notice here:</p>
<ol>
<li>There are no spaces between the name of the variable and the <code>=</code> or between the <code>=</code> and the value you are putting into the variable. Spaces have their own meaning in the shell and cannot be used any old way you want.</li>
<li>If you want to put a value into a variable or manipulate it in any way, you just have to write the name of the variable. If you want to see or use the contents of a variable, you put a <code>$</code> in front of it.</li>
<li>Changing <code>HOME</code> is risky! A lot programs rely on <code>HOME</code> to do stuff and changing it can have unforeseeable consequences. For example, just for laughs, change <code>HOME</code> as shown above and try typing <code>cd</code> and then [Enter]. As we have seen elsewhere in this series, you use <code>cd</code> to <i>c</i>hange to another <i>d</i>irectory. Without any parameters, <code>cd</code> takes you to your home directory. If you change the <code>HOME</code> variable, <code>cd</code> will take you to the new directory <code>HOME</code> points to.</li>
</ol>
<p>Changes to environment variables like the one described in point 3 above are not permanent. If you close your terminal and open it back up, or even open a new tab in your terminal window and move there, <code>echo $HOME</code> will show its original value.</p>
<p>Before we go on to how you make changes permanent, let’s look at another environment variable that it does make sense changing.</p>
<h3>PATH</h3>
<p>The <code>PATH</code> variable lists directories that contain executable programs. If you ever wondered where your applications go when they are installed and how come the shell seems to magically know which programs it can run without you having to tell it where to look for them, <code>PATH</code> is the reason.</p>
<p>Have a look inside <code>PATH</code> and you will see something like this:</p>
<pre>
$ <b>echo $PATH</b>
/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin
</pre>
<p>Each directory is separated by a colon (<code>:</code>) and if you want to run an application installed in any directory other than the ones listed in <code>PATH</code>, you will have to tell the shell where to find it:</p>
<pre>
/home/&lt;<i>user name</i>&gt;/bin/my_program.sh
</pre>
<p>This will run a program calle <i>my_program.sh</i> you have copied into a <i>bin/</i> directory in your home directory.</p>
<p>This is a common problem: you don’t want to clutter up your system’s <i>bin/</i> directories, or you don’t want other users running your own personal scripts, but you don’t want to have to type out the complete path every time you need to run a script you use often. The solution is to create your own <i>bin/</i> directory in your home directory:</p>
<pre>
mkdir $HOME/bin
</pre>
<p>And then tell <code>PATH</code> all about it:</p>
<pre>
PATH=$PATH:$HOME/bin
</pre>
<p>After that, your <i>/home//bin</i> will show up in your <code>PATH</code> variable. But… Wait! We said that the changes you make in a given shell will not last and will lose effect when that shell is closed.</p>
<p>To make changes permanent for your user, instead of running them directly in the shell, put them into a file that gets run every time a shell is started. That file already exists and lives in your home directory. It is called <i>.bashrc</i> and the dot in front of the name makes it a hidden file — a regular <code>ls</code> won’t show it, but <code>ls -a</code> will.</p>
<p>You can open it with a text editor like <a href="https://www.kde.org/applications/utilities/kate/">kate</a>, <a href="https://help.gnome.org/users/gedit/stable/">gedit</a>, <a href="https://www.nano-editor.org/">nano</a>, or <a href="https://www.vim.org/">vim</a> (NOT LibreOffice Writer — that’s a word processor. Different beast entirely). You will see that <i>.bashrc</i> is full of shell commands the purpose of which are to set up the environment for your user.</p>
<p>Scroll to the bottom and add the following on a new, empty line:</p>
<pre>
export PATH=$PATH:$HOME/bin
</pre>
<p>Save and close the file. You’ll be seeing what <code>export</code> does presently. In the meantime, to make sure the changes take effect immediately, you need to <code>source</code> <i>.bashrc</i>:</p>
<pre>
source .bashrc
</pre>
<p>What <code>source</code> does is execute <i>.bashrc</i> for the current open shell, and all the ones that come after it. The alternative would be to log out and log back in again for the changes to take effect, and who has the time for that?</p>
<p>From now on, your shell will find every program you dump in <i>/home//bin</i> without you having to specify the whole path to the file.</p>
<h3>DYI Variables</h3>
<p>You can, of course, make your own variables. All the ones we have seen have been written with ALL CAPS, but <a href="https://bash.cyberciti.biz/guide/Rules_for_Naming_variable_name">you can call a variable more or less whatever you want</a>.</p>
<p>Creating a new variables is straightforward: just set a value within it:</p>
<pre>
new_variable="Hello"
</pre>
<p>And you already know how to recover a value contained within a variable:</p>
<pre>
echo $new_variable
</pre>
<p>You often have a program that will require you set up a variable for things to work properly. The variable may set an option to “on”, or help the program find a library it needs, and so on. When you run a program in Bash, the shell spawns a daughter process. This means it is not exactly the same shell that executes your program, but a related mini-shell that inherits some of the mother’s characteristics. Unfortunately, variables, by default, are not one of them. This is because, by default again, variables are <i>local</i>. This means that, for security reasons, a variable set in one shell cannot be read in another, even if it is a daughter shell.</p>
<p>To see what I mean, set a variable:</p>
<pre>
robots="R2D2 &amp; C3PO"
</pre>
<p>… and run:</p>
<pre>
bash
</pre>
<p>You just ran a Bash shell program within a Bash shell program.</p>
<p>Now see if you can read the contents of you variable with:</p>
<pre>
echo $robots
</pre>
<p>You should draw a blank.</p>
<p>Still inside your bash-within-bash shell, set <code>robots</code> to something different:</p>
<pre>
robots="These aren't the ones you are looking for"
</pre>
<p>Check <code>robots</code>‘ value:</p>
<pre>
$ <b>echo $robots</b>
These aren't the ones you are looking for
</pre>
<p>Exit the bash-within-bash shell:</p>
<pre>
exit
</pre>
<p>And re-check the value of <code>robots</code>:</p>
<pre>
$ <b>echo $robots</b>
R2D2 &amp; C3P0
</pre>
<p>This is very useful to avoid all sorts of messed up configurations, but this presents a problem also: if a program requires you set up a variable, but the program can’t access it because Bash will execute it in a daughter process, what can you do? That is exactly what <code>export</code> is for.</p>
<p>Try doing the prior experiment, but, instead of just starting off by setting <code>robots="R2D2 &amp; C3PO"</code>, export it at the same time:</p>
<pre>
export robots="R2D2 &amp; C3PO"
</pre>
<p>You’ll notice that, when you enter the bash-within-bash shell, <code>robots</code> still retains the same value it had at the outset.</p>
<p><b>Interesting fact:</b> While the daughter process will “inherit” the value of an exported variable, if the variable is changed within the daughter process, changes will not flow upwards to the mother process. In other words, changing the value of an exported variable in a daughter process does not change the value of the original variable in the mother process.</p>
<p>You can see all exported variables by running</p>
<pre>
export -p
</pre>
<p>The variables you create should be at the end of the list. You will also notice some other interesting variables in the list: <code>USER</code>, for example, contains the current user’s user name; <code>PWD</code> points to the current directory; and <code>OLDPWD</code> contains the path to the last directory you visited and since left. That’s because, if you run:</p>
<pre>
cd -
</pre>
<p>You will go back to the last directory you visited and <code>cd</code> gets the information from <code>OLDPWD</code>.</p>
<p>You can also see all the environment variables using the <code>env</code> command.</p>
<p>To un-export a variable, use the <code>-n</code> option:</p>
<pre>
export -n robots
</pre>
<h3>Next Time</h3>
<p>You have now reached a level in which you are dangerous to yourself and others. It is time you learned how to protect yourself from yourself by making your environment safer and friendlier through the use of <i>aliases, </i>and that is exactly what we’ll be tackling in the next episode. See you then.</p>
</div>
Reply



Forum Jump:


Users browsing this thread:
3 Guest(s)

Forum software by © MyBB Theme © iAndrew 2016