Welcome to our today’s guide on how to customize and use the shell environment in Linux. In our day-to-day work as a skilled Linux System Administrator, knowing how to use shell is very important because it is an interface between the system users and the operating system’s kernel. Shell helps in the interpretation of commands invoked by any user. The well known shell in most Linux distros is bash (Bourne Again Shell). When bash is started it executes sequence of startup scripts which custom-make the system session’s environment.

Types of Linux Shells

The following are shell types you should be familiar with;

1. Login | Non-login Shells

These are kind of shells where a user using a computer system should enter valid credentials such username and passwords in order to login to a computer.

2. Interactive | Non-interactive Shells

In these type of shells, user interact with the shell. The user input the commands in the commandline using the keyboard then the shell gives the output on the screen.

Launching a Terminal in Linux

You can choose to open a terminal application or you can shift to the one of the system console when you in a desktop environment. When you are in GUI (Graphical User Interface) a new shell opened by terminal emulator like gnome-terminal or konsole is called pts(pseudo terminal slave) while that is opened by system console is called tty(teletypewritter).

Using the Ctrl+Alt+F1-F6 key combination will open an interactive text-based login shell while Ctrl+Alt+F7 will return to Desktop.

Using bash

After you have successfully logged in to the system, open your terminal and type bash to open a new shell which is a child process to the present shell.

Depending, you can use various options to choose the type of shell you want to start as follows;

bash optiontype of shell
-iwill launch an interactive shell.
-l or –loginwill launch a login shell.
 –noprofilethis will ignore both the system-wide startup file /etc/profile and the user-level startup files ~/.bash_profile, ~/.bash_login and ~/.profile with login shells.
–rcfile <file>this will take <file> as the startup file ignoring system wide /etc/bash.bashrc and user-level ~/.bashrc with interactive shells.
–norcthis will ignore both the system-wide startup file /etc/bash.bashrc and the user-level startup file ~/.bashrc with interactive shells.

Using su in Linux

Using this command su, you can call on both login and non-login shells when you are root or with super user privileges.

su optiontype of shell
su – user2, su -l user2 or su –login user2this will start an interactive login shell as user2.
su root or suthis will start an interactive non-login shell as root.
su user2this will start an interactive non-login shell as user2.
su – root or su –this will start an interactive login shell as root.

Using sudo in Linux

With sudo command, you can execute commands as another user. sudo command is used to acquire root privileges for a moment therefore the user executing command must be in sudoers file.

When the user is not in the sudoers file you will get the following error when you execute commands with sudo;

$ sudo apt update
[sudo] password for mike: 
mike is not in the sudoers file.  This incident will be reported.

To add user to sudoers file i.e mike, switch to root and use the following command;

$ usermod -aG sudo username

Using this command sudo, you can call on both login and non-login shells when you are root or with super user privileges.

sudo optiontype of shell
sudo su – user2, sudo su -l user2 or sudo su –login user2this will start an interactive login shell as user2.
sudo -u user2 -sthis will start an interactive non-login shell as user2.
sudo su – root or sudo su –this will start an interactive login shell as root.
sudo su user2this will start an interactive non-login shell as user2.
sudo -ithis  will start an interactive login shell as root.
sudo su root or sudo suthis will start an interactive non-login shell as root.
sudo -s or sudo -u root -sthis will start a non-login shell as root.
sudo -i <some_command>this will start an interactive login shell as root, run the command and return to the original user.

Determining Shell Types

Executing echo $0 command in your terminal will help you find out which type of shell you are running. Running his command you will find one o this output.

output of echo $0 command;

outputtype of shell
bash or /bin/bashIt will be interactive non-login
-bash or -suIt will be interactive login
<name_of_script>It will be non-interactive non-login (scripts)

example;

$ echo $0
-bash

Determining the Number of Shell Processes

Using ps aux | grep bash command, will help determine the number of bash shells running in your system.

$ ps aux | grep bash
frank       3508  0.0  0.2  13660  5300 pts/0    Ss+  08:01   0:00 -bash
frank     364521  0.0  0.2  13396  5320 pts/1    Ss   11:06   0:00 -bash
root      453804  0.0  0.2  13392  5004 pts/1    S    11:55   0:00 -bash
root      469440  0.0  0.0  11568   740 pts/1    S+   12:03   0:00 grep --color=auto bash

System Startup Files

In Linux systems, shell executes a series of startup files. /etc directory stores system wide or global scripts while ~(user’s home directory) stores local or user level scripts.

Global Scripts

/etc/profile

The .profile file for the Bourne shell and its compatible shells including bash is system wide file. /etc/bash.bashrc file and other files in /etc/profile.d directory are sourced by a sequence of if statements that /etc/profile file sets i.e number of variables such as PATH and PS1.

/etc/profile.d/*

This is a directory which contains scripts that get enforced by /etc/profile.

Local Scripts

~/.bash_profile

This is a Bash file used to source ~/.profile and ~/.bash_login and configure user environment.

~/.bash_login

This is a Bash file used to run commands required on login and it is only enforced when there is no ~/.bash_profile.

~/.profile

The main intention of this file is to check if the Bash shell is running thus sourcing ~/.bashrc ifit exists. This file is sourced only if neither ~/.bash_profile nor ~/.bash_login are available.

~/.bash_logout 

This Bash-specific file performs cleanup actions when the shell exists. This might be useful in situations where you’re in a remote session.

Sourcing Files

This is where some startup scripts run other scripts.

Sourcing Files with .(dot)

Most of the startup file have dots (.), let’s take a look at the section of .profile file;

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
	. "$HOME/.bashrc"
    fi
fi

We’ve previously seen how the execution of one script might result in the execution of another. As a result of the if statement, the file $HOME/.bashrc will be sourced (read and executed) during login if it exists (-f).

Also the dot (.) is used when you make changes in startup files, thus changes will be effective immediately without rebooting the system. Take a look at the following example where we will modify .bashrc file.

Adding an alias to ~/.bashrc file;

$ echo "alias hello='echo We are happy for you Linux Users.'" >> ~/.bashrc

You can now source the file with (.);

$. ~/.bashrc

Run the alias to check if it works.

$ hello
We are happy for you Linux Users.

Sourcing Files with source

You can also source files with source command, it serve the same purpose with the (.). You can source above file with source as follows.

$ source ~/.bashrc

The SKEL Directory

The absolute path to the skel directory is the value of the variable SKEL. The file system layout of users’ home directories is modeled after this directory. It contains the files that will be inherited by any newly established user accounts (including, of course, the configuration files for shells). SKEL and other relevant variables are kept in the configuration file /etc/adduser.conf.

You can look at it in the file;

$ grep SKEL /etc/adduser.conf
# The SKEL variable specifies the directory containing "skeletal" user
SKEL=/etc/skel
# If SKEL_IGNORE_REGEX is set, adduser will ignore files matching this
SKEL_IGNORE_REGEX="dpkg-(old|new|dist|save)"

Let’s list the contents of skel directory;

$ ls -a /etc/skel
.  ..  .bash_logout  .bashrc  .profile

Skel Demo

Let’s demonstrate how skel works.

Step 1. As a root user, change the directory to skel with cd command.

$ cd /etc/skel

Step 2. List the contents of the directory.

$ ls -a
.  ..  .bash_logout  .bashrc  .profile

Step 3. Create a directory of your choice.

$ mkdir New_User_Files

Step 4. Add new user who will obtain new home directory.

$ adduser mike
Adding user `mike' ...
Adding new group `mike' (1003) ...
Adding new user `mike' (1002) with group `mike' ...
Creating home directory `/home/mike' ...
Copying files from `/etc/skel' ...
New password: 
Retype new password: 
passwd: password updated successfully
Changing the user information for mike
Enter the new value, or press ENTER for the default
	Full Name []: 
	Room Number []: 
	Work Phone []: 
	Home Phone []: 
	Other []: 
Is the information correct? [Y/n] y

Step 5. Now log in as user mike and list the contents of its home directory /home/mike.

#log in as mike
$ su - mike

#print working directory
$ pwd
/home/mike

#list the contents of the directory
$ ls -a
.  ..  .bash_logout  .bashrc  New_User_Files  .profile

In the above output, you can see that the contents of home directory of user mike contains the file in skel directory.

Variables

A variable is a name that has a value attached to it. Giving a name a value in Bash is known as variable assignment, and it is how we create or set variables. Variable referencing, on the other hand, refers to the act of obtaining the value contained in a name.

Syntax;

<variable_name>=<variable_value>

Example;

$ Linux=Ubuntu

Let’s reference it using echo command where the variable is preceded with $.

$ echo $Linux
Ubuntu

Local or Shell Variables

Local variables, also known as shell variables, only live in the shell in which they were generated. Local variables are written in lowercase letters by default. Let’s make a local variable for the sake of running a few tests. As previously said, we select an appropriate variable name and equate it to a suitable value.

Examle;

$ Linux=Ubuntu

set Command

set is a handy command for working with local variables. set returns a list of all shell variables and functions that are presently assigned. Because there might be a lot of lines , it’s best to use it in conjunction with a pager like less.

Example;

$ set | less
BASH=/usr/bin/bash
BASHOPTS=checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:globasciiranges:histappend:interactive_comments:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=([0]="0")
BASH_ARGV=()
BASH_CMDS=()
BASH_COMPLETION_VERSINFO=([0]="2" [1]="10")
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="5" [1]="0" [2]="17" [3]="1" [4]="release" [5]="x86_64-pc-linux-gnu")
BASH_VERSION='5.0.17(1)-release'
COLUMNS=170
DIRSTACK=()
EUID=1002
GROUPS=()
HISTCONTROL=ignoreboth
HISTFILE=/home/mike/.bash_history
HISTFILESIZE=2000
HISTSIZE=1000
HOME=/home/mike
HOSTNAME=bett
HOSTTYPE=x86_64
IFS=$' \t\n'122361

Let’s check our variable above if it’s available;

$ set | grep Linux
Linux=Ubuntu

The variable Linux will not be inherited by any child processes generated from the current shell because it is a local variable.

We use unset command to unset any variable either being local or global.

$ unset Linux

Global or Environment Variables

The current shell, as well as all subsequent processes, has global or environment variables generated from it. Environment variables are written in capital letters by default.

Example;

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

export command is used to make a local variable to become a global variable.

$ export Linux

Now, the child shells will recognize Linux because we have made it a global variable. To turn a global variable into a local, we use export command with option -n with the variable name i.e export -n <VARIABLE _NAME>.

Also, when you invoke export command with -p or without any argument it will print list of all existing environment variables.

$ export
declare -x HOME="/home/mike"
declare -x LANG="en_GB.utf8"
declare -x LC_ADDRESS="en_US.UTF-8"
declare -x LC_IDENTIFICATION="en_US.UTF-8"
declare -x LC_MEASUREMENT="en_US.UTF-8"
declare -x LC_MONETARY="en_US.UTF-8"
declare -x LC_NAME="en_US.UTF-8"
declare -x LC_NUMERIC="en_US.UTF-8"
declare -x LC_PAPER="en_US.UTF-8"
declare -x LC_TELEPHONE="en_US.UTF-8"
declare -x LC_TIME="en_US.UTF-8"
declare -x LESSCLOSE="/usr/bin/lesspipe %s %s"
declare -x LESSOPEN="| /usr/bin/lesspipe %s"
declare -x LOGNAME="mike"

env and printenv Commands

These commands are also used to print a list of all environment variables.

$ env
SHELL=/bin/bash
LC_ADDRESS=en_US.UTF-8
LC_NAME=en_US.UTF-8
LC_MONETARY=en_US.UTF-8
PWD=/home/mike
LOGNAME=mike
HOME=/home/mike
LANG=en_GB.utf8
LC_PAPER=en_US.UTF-8
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:
LESSCLOSE=/usr/bin/lesspipe %s %s
TERM=xterm-256color
LC_IDENTIFICATION=en_US.UTF-8
LESSOPEN=| /usr/bin/lesspipe %s
USER=mike
SHLVL=2
LC_TELEPHONE=en_US.UTF-8
LC_MEASUREMENT=en_US.UTF-8
LC_TIME=en_US.UTF-8
XDG_DATA_DIRS=/usr/local/share:/usr/share:/var/lib/snapd/desktop
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
MAIL=/var/mail/mike
LC_NUMERIC=en_US.UTF-8
_=/usr/bin/env

Aliases

An alias is a name that is used to refer to another command (s). It can be used in the same way as a regular command, but it will execute another command based on the alias specification.

Creating Aliases

Declaring aliases follows a simple syntax. The term alias, followed by the alias assignment, is used to declare aliases. The alias assignment, on the other hand, consists of an equal sign, an alias name, and one or more instructions.

Syntax;

alias alias_name=command(s)

Example;

$ alias l='ls -alh'

In the above command, when you type l in your terminal and press enter key it will list all contents including hidden in long listing and human readable format in your current working directory.

alias command is used to display all available aliases in the system.

$ alias
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -alh'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'

To remove set aliases in the system, use unalias command.

$ unalias l

Functions

Functions are more programmatic and versatile than aliases, especially when it comes to fully using Bash’s built-in variables and positional parameters. They’re also fantastic for using with flow control structures like loops and conditionals. A function may be thought of as a command that incorporates logic via blocks or groups of other commands.

Creating Functions

There are two ways of creating functions;

i) Using the function keyword.

You can use the term function, which is followed by the function’s name and the commands enclosed in curly brackets..

Syntax;

function function_name {
command #1
command #2
command #3
.
.
.
command #n
}

ii) Using ()

On the other hand, we may omit the keyword function and instead use two brackets following the function name.

Syntax;

function_name() {
command #1
command #2
command #3
.
.
.
command #n
}

Example;

$ distros () {
Linux="CentOS, Ubuntu"
echo $Linux
}

Now let’s invoke the function above.

$ distros
CentOS, Ubuntu

Functions must be placed in shell initialization scripts such as /etc/bash.bashrc (global) or /.bashrc (local) to be durable between system reboots, just like variables and aliases.

Conclusion

This marks the end of our guide on how to customize and use the shell environment in Linux, we are glad that this article was of value to you. Thanks for for going through this guide. Stay tuned for more guides of the same.

Related guides;

LPIC 102 – Working with Locale Settings and Environment Variables

LPIC 102 – Managing Linux System Date and Time with UTC…

LPIC 102 – Managing User and Group Accounts on Linux

LPIC 102 – List of Major Linux Desktop Environments

LEAVE A REPLY

Please enter your comment!
Please enter your name here