An open API service indexing awesome lists of open source software.

https://github.com/tushcmd/bash-tush


https://github.com/tushcmd/bash-tush

Last synced: 2 months ago
JSON representation

Awesome Lists containing this project

README

        

# BASH Notes

## Introduction

### What is BASH?

+ A shell language
+ Short for **Bourne Again Shell**
+ Easy Commands.

### Why learn BASH?
+ Most used and popular shell language.
+ Used since early days of linux
+ Comes with Linux and other OS(MAC, windows using WSL)

### Why not BASH?
+ Lacks features needed for Advance scripts
+ No OOP
+ Difficult syntax compared to Python
+ Newer tools available like Ansible
+ Advanced script python is preferred.

### Still useful
+ Lightweight and always available.
+ Basic knowledge makes big difference.








## Understanding BASH script file

```bash
#!/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
1. **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.

2. **Comment** : Use '#'

3. **Variable**: Variable names are case sensitive and can contain letters, numbers and underscore in the name.
4. **Command Execution**: Commands are typically written one per line and they are executed sequentially from top to bottom.
5. **Control Structure**: Conditional(if-else-then), loops(for,while,until) and case.








## Positional Arguments

1. $0: Represents the name of the script or command shell
2. $1: first positional argument
3. $2: second positional argument
.
.
.
$n: nth positional argument

Example the script below:
```bash
#!/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 "
fi
```

The script is called in below format
```cmd
./test.sh arg1 arg2
```








## Output/Input redirection in shell


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:

1. `>` (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:

```bash
command > output.txt
```

2. `>>` (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:

```bash
command >> output.txt
```

3. `2>` (Greater Than Symbol Followed by 2): This operator redirects standard error (stderr) to a file. For example:

```bash
command 2> error.txt
```

4. `2>>` (Double Greater Than Symbol Followed by 2): This operator appends standard error (stderr) to a file. For example:

```bash
command 2>> error.txt
```

5. `&>` or `&>>`: These operators redirect both standard output and standard error to a file. For example:

```bash
command &> output_and_error.txt
```

6. `<` (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:

```bash
command < input.txt
```
7. `<<` (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:
```bash
# Use a here document to provide input to 'cat'
cat << EOF
This is line 1
This is line 2
EOF
```
7. `|` (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:

```bash
command1 | command2
```

Here are some examples of how to use output redirection:

- Redirect standard output to a file:
```bash
echo "Hello, World!" > output.txt
```

- Redirect standard error to a file:
```bash
command_that_generates_error 2> error.txt
```

- Redirect both standard output and standard error to a file:
```bash
command &> output_and_error.txt
```

- Append standard output to an existing file:
```bash
echo "This is additional text." >> existing_file.txt
```

- Pipe the output of one command as input to another:
```bash
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.








## Test Operators in shell


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:

1. **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`).

2. **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`).

3. **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.

4. **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).

5. **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" ]`).

6. **File Comparisons**:
- `file1 -nt file2`: Checks if `file1` is newer than `file2`.
- `file1 -ot file2`: Checks if `file1` is older than `file2`.

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:

```bash
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.







## If/Elif/Else


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:



```bash
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`: The `if` statement is used to test a condition. If the condition is true, the code block following `then` is executed.

- `elif`: The `elif` statement is used to test an alternative condition if the previous `if` condition is false. You can have multiple `elif` statements to test different conditions sequentially.

- `else`: The `else` statement is optional and is executed if none of the previous conditions (including the `if` and any `elif` statements) are true.

Here's an example of how `if`, `elif`, and `else` statements can be used in a shell script:

```bash
#!/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.








## Case statements

> 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:

```bash
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:

```bash
#!/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.




## Arrays
You can assign multiple values to one variable collected in a list which we call them `arrays`.




You can create them like this:
```bash
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.
- ` ` (space): Each index of values separated by space.

To call them you should do

```bash
${VariableName[index]}
```
- `VariableName`: Name of the array you Initialized.
- `index`: The index number you want. Indexes start from `0`. 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:

```bash
declare -a
```

- `declare`: Bash command used to explicitly set the array variable attribute.
- `-a`: Option indicating the declaration of an indexed array.
- ``: The name you want to assign to the array.

```bash
declare -a MyArray
```


For adding new values after declaration you can do either of these:

```bash
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.

```bash
MyArray[1]=one
```

or

```bash
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.

```bash
MyArray+=(one two three)
```