# 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)