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 option | type of shell |
-i | will launch an interactive shell. |
-l or –login | will launch a login shell. |
–noprofile | this 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. |
–norc | this 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 option | type of shell |
su – user2, su -l user2 or su –login user2 | this will start an interactive login shell as user2. |
su root or su | this will start an interactive non-login shell as root. |
su user2 | this 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 option | type of shell |
sudo su – user2, sudo su -l user2 or sudo su –login user2 | this will start an interactive login shell as user2. |
sudo -u user2 -s | this 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 user2 | this will start an interactive non-login shell as user2. |
sudo -i | this will start an interactive login shell as root. |
sudo su root or sudo su | this will start an interactive non-login shell as root. |
sudo -s or sudo -u root -s | this 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:
output | type of shell |
bash or /bin/bash | It will be interactive non-login |
-bash or -su | It 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;
1. 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
}
2. 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: