Manage Shell Environment and Configuration in Linux

CompTIABeginner
Practice Now

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.