Ahoy sailors! This time we onboard the sail and take on a voyage to explore the realms of THE SHELL...
This blog post summarizes the first lecture of the "Missing Semester" course, focusing on the shell and its functionalities. You may find the link for Lecture 1 here: https://missing.csail.mit.edu/2020/course-shell/
Why the Shell?
Graphical interfaces are convenient, but they limit what you can do. The shell offers a powerful way to interact with your computer directly. And, to sum it up all, I'd say that to take full advantage of the tools your computer provides, we have to go old-school and drop down to a textual interface: The Shell.
What is the Shell?
In the context of computers, a shell is a program that acts as an interface between the user and the operating system. It provides a way to communicate with the operating system by issuing commands and receiving feedback. There are two main types of shells:
Command-Line Shell (CLS): This is a text-based interface where you type commands and see text output. It's considered the traditional way to interact with the system, especially for power users and system administrators. Bash (Bourne Again SHell) is a common example of a CLS found on Linux and macOS systems.
Graphical Shell (GUI Shell): This is the more user-friendly interface most people are familiar with today. It uses windows, icons, menus, and other visual elements to interact with the operating system. The Finder on macOS and File Explorer on Windows are examples of GUI shells.
Here's a summary of the key points about shells:
Provides Access: Shells offer a way to access the functionalities of the operating system.
Accepts Commands: Users can type commands to instruct the operating system to perform specific tasks.
Provides Feedback: The shell displays the output or results of the executed commands.
Two Types: Command-line shells (CLS) offer a more direct and powerful way to interact with the system, while graphical shells (GUI shells) provide a more user-friendly visual experience.
While GUI shells are dominant for everyday tasks, CLS (like Bash) can be much more efficient for repetitive tasks, automation, and scripting.
This lecture is focused on the widely used Bourne Again SHell (Bash).
Using the Shell
Open a terminal to access the shell prompt (e.g.,
missing:~$
).Type commands at the prompt to execute programs.
Example:
date
prints the current date and time.Commands can take arguments (e.g.,
echo hello
prints "hello").The shell searches for programs in directories listed in the
$PATH
environment variable.Use
which
to find the location of a program.
Navigating in the Shell
Paths specify locations of files and directories.
/
is the root directory.pwd
shows the current working directory.cd
changes the current working directory.ls
lists the contents of a directory.ls -l
provides detailed information about files and directories.Permissions (read, write, execute) control access to files and directories.
Connecting Programs
Programs have input and output streams (usually the keyboard and screen).
Redirection allows you to change these streams.
>
redirects output to a file (e.g.,echo hello > hello.txt
).<
redirects input from a file (e.g.,cat < hello.txt
).>>
appends output to a file.Pipes (
|
) connect the output of one program to the input of another (e.g.,ls -l / | tail -n1
).
A Versatile Tool
The
sudo
command allows you to run commands with root privileges (carefully!).The
/sys
file system exposes kernel parameters for configuration (not on Windows or macOS).
Let's dive into some basic scripting...
Comments:
- Lines starting with
#
are comments and ignored during script execution. They explain the purpose of the code block below them.
Shell Script Header (Shebang Line):
#!/usr/bin/bash
- This line specifies the interpreter to be used for running the script. Here,
/usr/bin/bash
indicates the Bash interpreter. More could be read & understood in detail here on https://en.wikipedia.org/wiki/Shebang_(Unix)
Variable Usage:
# Uppercase by convention
# Letters, numbers, underscores
NAME="Epsit"
echo "Hello ${NAME} 'sup?"
Variables store values that can be used throughout the script.
Variable names are typically uppercase by convention (though not strictly required).
They can contain letters, numbers, and underscores.
Assignment uses
=
to assign a value to a variable (e.g.,NAME="Epsit"
).Accessing a variable's value is done using
$
followed by the variable name (e.g.,$NAME
).String interpolation using
${NAME}
within double quotes allows embedding variable values into strings (e.g., "Hello ${NAME} 'sup?").
User Input:
read -p "Enter your name: " NAME
echo "Hello $NAME, nice to meet you!"
The
read
command allows the script to prompt the user for input.-p "Enter your name: "
sets a prompt displayed before user input.The user's input is stored in the variable specified after
read
(here,NAME
).
Conditional Statements:
- These control the script's flow based on certain conditions.
Simple if Statement:
if [ "$NAME" == "Epsit" ]
then
echo "Wassup Epsit?"
fi
The
if
statement checks if a condition is true.[ "$NAME" == "Epsit" ]
compares the value of$NAME
with "Epsit" using double square brackets[]
for comparison.==
checks for equality.The indented code block (
echo "Wassup Epsit?"
) executes only if the condition is true.
if-else Statement:
if [ "$NAME" == "Epsit" ]
then
echo "Wassup Epsit?"
else
echo "You ain't Epsit"
fi
- The
else
clause provides an alternative code block to execute if theif
condition is false.
else-if (elif) Statement:
if [ "$NAME" == "Epsit" ]
then
echo "Wassup Epsit?"
elif [ "$NAME" == "John Doe" ]
then
echo "Ohhkay you are John Doe, a friend of Epsit."
else
echo "You are some stranger for me, nothing else"
fi
The
elif
(else if) clause allows checking additional conditions if the initialif
fails.Multiple
elif
statements can be chained to handle various scenarios.
Comparison Operators:
NUM1=3
NUM2=5
if [ "$NUM1" -gt "$NUM2" ]
then
echo "$NUM1 is greater than $NUM2"
else
echo "$NUM1 is less than $NUM2"
fi
- Comparison operators like
-gt
(greater than),-lt
(less than),-eq
(equal to), etc., are used within square brackets for numeric comparisons.
File Conditions:
# -f file True if file is a regular file
# -e file True if file exists (regardless of type)
# -d file True if file is a directory
# -x file True if the file is executable
# -w file True if the file is writable
# -u file True if the user id is set on a file
These operators check file properties within square brackets.
The example using
-f "$FILE"
checks if the file$FILE
exists and is a regular file.
Looping:
total_lines=-1
FILE="hello.txt"
for file in "$FILE"
do
lines=$(wc -l < "$FILE")
total_lines=$((total_lines + lines))
done
echo "Total lines: $total_lines"
This code snippet demonstrates a loop in Bash scripting that calculates the total number of lines in a file. Here's a breakdown of its functionality:
Variable Initialization:
total_lines=-1
: Initializes a variabletotal_lines
to -1. This variable will store the accumulated total line count.FILE="hello.txt"
: Initializes a variableFILE
with the name of the file to be processed ("hello.txt" in this case).
for Loop:
for file in "$FILE"
: This line defines the loop structure.for
: Keyword indicating a loop.file
: This is a loop variable that will take on the value of each item in the list during each iteration.in "$FILE"
: Specifies the list to iterate over. Here, it's just the single filename stored in theFILE
variable (enclosed in double quotes).
Loop Body:
The indented code block (
lines=$(wc -l < "$FILE")
,total_lines=$((total_lines + lines))
) executes for each item (filename) in the list.lines=$(wc -l < "$FILE")
:This line counts the number of lines in the file and stores the result in the
lines
variable.wc -l
: Thewc
command with the-l
flag counts the number of lines in a file.< "$FILE"
: This redirects the output ofwc -l
(which is normally sent to the console) to the command following<
, effectively treating the file content as input forwc -l
.
total_lines=$((total_lines + lines))
:This line accumulates the line count from each iteration.
$(( ))
: This is a Bash arithmetic expansion construct. It performs mathematical operations on integers within double parentheses.total_lines + lines
: Adds the current line count (lines
) to the previously accumulated total (total_lines
).
Printing the Result:
echo "Total lines: $total_lines"
: After the loop finishes iterating through all items (the file list in this case), this line prints the final accumulated total line count stored in thetotal_lines
variable.
And with this concludes my learnings of Shell Scripting: Day #1 (Though I also made some small shell scripting projects but I'll keep them in extras alongwith the solved exercises for this lecture, they'll be posted as separate blog discussion)... Let's stay tuned and see where the journey takes us. Signing off for now until my next blog comes.
Bleed code!