Skip to content

Linux Shell Basics: Variables, Redirection, Pipes & PATH

โ† Back to Linux Commands


This page explains how the Linux shell works, including different shell types, variables, and the powerful operators that allow you to chain commands together.


๐Ÿ›๏ธ Types of Shell

The shell is a command-line interpreter that acts as an interface between the user and the operating system kernel.

  • sh: The original Bourne shell.
  • bash (Bourne Again Shell): The default shell for most Linux distributions.
  • zsh: A highly customizable shell popular for modern development.
  • ksh (Korn Shell): A powerful shell often used in enterprise environments.
  • csh: A C-like syntax shell.

๐Ÿ” Pro-Tip: Identifying Available Shells

You can list all valid login shells installed on your system by inspecting the /etc/shells file:

[opc@new-k8s ~]$ cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash


๐Ÿ“Š Shell Variable Architecture

Understanding the difference between Shell Variables (local) and Environment Variables (global) is critical for managing processes and automation scripts.

graph TD
    A[Linux Kernel] --> B[Parent Shell Session]
    B --> C(Shell Variables - Local Only)
    B --> D{export command}
    D --> E[Environment Variables - Global]
    E --> F[Child Process 1: Script]
    E --> G[Child Process 2: Command]
    C -.-> |X| F
    C -.-> |X| G

๐Ÿ› ๏ธ Creating Shell Variables

Shell variables are only accessible within the current shell session.

[opc@new-k8s ~]$ clear
[opc@new-k8s ~]$ NAME="vignesh"
[opc@new-k8s ~]$ echo $NAME
vignesh
[opc@new-k8s ~]$ printenv NAME      # Returns nothing
[opc@new-k8s ~]$ env | grep NAME    # Returns nothing

Local variables are strictly session-bound and are not part of the system environment. Therefore, commands like env or printenv will not display them.

๐Ÿงช Proving Local Scope (Subshells)

A powerful way to prove that shell variables are local is to start a new "child" shell session. The child will not inherit the parent's local variables.

[opc@new-k8s ~]$ MY_ROLE="DevOps"
[opc@new-k8s ~]$ echo $MY_ROLE
DevOps
[opc@new-k8s ~]$ bash                # Enter a new child shell
[opc@new-k8s ~]$ echo $MY_ROLE       # Attempt to read variable
                                     # (Output is empty)
[opc@new-k8s ~]$ exit                # Return to parent shell
[opc@new-k8s ~]$ echo $MY_ROLE
DevOps

๐ŸŒŽ Managing Environment Variables using export

Environment variables are accessible to child processes as well.

1. Creating an Environment Variable

[opc@new-k8s ~]$ export NEW_NAME="Raghav"
[opc@new-k8s ~]$ echo $NEW_NAME
Raghav
[opc@new-k8s ~]$ printenv NEW_NAME
Raghav
[opc@new-k8s ~]$ env | grep NEW_NAME
NEW_NAME=Raghav

๐Ÿงช Proving Global Scope (Subshells)

Unlike local shell variables, environment variables are inherited by child processes.

[opc@new-k8s ~]$ export APP_STAGE="production"
[opc@new-k8s ~]$ bash                # Enter a new child shell
[opc@new-k8s ~]$ echo $APP_STAGE     # Read inherited variable
production                           # (Variable IS available)
[opc@new-k8s ~]$ exit                # Return to parent shell

2. Viewing Environment Variables

You can view a single variable with echo or list all environment variables using env or printenv.

[opc@new-k8s test]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/opc/.local/bin:/home/opc/bin
[opc@new-k8s test]$ env
XDG_SESSION_ID=172502
HOSTNAME=new-k8s
SELINUX_ROLE_REQUESTED=
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
SELINUX_USE_CURRENT_RANGE=
SSH_TTY=/dev/pts/0
USER=opc
MAIL=/var/spool/mail/opc
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/opc/.local/bin:/home/opc/bin
PWD=/home/opc
LANG=en_US.UTF-8
NEW_NAME=Raghav
SELINUX_LEVEL_REQUESTED=
HISTCONTROL=ignoredups
SHLVL=1

๐Ÿ“ The PATH Environment Variable

Most Linux commands can be executed from any directory because their paths are added to the PATH environment variable.

[opc@new-k8s ~]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/opc/.local/bin:/home/opc/bin

๐Ÿ”„ Shell Operators: Redirection

Redirection allows you to capture command output and save it to files.

>  Overwrites the file content, if the file already exists
>> Appends the content to the existing content in the file

In both cases, if the file is not present, it will create the file and write the content to it. By default, the echo command prints the output to the screen. But if we use redirection arrows, it can store the output to files.

1. Overwrite (>)

[opc@new-k8s ~]$ mkdir redirection
[opc@new-k8s ~]$ cd redirection/
[opc@new-k8s redirection]$ pwd
/home/opc/redirection
[opc@new-k8s redirection]$ ll
total 0
[opc@new-k8s redirection]$ pwd
/home/opc/redirection
[opc@new-k8s redirection]$ echo "hello devops"    # Prints to terminal
hello devops
[opc@new-k8s redirection]$ echo "hello devops" > hello.txt   # Redirects to file
[opc@new-k8s redirection]$ cat hello.txt
hello devops
[opc@new-k8s redirection]$ echo "I am learning devops" > hello.txt
[opc@new-k8s redirection]$ cat hello.txt
I am learning devops

2. Append (>>)

[opc@new-k8s redirection]$ pwd
/home/opc/redirection
[opc@new-k8s redirection]$ ll
total 0
[opc@new-k8s redirection]$ echo "I eat fruits daily" >> double-arrow.txt
[opc@new-k8s redirection]$ ll
total 4
-rw-rw-r--. 1 opc opc 19 Apr 17 14:13 double-arrow.txt
[opc@new-k8s redirection]$ cat double-arrow.txt
I eat fruits daily
[opc@new-k8s redirection]$ echo "I love banana" >> double-arrow.txt
[opc@new-k8s redirection]$ echo "I also like apples" >> double-arrow.txt
[opc@new-k8s redirection]$ ll
total 4
-rw-rw-r--. 1 opc opc 52 Apr 17 14:13 double-arrow.txt
[opc@new-k8s redirection]$ cat double-arrow.txt
I eat fruits daily
I love banana
I also like apples

๐Ÿ”— Shell Operators: Pipe (|)

A pipe (|) is used to pass the output from one command/program to the input for another command. This is essential for filtering long lists of information.

Example: Searching for Environment Variables

If you run env alone, the output is often dozens of lines long. To find a specific variable like your home directory, you can pipe the output to grep.

[opc@new-k8s test]$ env | grep HOME
HOME=/home/opc

๐Ÿ“œ Creating a Shell Script and Exporting to PATH

Create a script named sysinfo.sh that prints the current date and user.

Run echo -e '#!/bin/bash\ndate\nwhoami' > sysinfo.sh.

Verify the file creation and content:

[opc@new-k8s ~]$ ls -l sysinfo.sh
-rw-rw-r--. 1 opc opc 24 Apr 27 12:00 sysinfo.sh
[opc@new-k8s ~]$ cat sysinfo.sh
#!/bin/bash
date
whoami

Making it Executable and Running Locally

After creating the script, you need to give it execute permissions.

[opc@new-k8s ~]$ chmod +x sysinfo.sh
[opc@new-k8s ~]$ ls -l sysinfo.sh
-rwxrwxr-x. 1 opc opc 24 Apr 27 12:05 sysinfo.sh

Now, try to run the script by just typing its name:

[opc@new-k8s ~]$ sysinfo.sh
bash: sysinfo.sh: command not found...
It fails! This is because the current directory (.) is not in your PATH. To run it from the current directory, you must specify the path explicitly using ./:

[opc@new-k8s ~]$ ./sysinfo.sh
Sat Apr 27 12:10:00 GMT 2026
opc

Making the Script Globally Accessible (PATH)

If you want to run sysinfo.sh from any directory without typing ./, you must add its directory to the PATH environment variable.

First, let's move to a different directory and see it fail again:

[opc@new-k8s ~]$ cd /tmp
[opc@new-k8s tmp]$ sysinfo.sh
bash: sysinfo.sh: command not found...

Now, let's check the current PATH and add /home/opc to it:

[opc@new-k8s tmp]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/opc/.local/bin:/home/opc/bin

[opc@new-k8s tmp]$ export PATH=$PATH:/home/opc

[opc@new-k8s tmp]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/opc/.local/bin:/home/opc/bin:/home/opc

Now that the directory is in the PATH, the script can be executed from anywhere:

[opc@new-k8s tmp]$ sysinfo.sh
Sat Apr 27 12:12:00 GMT 2026
opc


๐Ÿ’พ Persisting Environment Variables (.bashrc)

Manual changes to environment variables are lost when you close your terminal. To make them permanent, add them to your ~/.bashrc file.

๐Ÿ“œ Adding Variables to .bashrc

[opc@new-k8s ~]$ echo 'export APP_STAGE="production"' >> ~/.bashrc
[opc@new-k8s ~]$ source ~/.bashrc   # Apply changes immediately

๐Ÿงช Proving Persistence

To verify the variable is now permanent, enter a new child shell.

[opc@new-k8s ~]$ bash                # Enter child shell
[opc@new-k8s ~]$ echo $APP_STAGE     # Variable is available!
production
[opc@new-k8s ~]$ exit                # Return to parent
[opc@new-k8s ~]$ cat .bashrc
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

# User specific aliases and functions

export APP_STAGE="production"
export NEW_NAME="Raghav"

๐Ÿšฆ Exit Codes ($?)

Every command returns an exit status code after execution. This is stored in the special variable $?. In Linux, 0 means success, and any other value (usually 1-255) indicates an error.

[opc@new-k8s ~]$ ls
sysinfo.sh
[opc@new-k8s ~]$ echo $?      # Success code
0
[opc@new-k8s ~]$ ls /fake-dir
ls: cannot access '/fake-dir': No such file or directory
[opc@new-k8s ~]$ echo $?      # Error code
2

๐Ÿง  Quick Quiz โ€” Shell Basics & Environment

#

Which environment variable determines where Linux looks for executable commands?


๐Ÿ“ Want More Practice?

To strengthen your understanding and prepare for interviews, try the full 20-question practice quiz based on this chapter:

๐Ÿ‘‰ Start Shell Basics & Environment Quiz (20 Questions)


๐Ÿ“ฌ DevopsPilot Weekly โ€” Learn DevOps, Cloud & Gen AI the simple way.
๐Ÿ‘‰ Subscribe here