# Bash Scripting

A Bash script is a plain-text file that contains a series of commands that are executed as if they had been typed at a terminal prompt, sequentially.&#x20;

{% hint style="info" %}
Shebang -> #!&#x20;

The shebang symbol is used to indicate the interpreter used to execute the script&#x20;

e.g. #!/bin/bash
{% endhint %}

**Bash Script Checklist**

* [ ] \#!/bin/bash - Adding the 'shebang' at the top of the file
* [ ] Providing execution permission for the file

**Bash Notes**

* Bash is case-sensitive
* execute bash with ' -x ' flag to print extra debug info
* Semi-colon ' ; ' is used as a command terminator&#x20;
* Single quotes acts different than double quotes

  * Double quotes allow the special meaning of these characters - $ , \ , \`

  ```bash
  name='sahar shukrun'

  greeting1='Hello $name' # cannot resolve the variable and prints the var name as is
  --Hello $name

  greeting="Hello $name" # variable can be used even when quotes are in place
  --Hello sahar shukrun
  ```

## Variables

```bash
# Declaring variables
cert_name='oscp'

# Variable dereference using the '$' sign
$cert_name
--'oscp'
```

### Scope of Variables

**Local variables**

```bash
local name="Joe"

## Usage
---------
#!/bin/bash
# var scope example
name1="John"
name2="Jason"

name_change() {
	local name1="Edward"
	echo "Inside of this function, name1 is $name1 and name2 is $name2"
	name2="Lucas"
}

echo "Before the function call, name1 is $name1 and name2 is $name2"
name_change
echo "After the function call, name1 is $name1 and name2 is $name2"
---
kali@kali:~$ ./varscope.sh
Before the function call, name1 is John and name2 is Jason
Inside of this function, name1 is Edward and name2 is Jason
After the function call, name1 is John and name2 is Lucas
```

### Command Substitution

A mechanism to save the output of a command to a variable; Two method are available:

* Wrapping the command with: **$(** ) - Newer and preferred method
* Wrapping the command with: **\` -** older and discouraged method (both method are implemented differently)

> command substitution happens in a subshell and changes to variables in the subshell will not alter variables from the master process

```bash
## Method 1
user=$(whoami)
echo $user
--kali

## Method 2
user=`whoami`
echo $user
--kali
```

### Reading user Input

We can read the user input while the script is running by using 'read'

```bash
kali@kali:~$ cat ./input.sh
#!/bin/bash
echo "Hello there, would you like to learn how to hack: Y/N?"
read answer
echo "Your answer was $answer"
kali@kali:~$ chmod +x ./input.sh
kali@kali:~$ ./input.sh
Hello there, would you like to learn how to hack: Y/N?
Y
Your answer was Y
```

**Read**

* -p - allows you to specify a prompt to the user
* -s - makes the input silent (unseen on screen)

### Arguments

<figure><img src="/files/xR4dCg5XBCPSbN9SxEmR" alt=""><figcaption><p>Special Bash Variables</p></figcaption></figure>

## If, Else, Elif Statements

**General syntax**

```bash
if [ <condition> ]
then
	<code>
elif
then
	<code>
else
	<code>
fi #block terminator
```

<figure><img src="/files/QdHzTOTdBvnX9EdqY5EO" alt=""><figcaption></figcaption></figure>

### Boolean operators & Command list

**Command list**

Command lists are a chain of commands that have a certain code flow according to the operators used

* \| - Pipe, is one such operator, a pipe will redirect the output of a command to the next command
* && - The AND operator bind the commands it is being used by with an AND condition;

  If the first command is not successful, the second command will not be executed, it requires the first command to yield True, otherwise it will stop

  ```bash
  # Example for Successful &&
  kali@kali:~$ user2=kali
  kali@kali:~$ grep $user2 /etc/passwd && echo "$user2 found!"
  kali:x:1000:1000:,,,:/home/kali:/bin/bash
  kali found!

  # Failed &&
  kali@kali:~$ user2=bob
  kali@kali:~$ grep $user2 /etc/passwd && echo "$user2 found!"
  ```
* || - The OR operator requires at-least 1 command, meaning, only if the first command failed, the next one will be executed.

  ```bash
  kali@kali:~$ grep $user2 /etc/passwd && echo "$user2 found!" || echo "$user2 not found!"
  bob not found!
  ```

**Boolean Operators**

The same && and || operator can be use like normal AND, OR in conditioning (if, else, etc)

## Loops

**For Loops**

```bash
for var-name in <list>
do
<action to perform>
done
```

**While Loops**

```bash
while [ <some test> ]
do
<perform an action>
done
```

```bash
# while loops example
counter=1
while [ $counter -le 10 ]
do
echo "10.11.1.$counter"
((counter++))
done
```

**Utility Commands**

* seq - sequence, seems to operate like python's 'range' function; 1st parameter is the first number on the list (inclusive), **2nd number is the end of the list (inclusive)**

  * A sequence can also be created by using 'brace expansion' = {1..10}

  ```bash
  ## ways to generate a list of number or chars

  # 1st way
  seq 1 10

  #2nd way
  {1..10}
  ```

## Functions

**Note:** The parenthasis serve only as decoration, parameters cannot be used.

```bash
# 1st format
function_name () {
commands...
}

# 2nd format 
function function_name {
commands...
}
```

To get return values from the functions we can:

* Use the $? global variable and receive an exit status (Zero for success, non-zero for failure)

```bash
#!/bin/bash
# function return value example
return_me() {
echo "Oh hello there, I'm returning a random value!"
return $RANDOM
}
return_me
echo "The previous function returned a value of $?"
kali@kali:~$ chmod +x ./funcrvalue.sh
kali@kali:~$ ./funcrvalue.sh
Oh hello there, I'm returning a random value!
The previous function returned a value of 198
```

* Set a new global variable with the value we want to return
* Use command substitution on the function and simulate a return value by assigning it to a new variable


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.221bluestreet.com/miscellaneous/bash-scripting.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
