- A shell language
- Short for Bourne Again Shell
- Easy Commands.
- Most used and popular shell language.
- Used since early days of linux
- Comes with Linux and other OS(MAC, windows using WSL)
- Lacks features needed for Advance scripts
- No OOP
- Difficult syntax compared to Python
- Newer tools available like Ansible
- Advanced script python is preferred.
- Lightweight and always available.
- Basic knowledge makes big difference.
#!/bin/bash
#Prompt the user for their name
echo "Please enter your name: "
#Read the user's input into the name variable
read name
#Print a greeting message
echo " Hello , $name!"
Consider the above example
-
Shebang(#! line): A bash script usually starts with a shebang line at the beginning, which tells the system which interpreter to use to execute the script.
-
Comment : Use '#'
-
Variable: Variable names are case sensitive and can contain letters, numbers and underscore in the name.
-
Command Execution: Commands are typically written one per line and they are executed sequentially from top to bottom.
-
Control Structure: Conditional(if-else-then), loops(for,while,until) and case.
- $0: Represents the name of the script or command shell
- $1: first positional argument
- $2: second positional argument . . . $n: nth positional argument
Example the script below:
#!/bin/bash
# Check if at least two positional arguments are provided
if [ $# -ge 2 ]; then
echo "The first argument is: $1"
echo "The second argument is: $2"
else
echo "Usage: $0 <arg1> <arg2>"
fi
The script is called in below format
./test.sh arg1 arg2
Output redirection in shell scripting allows you to change the destination of the output generated by a command or script. By default, the output of a command is usually displayed in the terminal (standard output, often denoted as `stdout`). However, you can use redirection operators to send the output to a file or to another command's input. Here are some common output redirection operators in shell scripting:
-
>
(Greater Than Symbol): This operator redirects standard output to a file. If the file does not exist, it is created; if it exists, it is overwritten. For example:command > output.txt
-
>>
(Double Greater Than Symbol): This operator appends standard output to a file. If the file does not exist, it is created; if it exists, the output is added to the end of the file. For example:command >> output.txt
-
2>
(Greater Than Symbol Followed by 2): This operator redirects standard error (stderr) to a file. For example:command 2> error.txt
-
2>>
(Double Greater Than Symbol Followed by 2): This operator appends standard error (stderr) to a file. For example:command 2>> error.txt
-
&>
or&>>
: These operators redirect both standard output and standard error to a file. For example:command &> output_and_error.txt
-
<
(Less Than Symbol): This operator is used for input redirection, allowing you to read data from a file as input for a command. For example:command < input.txt
-
<<
(Double Less than symbol): Allows you to create a here document, which is a way to provide input to a command within your script. The content between << EOF and EOF is treated as input to the command. This is particularly useful when you want to provide multiple lines of input or specify configuration settings. For example:# Use a here document to provide input to 'cat' cat << EOF This is line 1 This is line 2 EOF
-
|
(Pipe Symbol): This operator is used for piping the output of one command as input to another command. It doesn't create files but is a way to pass data between commands. For example:command1 | command2
Here are some examples of how to use output redirection:
-
Redirect standard output to a file:
echo "Hello, World!" > output.txt
-
Redirect standard error to a file:
command_that_generates_error 2> error.txt
-
Redirect both standard output and standard error to a file:
command &> output_and_error.txt
-
Append standard output to an existing file:
echo "This is additional text." >> existing_file.txt
-
Pipe the output of one command as input to another:
cat input.txt | grep "pattern"
Output redirection is a powerful feature in shell scripting that allows you to control where the output of commands goes, making it useful for logging, capturing results, and processing data.
Input redirection allows you to automate tasks by providing data to commands or scripts without manual user input. It's a valuable feature for processing files, configuration, and other data sources within shell scripts.
In shell scripting, test operators are used to evaluate conditions and return a Boolean result (true or false) based on the outcome of the test. The `test` command, often used with square brackets `[ ]`, is commonly used for conditional checks within shell scripts. Alternatively, you can use the `[[ ]]` construct in Bash for more advanced and flexible tests. Here are some commonly used test operators:
-
Numeric Comparisons:
-eq
: Equal to (e.g.,[ "$a" -eq "$b" ]
checks if$a
is equal to$b
).-ne
: Not equal to (e.g.,[ "$a" -ne "$b" ]
checks if$a
is not equal to$b
).-lt
: Less than (e.g.,[ "$a" -lt "$b" ]
checks if$a
is less than$b
).-le
: Less than or equal to (e.g.,[ "$a" -le "$b" ]
checks if$a
is less than or equal to$b
).-gt
: Greater than (e.g.,[ "$a" -gt "$b" ]
checks if$a
is greater than$b
).-ge
: Greater than or equal to (e.g.,[ "$a" -ge "$b" ]
checks if$a
is greater than or equal to$b
).
-
String Comparisons:
=
: Equal to (e.g.,[ "$str1" = "$str2" ]
checks if$str1
is equal to$str2
).!=
: Not equal to (e.g.,[ "$str1" != "$str2" ]
checks if$str1
is not equal to$str2
).
-
File Tests:
-e
: Checks if a file exists (e.g.,[ -e "$filename" ]
).-f
: Checks if a file exists and is a regular file (not a directory or a special file).-d
: Checks if a directory exists.-s
: Checks if a file is not empty (size greater than zero).-r
,-w
,-x
: Checks if a file is readable, writable, or executable, respectively.
-
Logical Operators:
!
: Negation (e.g.,[ ! -e "$filename" ]
checks if the file does not exist).-a
: Logical AND (e.g.,[ "$a" -eq 1 -a "$b" -eq 2 ]
checks if both conditions are true).-o
: Logical OR (e.g.,[ "$a" -eq 1 -o "$b" -eq 2 ]
checks if at least one condition is true).
-
String Tests:
-z
: Checks if a string is empty (e.g.,[ -z "$str" ]
).-n
: Checks if a string is not empty (e.g.,[ -n "$str" ]
).
-
File Comparisons:
file1 -nt file2
: Checks iffile1
is newer thanfile2
.file1 -ot file2
: Checks iffile1
is older thanfile2
.
These operators can be used in conditional statements such as if
, elif
, and while
to perform tests and make decisions within shell scripts. For example:
if [ "$a" -eq 10 ]; then
echo "The value of 'a' is 10."
fi
if [ -e "$filename" ]; then
echo "The file exists."
else
echo "The file does not exist."
fi
Keep in mind that you can also use the [[ ]]
construct in Bash for more advanced and flexible conditional tests, which provide additional capabilities, such as pattern matching and logical operators.
The `if`, `elif` (short for "else if"), and `else` statements are used in shell scripting and various programming languages to control the flow of a program based on conditional tests. They allow you to execute different blocks of code depending on whether certain conditions are true or false. Here's the basic syntax for using `if`, `elif`, and `else` statements in shell scripts:
if condition1; then
# Code to execute if condition1 is true
elif condition2; then
# Code to execute if condition1 is false and condition2 is true
else
# Code to execute if neither condition1 nor condition2 is true
fi
-
if
: Theif
statement is used to test a condition. If the condition is true, the code block followingthen
is executed. -
elif
: Theelif
statement is used to test an alternative condition if the previousif
condition is false. You can have multipleelif
statements to test different conditions sequentially. -
else
: Theelse
statement is optional and is executed if none of the previous conditions (including theif
and anyelif
statements) are true.
Here's an example of how if
, elif
, and else
statements can be used in a shell script:
#!/bin/bash
score=85
if [ "$score" -ge 90 ]; then
echo "Grade: A"
elif [ "$score" -ge 80 ]; then
echo "Grade: B"
elif [ "$score" -ge 70 ]; then
echo "Grade: C"
elif [ "$score" -ge 60 ]; then
echo "Grade: D"
else
echo "Grade: F"
fi
In the above script, based on the value of the score
variable, it determines the corresponding grade using if
, elif
, and else
statements.
- If
score
is greater than or equal to 90, it prints "Grade: A". - If
score
is between 80 and 89, it prints "Grade: B". - If
score
is between 70 and 79, it prints "Grade: C". - If
score
is between 60 and 69, it prints "Grade: D". - If
score
is below 60, it prints "Grade: F".
You can use if
, elif
, and else
statements to handle more complex conditional logic and make decisions within your shell scripts based on various conditions.
They are better than if/elif/else when
- Checking for multiple values
- is easier to read
In shell scripting, a case statement is used for conditional branching, allowing you to execute different blocks of code based on the value of a variable or an expression. A case statement is particularly useful when you have multiple conditions to check and want a more structured and readable way to handle them.
The basic syntax of a case statement in Bash looks like this:
case expression in
pattern1)
# Code to execute if expression matches pattern1
;;
pattern2)
# Code to execute if expression matches pattern2
;;
...
patternN)
# Code to execute if expression matches patternN
;;
*)
# Default code to execute if none of the patterns match
;;
esac
Here's a breakdown of how a case statement works:
case
: Begins the case statement.expression
: The value or variable you want to evaluate.in
: Separates the expression from the patterns.pattern1
,pattern2
, ...,patternN
: Patterns to match against the expression.)
(right parenthesis): Marks the end of each pattern.;;
(double semicolon): Separates each code block associated with a pattern.*)
: A wildcard pattern that matches anything. It is used as a default case if none of the patterns match.esac
: Marks the end of the case statement.
Here's an example of a case statement in a shell script:
#!/bin/bash
fruit="apple"
case "$fruit" in
"apple")
echo "It's an apple."
;;
"banana")
echo "It's a banana."
;;
"orange")
echo "It's an orange."
;;
*)
echo "It's something else."
;;
esac
In this script, the value of the fruit
variable is checked against different patterns, and the corresponding block of code is executed based on the match. In this case, it will print "It's an apple."
You can have as many patterns as needed, and each pattern can contain multiple conditions. Case statements are particularly useful when you have a finite number of options to check, making your code more structured and easier to read than a series of if
/elif
/else
statements for each condition.
You can assign multiple values to one variable collected in a list which we call them arrays
.
You can create them like this:
VariableName=(value1 value2 value3 value3)
VariableName
: Name of the array you want.()
(brackets): You can use which of()
,[]
,{}
but you should remember to use the same opening and closing brackets.
To call them you should do
${VariableName[index]}
VariableName
: Name of the array you Initialized.index
: The index number you want. Indexes start from0
. To use all of the indexes in your array you can use@
as your index.
You can declare an empty array too. Here's how to do it:
declare -a <array_name>
declare
: Bash command used to explicitly set the array variable attribute.-a
: Option indicating the declaration of an indexed array.<array_name>
: The name you want to assign to the array.
declare -a MyArray
For adding new values after declaration you can do either of these:
array_name[position]=value
array_name
: The name of the array you assign.position
: The index at which you want to assign value.value
: The item you insert to the specified index.
MyArray[1]=one
or
array_name+=(item item item)
array_name
: The name of the array you assign.+=
: Compound operator to add array elements.item
: Value you want to put in your array.
MyArray+=(one two three)
One of the ways of having loop is for
loop. It reads each value of your array in each loop and puts it in a variable for later usage.
The for
loop syntax is like:
for ItemsName in ArrayName;
do
#Your code
done
ItemsName
: The name of each value of your array. You can access it later as a variable inside the loop.ArrayName
: The name of the array you assigned.do
: Start sign of for loop. After this, your code should be placed.done
: End sign of for loop. Before this, your code should be placed.
For example:
Mylist=(one two three four five)
for item in ${Mylist[@]};
do
echo $item
done
Mylist
: The name of the array.item
: The name of each value of Mylist array.${Mylist[@]}
: Calling the array with all of its indexes or values (by @ as the array index).echo
: Prints value to the output.$item
: Calling the local variable which contains one of the array's values in each loop.