# Global Variable
1. Why need global variable? why is it mandotary?
-> [Global Variable Explained](https://hackmd.io/@QBrv51OvRPqs9dJjL2YIig/r1QGZeWfJl)
---
# Absolute path command
```bash
/bin/cat /etc/hostname
/bin/date
/bin/pwd
* (return value: 1)
/bin/mv /home/user/file.txt /home/user/backup/
```
---
# Echo
```bash
echo
echo -n kekekel
echo -nnnnnnnn kekekke
echo -n-n ekekle -n
echo ekekle -n
echo ekekle -nnnn
echo -n "Hello, World!"
echo -n ""
echo " Hello World "
echo Hello World
echo Hello World""
echo Hello World" "yo
echo -n "Hello, World!"
```
---
# Exit
* LONG MAX / LONG MIN
https://learn.microsoft.com/fr-fr/cpp/cpp/integer-limits?view=msvc-170
```bash
exit
```
```bash
exit 0
```
**Expected Outcome:** The shell terminates with exit status `0` (indicating successful completion).
```bash
exit 1
```
**Expected Outcome:** The shell terminates with exit status `1` (indicating an error or failure).
```bash
# test_script.sh
exit 2
```
**Expected Outcome:** The script exits with status `2`.
```bash
exit 999
```
**Expected Outcome:** The exit status will be `999 % 256 = 231`.
```bash
exit -1
```
**Expected Outcome:** The negative number will be treated as a positive number by taking modulo 256. So, `-1 % 256 = 255`, meaning the shell will exit with status `255`.
```bash
exit "error"
```
**Expected Outcome:** Bash will raise a syntax error, as `exit` expects an integer argument.
```bash
exit 300
```
**Expected Outcome:** Exit code `300` is treated as `300 % 256 = 44`. The shell exits with status `44`.
```bash
exit 255
```
**Expected Outcome:** The terminal will close and return exit status `255`.
```bash
echo "Hello" | exit 1
```
**Expected Outcome:** The pipeline will terminate with the exit status of `exit`, in this case, `1`.
```bash
//Test Input
exit 1 j
//Expected bash output
➜ minishell git:(master) ✗ bash --posix
bash-5.1$ exit 1 j
exit
bash: exit: too many arguments
bash-5.1$ exit
exit
➜ minishell git:(master) ✗ echo $?
1
```
```bash
//Test input
exit j 1
// Expected bash output
➜ minishell git:(master) ✗ bash --posix
bash-5.1$ exit j 1
exit
bash: exit: j: numeric argument required
➜ minishell git:(master) ✗ echo $?
2
```
*NO NEED HANDLE*
#### `exit` when a script is running in the background:
Tests how `exit` behaves in a background process.
```bash
(exit 99) &
```
**Expected Outcome:** The background process terminates with exit status `99`. You can check the exit status with `echo $?` (from the foreground shell).
#### `exit` in a nested script (exiting a subshell):
Tests how `exit` behaves when used inside a subshell.
```bash
(exit 5)
```
**Expected Outcome:** The subshell exits with status `5`, but the parent shell remains unaffected (i.e., the parent shell continues execution or remains open).
---
# Double Quotes / Single Quotes
```bash
echo "cat > lol.c | cat > lol.c"
```
```bash
echo $USER
```
```bash
echo "$USER"
```
```bash
echo '$USER'
```
```bash
echo "It's a sunny day"
```
```bash
echo 'The "quick" fox jumps'
```
```bash
echo 'It\'s a test'
```
```bash
echo "cat > lol.c"
```
```bash
echo 'cat > lol.c'
```
```bash
echo "$HOME/.bashrc"
```
```bash
echo "echo Hello | grep Hello > output.txt"
```
```bash
echo "This is a test: It's a success"
```
*NO NEED HANDLE*
```bash
bash-5.1$ echo "The \"quick\" fox"
The "quick" fox
bash-5.1$ echo "The current user is $(whoami)"
The current user is yilin
```
```bash
supershell>$ echo "The \"quick\" fox"
The \quick\ fox
supershell>$ echo "The current user is $(whoami)"
The current user is (whoami)
```
---
# env
*Special Notes (some people may ask):*
```bash
SHLVL=2
```
The `SHLVL` environment variable represents the **shell level**. It indicates the depth of the current shell session in terms of how many times a shell has been invoked.
- A value of `1` typically refers to the initial shell session (i.e., the shell you directly log into).
- A value of `2` means that you've started a new shell from the initial shell (e.g., by running `bash` or `zsh` from within the first shell).
- Each time you start a new shell session (whether it's interactive or not), the `SHLVL` variable is incremented by 1.
So `SHLVL=2` means you're currently in a second-level shell session (e.g., you're running a shell inside another shell).
---
# export / unset / environment variable
```bash
export
export USER=yilin
export NEW=weshwesh
env
export
echo $USER
echo $NEW
```
---
# cd /pwd
```bash
cd documents
```
```bash
cd ..
```
```bash
cd ../../
```
```bash
cd music
```
```bash
cd ../music
```
### **2. Absolute Path**
```bash
cd /home/user/documents
```
```bash
cd /
```
```bash
cd /var/log
```
```bash
cd $HOME
```
If `/home/user/My Documents` exists, you can use the absolute path:
```bash
cd "/home/user/My Documents"
```
```bash
cd /home/user/shortcut
```
### **3. Combining Relative and Absolute Path**
```bash
cd /home/user/documents/projects
```
---
# redirec / heredoc
- **Valid: Redirecting output to a file**:
```bash
echo "Hello World" > output.txt
```
This writes "Hello World" into `output.txt`, creating the file if it doesn't exist.
- **Valid: Redirecting output to an existing file (overwrite)**:
```bash
echo "New content" > output.txt
```
- **Invalid: Trying to redirect to a directory**:
```bash
echo "This will fail" > /home/user/
```
Error: `bash: /home/user/: Is a directory`.
- **Invalid: Redirecting output without write permission**:
```bash
echo "Some content" > /root/output.txt
```
Error: `bash: /root/output.txt: Permission denied`.
## **Redirection with `>>` (Append Output to a File)**
- **Valid: Appending output to a file**:
```bash
echo "Appended content" >> output.txt
```
- **Valid: Appending output to an existing file**:
```bash
echo "More content" >> output.txt
```
- **Invalid: Appending to a file without write permissions**:
```bash
echo "This will fail" >> /root/output.txt
```
Error: `bash: /root/output.txt: Permission denied`.
## **Input Redirection with `<` (Read Input from a File)**
- **Valid: Redirecting input from a file**:
```bash
cat < input.txt
```
This takes the content of `input.txt` and sends it to the `cat` command.
- **Invalid: Input redirection from a non-existing file**:
```bash
cat < nonexistentfile.txt
```
Error: `bash: nonexistentfile.txt: No such file or directory`.
- **Valid: Using input redirection in a pipeline**:
```bash
grep "pattern" < input.txt
```
## **Heredoc (`<<`)**
- **Valid: Using `<<` for multi-line input**:
```bash
cat <<EOF
This is a multi-line
string example
EOF
```
- **Invalid: Misusing `<<` with a missing delimiter**:
```bash
cat << # No delimiter specified
```
- **Valid: Using `<<` to pass a string to a command**:
```bash
sort <<EOF
banana
apple
orange
EOF
```
- **Invalid: Missing closing delimiter for `<<`**:
```bash
cat <<EOF
This will cause an error
```
### **Heredoc with Variable Expansion (`<<-`)**
- **Valid: Using `<<-` with variable expansion**:
```bash
VAR="Variable Expansion"
cat <<-EOF
This is a test for $VAR.
EOF
```
---
# **Pipe (`|`)**
- **Valid: Piping output between commands**:
```bash
ls | grep ".txt"
```
- **Valid: Multiple commands piped together**:
```bash
ls | grep ".txt" | sort
```
- **Valid: Pipe output through `more`**:
```bash
ls | more
```
- **Invalid: Pipe to a non-existent command**:
```bash
ls | non_existent_command
```
Error: `bash: non_existent_command: command not found`.
- **Valid: Using `pipe` with `cat` and `grep`**:
```bash
cat file.txt | grep "pattern"
```
- **Invalid: Pipe with a command that expects input**:
```bash
echo "hello" | cat > output.txt | more
```
This doesn't work as expected because `cat` takes input from the pipe and sends it to `output.txt`, so `more` won’t receive the content.
## **Edge Cases:**
- **Pipe with an invalid command in between**:
```bash
ls | non_existent_command | more
```
Error: `bash: non_existent_command: command not found`.
- **Redirection to a file and then pipe**:
```bash
ls > output.txt | grep "pattern"
```
This may not work as expected because the pipe (`|`) executes in the background, while the redirection (`>`) runs in the foreground. The pipe will be executed before the redirection completes.
- **Piping commands with mixed valid and invalid commands**:
```bash
ls | non_existent_command | more
```
The first valid command will execute, but the error for `non_existent_command` will halt the pipeline.
- **Redirecting the output of a command to both a file and the pipe**:
```bash
ls > output.txt | grep ".txt"
```
This syntax won't work as expected, since `> output.txt` overwrites the file first, and the pipe won’t take effect until after the file redirection.
## **Complex Examples:**
- **Valid: Pipe with a valid sequence**:
```bash
cat file.txt | grep "pattern" | sort | more
```
- **Valid: Combining input/output redirection with pipes**:
```bash
cat < input.txt | grep "pattern" > output.txt
```
---
# Other Important Edge cases!
## cat | ls related
```bash
cat
//infinite loop
//terminate with ctrl+c
exit
echo $?
```
-> Will cause infinite loop, in minishell can be marked as "Syntax Error"
-> Should be Terminated with Ctrl+C
-> Exit the program with "exit" command
-> Exit code should be 130 (Terminated by signal)
*Need to use ctrl+c to terminate "cat"*
```bash
cat | ls
```
-> **Output:** The same as running **ls**. The contents of the current directory will be displayed.
- cat reads from its standard input (stdin) but doesn't receive any input from a file or terminal in this case.
- The pipe sends cat's output (empty in this case) as input to ls, but ls does not consume stdin.
- ls lists the contents of the current directory.
```bash
cat | cat | ls
```
-> **Output:** The same as running **ls**. The contents of the current directory will be displayed.
- The first cat reads from stdin but doesn't receive input, so it produces no output.
- The second cat receives nothing from the first cat, so it also produces no output.
- ls runs independently of the pipe and lists the contents of the current directory.
```bash
ls | cat
```
-> Output: The output of ls, showing the contents of the current directory, will be displayed.
- ls lists the contents of the current directory, sending its output to the pipe.
- cat reads from the pipe and writes the contents to stdout without modification.
```bash
ls | cat | cat
```
-> Output: The output of ls, showing the contents of the current directory, will be displayed. This is equivalent to ls.
- ls lists the contents of the current directory, sending its output to the first cat.
- The first cat passes the data unchanged to the second cat.
- The second cat writes the data to stdout.
## unset PATH
```bash
unset PATH
```
-> Can only run builtin functions (env, export, unset, cd, exit, echo)