Introduction
In this lab, you will learn the fundamentals of managing the shell environment and configuration in Linux. You will begin by creating both local and environment variables, using commands like echo, export, and env to understand the key differences in their scope and availability within a shell session.
Building on this foundation, you will explore how variables and aliases are inherited in child shells. You will also learn how to control automatic variable exporting with the set -o allexport option and how to make your custom configurations persistent across sessions by modifying the .bashrc file.
Create and Differentiate Local and Environment Variables
In this step, you will learn how to create and manage shell variables. In a Linux shell like Zsh, variables are used to store information. There are two main types: local variables and environment variables.
- A local variable (or shell variable) is only available within the shell where it was created.
- An environment variable is available not only in the current shell but also in any child processes started from that shell.
We will use commands like echo, export, and env to work with them. All commands will be executed in the terminal.
First, let's create a local variable. In your terminal, which is already in the ~/project directory, type the following command to create a variable named flower and assign it the value rose. Note that there must be no spaces around the equals sign (=).
flower=rose
To verify that the variable was created, you can use the echo command to print its value. The dollar sign ($) before the variable name tells the shell to substitute the variable with its value.
echo $flower
You should see the value of the variable printed to the terminal:
rose
Now, let's check if this local variable is part of the shell's environment. The env command lists all environment variables. We can pipe its output to grep to search for our variable.
env | grep flower
This command will produce no output. This is the expected result, and it confirms that flower is a local variable, not an environment variable.
Next, let's create an environment variable. The process is similar, but we use the export command. This command creates a variable and marks it to be passed to all child processes of the current shell. Let's create an environment variable named nut with the value almond.
export nut=almond
Let's verify it with echo just like we did before.
echo $nut
The command will output the value of the nut variable:
almond
Now, let's check if it exists in the environment using the env command again.
env | grep nut
This time, the command finds and displays the variable, confirming that nut is an environment variable:
nut=almond
You have now successfully created both a local and an environment variable and have seen the fundamental difference in how they are treated by the shell's environment. We will leave these variables set for use in the next steps.
Test Variable and Alias Inheritance in a Child Shell
In this step, you will explore how variables and aliases behave when you start a new shell from your current one. This new shell is called a "child shell," and the original shell is the "parent shell." This concept is crucial for understanding how shell environments are structured and how scripts execute. We will test whether the variables flower and nut from the previous step are passed down, or "inherited," by a child shell.
First, let's identify the Process ID (PID) of our current parent shell. Every process in Linux has a unique PID. You can view it with the echo $$ command.
echo $$
Your output will be a number, which is the PID of your current shell. For example:
123
Now, start a child shell by simply typing zsh and pressing Enter. This creates a new shell process inside your current one.
zsh
You are now in a new shell session. To confirm this, we can use the ps -f command, which shows detailed process information, including the Parent Process ID (PPID).
ps -f
Look at the output. You will see two zsh processes. The PID of the new zsh process should have a PPID that matches the PID of the parent shell you noted earlier.
UID PID PPID C STIME TTY TIME CMD
labex 123 1 0 10:00 pts/0 00:00:00 zsh
labex 456 123 0 10:01 pts/0 00:00:00 zsh
labex 457 456 0 10:01 pts/0 00:00:00 ps -f
In this example, the new shell (PID 456) is a child of the original shell (PPID 123).
Now, let's test the variables. In this child shell, try to display the value of the local variable flower.
echo $flower
The command produces no output. This is because local variables are confined to the shell in which they are created and are not inherited by child shells.
Next, check the environment variable nut.
echo $nut
This time, the shell prints the value of the variable:
almond
This demonstrates that environment variables, unlike local variables, are inherited by child shells.
Now, let's return to the parent shell by using the exit command.
exit
You are now back in your original shell. Let's perform a similar test with an alias. An alias is a shortcut for a command. Create an alias named ldetc that executes ls -ld /etc.
alias ldetc='ls -ld /etc'
Verify the alias was created by typing alias.
alias ldetc
You should see the definition of your alias:
ldetc='ls -ld /etc'
Now, test the alias by running it.
ldetc
The command will execute ls -ld /etc and show you the details of the /etc directory.
drwxr-xr-x 1 root root 4096 Oct 10 10:00 /etc
Now, open another child shell to see if the alias is inherited.
zsh
Inside the new child shell, try to use the ldetc alias.
ldetc
You will receive an error message, because aliases, like local variables, are not inherited by child shells.
zsh: command not found: ldetc
Return to the parent shell.
exit
Finally, let's clean up by removing the alias from the parent shell using the unalias command.
unalias ldetc
Verify its removal by trying to list it again.
alias ldetc
Nothing is returned.
This exercise has shown you a key principle of shell behavior: environment variables are inherited by child processes, but local variables and aliases are not.
Control Automatic Variable Export with set -o allexport
In this step, you will learn about a powerful shell option called allexport. Normally, when you create a variable, you must explicitly use the export command to make it an environment variable. However, by enabling the allexport option, you can instruct the shell to automatically export every new variable you define. This can be a convenient shortcut, especially in scripts where all variables need to be available to sub-processes.
Shell options are internal settings that change the behavior of your shell. You can turn them on with set -o [option_name] and turn them off with set +o [option_name].
First, let's check the current status of the allexport option. You can list all shell options and filter for allexport using grep.
set -o | grep allexport
By default, this option is turned off. The output will show its status as off:
allexport off
Now, let's turn on the allexport option.
set -o allexport
Verify that the setting has changed by running the check command again.
set -o | grep allexport
This time, the output will confirm that the option is on:
allexport on
With allexport enabled, any variable you create will automatically become an environment variable. Let's test this. Create a new variable named truck without using the export command.
truck=chevy
Now, check if truck exists in the environment using the env command.
env | grep truck
You will see that the truck variable is listed, even though you did not use export. This is because the allexport option was active.
truck=chevy
This feature can be very useful, but it's good practice to turn it off when you no longer need it to avoid unintentionally exporting variables. Let's turn allexport off.
set +o allexport
Finally, verify that it has been turned off.
set -o | grep allexport
The output will once again show that the option is off.
allexport off
Any new variables you create from this point forward will be local variables by default, unless you explicitly use the export command.
Persist Shell Options Using the .bashrc File
In this step, you will learn how to make your shell customizations permanent. Any aliases, functions, or shell options you set are temporary and will be lost when you close your terminal session. To save them permanently, you need to add them to a shell configuration file.
While the title mentions .bashrc, which is the configuration file for the Bash shell, our lab environment uses the Zsh shell. The equivalent configuration file for Zsh is ~/.zshrc. This file is a script that runs automatically every time you open a new interactive shell, making it the perfect place to store your personal settings.
We will practice this by making the noclobber shell option permanent. The noclobber option prevents you from accidentally overwriting an existing file when using output redirection (>).
First, let's use the nano text editor to add the noclobber option to your ~/.zshrc file. The ~ symbol is a shortcut for your home directory, /home/labex.
nano ~/.zshrc
This command opens the ~/.zshrc file in the nano editor. Use the arrow keys to move the cursor to the very end of the file and add the following line:
set -o noclobber
Now, save the file and exit nano. To do this, press Ctrl+O (Write Out), press Enter to confirm the filename, and then press Ctrl+X to exit.
You are now back at the command prompt. Let's check if the noclobber option is active in your current shell.
set -o | grep noclobber
The output will be:
noclobber off
Why is it off? Because your current shell session has not read the changes you just made to the ~/.zshrc file. The file is only read when a new shell starts.
To prove this, let's start a new child shell.
zsh
You are now in a new shell. Let's check the noclobber status here.
set -o | grep noclobber
This time, the output will be:
noclobber on
This confirms that new shells correctly read the ~/.zshrc file and apply the settings. Now, exit the child shell to return to your original parent shell.
exit
So how can you apply the changes to your current shell without closing and reopening it? You can use the source command, which reads and executes the commands from a file in the current shell's context.
source ~/.zshrc
The source command has now executed the set -o noclobber line from your configuration file. Let's verify that noclobber is now turned on in our original shell.
set -o | grep noclobber
The output will now be:
noclobber on
You have successfully learned how to persist shell settings by editing the ~/.zshrc file and how to apply those changes to your current session using the source command.
Summary
In this lab, you learned the fundamental concepts of managing the Linux shell environment. You practiced creating both local variables, which are confined to the current shell, and environment variables, which are inherited by any child processes. Key commands such as echo for displaying variable values, export for creating environment variables, and env for listing them were utilized. The concept of inheritance was further explored by launching a child shell to test which variables and aliases were successfully passed down from the parent shell.
Furthermore, you explored methods for controlling and persisting your shell configuration. You used the set -o allexport option to automatically export all subsequently defined variables, streamlining the process of making them available to child processes. To ensure that your custom variables, aliases, and shell options are available across all future terminal sessions, you learned how to add these configurations to the .bashrc startup file, making your environment customizations permanent.



