diff --git a/curriculum/challenges/english/25-front-end-development/review-bash-scripting/6724e417419c2f211bb41bfc.md b/curriculum/challenges/english/25-front-end-development/review-bash-scripting/6724e417419c2f211bb41bfc.md index 9f81be99598..af070be047a 100644 --- a/curriculum/challenges/english/25-front-end-development/review-bash-scripting/6724e417419c2f211bb41bfc.md +++ b/curriculum/challenges/english/25-front-end-development/review-bash-scripting/6724e417419c2f211bb41bfc.md @@ -7,7 +7,708 @@ dashedName: review-bash-scripting # --description-- -Description placeholder +## Bash Scripting Basics + +- **Bash scripting**: Writing a sequence of Bash commands in a file, which you can then execute with Bash to run the contents of the file. +- **Shebang**: The commented line at the beginning of a script (e.g., `#!/bin/bash`) that indicates what interpreter should be used for the script. + + ```bash + #!/bin/bash + ``` + +- **Variable assignment**: Instantiate variables using the syntax `variable_name=value`. + + ```bash + servers=("prod" "dev") + ``` + +- **Variable creation rules**: Create variables with `VARIABLE_NAME=VALUE` syntax. No spaces are allowed around the equal sign (`=`). Use double quotes if the value contains spaces. + + ```bash + NAME=John + MESSAGE="Hello World" + COUNT=5 + TEXT="The next number is, " + ``` + +- **Variable usage**: Access variable values by placing `$` in front of the variable name. + + ```bash + echo $NAME + echo "The message is: $MESSAGE" + ``` + +- **Variable interpolation**: Use `$variable_name` to access the value of a variable within strings and commands. + + ```bash + TEXT="The next number is, " + NUMBER=42 + echo $TEXT B:$NUMBER + echo $TEXT I:$NUMBER + + echo "Pulling $server" + rsync --archive --verbose $server:/etc/nginx/conf.d/server.conf configs/$server.conf + ``` + +- **Variable scope**: Shell scripts run from top to bottom, so variables can only be used below where they are created. + + ```bash + NAME="Alice" + echo $NAME + ``` + +- **User input**: Use `read` to accept input from users and store it in a variable. + + ```bash + read USERNAME + echo "Hello $USERNAME" + ``` + +- **Comments**: Add comments to your scripts using `#` followed by your comment text. + - Single-line comments start with `#` and continue to the end of the line + - Comments are ignored by the shell and don't affect script execution + + ```bash + # This is a single-line comment + NAME="John" # Comment at end of line + ``` + +- **Multi-line comments**: Comment out blocks of code using colon and quotes. + + ```bash + : ' + This is a multi-line comment + Everything between the quotes is ignored + Useful for debugging or documentation + ' + ``` + +- **Built-in commands and help**: + - Use `help` to see a list of built-in bash commands + - Use `help ` to get information about specific built-in commands + - Some commands (like `if`) are built-ins and don't have man pages + - Built-in commands are executed directly by the shell rather than as external programs + - Use `help function` to see information about creating functions + + ```bash + help + help if + help function + ``` + +- **Finding command locations**: Use `which` to locate where executables are installed. + - Shows the full path to executable files + - Useful for finding interpreter locations (like bash) + - Helps verify which version of a command will be executed + + ```bash + which bash + which python + which ls + ``` + +- **Manual pages**: Use `man` to access detailed documentation for commands. + - Provides comprehensive information about command usage + - Shows all available options and examples + - Use arrow keys to navigate, 'q' to quit + - Not all commands have manual pages (built-ins use `help` instead) + + ```bash + man echo + man ls + man bash + ``` + +- **Help flags**: Many commands support `--help` for quick help information. + - Alternative to manual pages for quick reference + - Shows command syntax and common options + - Not all commands support this flag (some may show error) + + ```bash + ls --help + chmod --help + mv --help + ``` + +- **Echo command options**: The `echo` command supports various options: + - `-e` option enables interpretation of backslash escapes + - `\n` creates a new line + - Empty lines are only printed when values are enclosed in quotes + - Useful for creating formatted output and program titles + + ```bash + echo -e "Line 1\nLine 2" + echo "" + echo -e "\n~~ Program Title ~~\n" + echo "Line 1\nLine 2" + ``` + +- **Script arguments**: Programs can accept arguments that are accessible using `$` variables. + - `$*` prints all arguments passed to the script + - `$@` prints all arguments passed to the script as separate quoted strings + - `$` accesses specific arguments by position (e.g., `$1`, `$2`, `$3`) + + ```bash + echo $* + echo $@ + echo $1 + echo $2 + ``` + +## Double Bracket Expressions `[[ ]]` + +- **Double bracket syntax**: Use `[[ ]]` for conditional testing and pattern matching. + - Must have spaces inside the brackets and around operators + - Returns exit status 0 (true) or 1 (false) based on the test result + + ```bash + [[ $variable == "value" ]] + [[ $number -gt 10 ]] + [[ -f filename.txt ]] + ``` + +- **String comparison operators**: Compare strings using various operators within `[[ ]]`. + - `==` (equal): Tests if two strings are identical + - `!=` (not equal): Tests if two strings are different + - `<` (lexicographically less): String comparison in alphabetical order + - `>` (lexicographically greater): String comparison in alphabetical order + + ```bash + [[ "apple" == "apple" ]] + [[ "apple" != "orange" ]] + [[ "apple" < "banana" ]] + [[ "zebra" > "apple" ]] + ``` + +- **Numeric comparison operators**: Compare numbers using specific numeric operators. + - `-eq` (equal): Numeric equality comparison + - `-ne` (not equal): Numeric inequality comparison + - `-lt` (less than): Numeric less than comparison + - `-le` (less than or equal): Numeric less than or equal comparison + - `-gt` (greater than): Numeric greater than comparison + - `-ge` (greater than or equal): Numeric greater than or equal comparison + + ```bash + [[ $number -eq 5 ]] + [[ $count -ne 0 ]] + [[ $age -ge 18 ]] + [[ $score -lt 100 ]] + ``` + +- **Logical operators**: Combine multiple conditions using logical operators. + - `&&` (and): Both conditions must be true + - `||` (or): At least one condition must be true + - `!` (not): Negates the condition (makes true false, false true) + + ```bash + [[ $age -ge 18 && $age -le 65 ]] + [[ $name == "John" || $name == "Jane" ]] + [[ ! -f missing_file.txt ]] + ``` + +- **File test operators**: Test file properties and existence. + - `-e file`: True if file exists + - `-f file`: True if file exists and is a regular file + - `-d file`: True if file exists and is a directory + - `-r file`: True if file exists and is readable + - `-w file`: True if file exists and is writable + - `-x file`: True if file exists and is executable + - `-s file`: True if file exists and has size greater than zero + + ```bash + [[ -e /path/to/file ]] + [[ -f script.sh ]] + [[ -d /home/user ]] + [[ -x program ]] + ``` + +- **Pattern matching with `=~`**: Use regular expressions for advanced pattern matching. + - `=~` operator enables regex pattern matching + - Pattern should not be quoted when using regex metacharacters + - Supports full regular expression syntax + - Case-sensitive by default + + ```bash + [[ "hello123" =~ [0-9]+ ]] + [[ "email@domain.com" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]] + [[ "filename.txt" =~ \.txt$ ]] + ``` + +- **Variable existence testing**: Check if variables are set or empty. + - Test if variable is empty: `[[ ! $variable ]]` + + ```bash + [[ ! $undefined_var ]] + ``` + +## Double Parentheses Expressions `(( ))` + +- **Arithmetic evaluation**: Use `(( ))` for mathematical calculations and numeric comparisons. + - Evaluates arithmetic expressions using C-style syntax + - Variables don't need `$` prefix inside double parentheses + - Returns exit status 0 if result is non-zero, 1 if result is zero + - Supports all standard arithmetic operators + + ```bash + (( result = 10 + 5 )) + (( count++ )) + (( total += value )) + ``` + +- **Arithmetic operators**: Mathematical operators available in `(( ))`. + - `+` (addition): Add two numbers + - `-` (subtraction): Subtract second number from first + - `*` (multiplication): Multiply two numbers + - `/` (division): Divide first number by second (integer division) + - `%` (modulus): Remainder after division + - `**` (exponentiation): Raise first number to power of second + + ```bash + (( sum = a + b )) + (( diff = x - y )) + (( product = width * height )) + (( remainder = num % 10 )) + (( power = base ** exponent )) + ``` + +- **Assignment operators**: Modify variables using arithmetic assignment operators. + - `=` (assignment): Assign value to variable + - `+=` (add and assign): Add value to variable + - `-=` (subtract and assign): Subtract value from variable + - `*=` (multiply and assign): Multiply variable by value + - `/=` (divide and assign): Divide variable by value + - `%=` (modulus and assign): Set variable to remainder + + ```bash + (( counter = 0 )) + (( counter += 5 )) + (( total -= cost )) + (( area *= 2 )) + (( value /= 3 )) + ``` + +- **Increment and decrement operators**: Modify variables by one. + - `++variable` (pre-increment): Increment before use + - `variable++` (post-increment): Increment after use + - `--variable` (pre-decrement): Decrement before use + - `variable--` (post-decrement): Decrement after use + + ```bash + (( ++counter )) + (( index++ )) + (( --remaining )) + (( attempts-- )) + ``` + +- **Comparison operators**: Compare numbers using arithmetic comparison. + - `==` (equal): Numbers are equal + - `!=` (not equal): Numbers are not equal + - `<` (less than): First number is less than second + - `<=` (less than or equal): First number is less than or equal to second + - `>` (greater than): First number is greater than second + - `>=` (greater than or equal): First number is greater than or equal to second + + ```bash + (( age >= 18 )) + (( score < 100 )) + (( count == 0 )) + (( temperature > freezing )) + ``` + +- **Logical operators**: Combine arithmetic conditions. + - `&&` (and): Both conditions must be true + - `||` (or): At least one condition must be true + - `!` (not): Negates the condition + + ```bash + (( age >= 18 && age <= 65 )) + (( score >= 90 || extra_credit > 0 )) + (( !(count == 0) )) + ``` + +- **Bitwise operators**: Perform bit-level operations on integers. + - `&` (bitwise AND): AND operation on each bit + - `|` (bitwise OR): OR operation on each bit + - `^` (bitwise XOR): XOR operation on each bit + - `~` (bitwise NOT): Invert all bits + - `<<` (left shift): Shift bits to the left + - `>>` (right shift): Shift bits to the right + + ```bash + (( result = a & b )) + (( flags |= new_flag )) + (( shifted = value << 2 )) + ``` + +- **Conditional (ternary) operator**: Use `condition ? true_value : false_value` syntax. + - Provides a concise way to assign values based on conditions + - Similar to the ternary operator in C-style languages + - Evaluates condition and returns one of two values + + ```bash + (( result = (score >= 60) ? 1 : 0 )) + (( max = (a > b) ? a : b )) + (( sign = (num >= 0) ? 1 : -1 )) + ``` + +- **Command substitution with arithmetic**: Use `$(( ))` to capture arithmetic results. + - Returns the result of the arithmetic expression as a string + - Can be used in assignments or command arguments + - Useful for calculations that need to be used elsewhere + + ```bash + result=$(( 10 + 5 )) + echo "The answer is $(( a * b ))" + array_index=$(( RANDOM % array_length )) + ``` + +## Control Flow and Conditionals + +- **Conditional statements**: Use `if` statements to execute code based on conditions. + - Basic syntax: `if [[ CONDITION ]] then STATEMENTS fi` + - Full syntax: `if [[ CONDITION ]] then STATEMENTS elif [[ CONDITION ]] then STATEMENTS else STATEMENTS fi` + - Can use both `[[ ]]` and `(( ))` expressions for different types of conditions + - **elif (else if)**: Optional, can be repeated multiple times to test additional conditions in sequence + - **else**: Optional, executes when all previous conditions are false + - Can mix double parentheses `(( ... ))` and double brackets `[[ ... ]]` in same conditional chain + + ```bash + if (( NUMBER <= 15 )) + then + echo "B:$NUMBER" + elif [[ $NUMBER -le 30 ]] + then + echo "I:$NUMBER" + elif (( NUMBER < 46 )) + then + echo "N:$NUMBER" + elif [[ $NUMBER -lt 61 ]] + then + echo "G:$NUMBER" + else + echo "O:$NUMBER" + fi + ``` + +## Command Execution and Process Control + +- **Command separation**: Use semicolon (`;`) to run multiple commands on a single line. + - Commands execute sequentially from left to right + - Each command's exit status can be checked individually + + ```bash + [[ 4 -ge 5 ]]; echo $? + ls -l; echo "Done" + ``` + +- **Exit status**: Every command has an exit status that indicates success or failure. + - Access exit status of the last command with `$?` + - Exit status `0` means success (true/no errors) + - Any non-zero exit status means failure (false/errors occurred) + - Common error codes: `127` (command not found), `1` (general error) + + ```bash + echo $? + [[ 4 -le 5 ]]; echo $? + ls; echo $? + bad_command; echo $? + ``` + +- **Subshells and command substitution**: Different uses of parentheses for execution contexts. + - Single parentheses `( ... )` create a subshell + - `$( ... )` performs command substitution + - Subshells run in separate environments and don't affect parent shell variables + + ```bash + ( cd /tmp; echo "Current dir: $(pwd)" ) + current_date=$(date) + file_count=$(ls | wc -l) + echo "Today is $current_date" + echo "Found $file_count files" + ``` + +- **Sleep command**: Pause script execution for a specified number of seconds. + - Useful for creating delays in scripts + - Can be used with decimal values for subsecond delays + + ```bash + sleep 3 + sleep 0.5 + sleep 1 + ``` + +## Loops + +- **While loops**: Execute code repeatedly while a condition is true. + - Syntax: `while [[ CONDITION ]] do STATEMENTS done` + + ```bash + I=5 + while [[ $I -ge 0 ]] + do + echo $I + (( I-- )) + sleep 1 + done + ``` + +- **Until loops**: Execute code repeatedly until a condition becomes true. + - Syntax: `until [[ CONDITION ]] do STATEMENTS done` + + ```bash + until [[ $QUESTION =~ \?$ ]] + do + echo "Please enter a question ending with ?" + read QUESTION + done + until [[ $QUESTION =~ \?$ ]] + do + GET_FORTUNE again + done + ``` + +- **For loops**: Iterate through arrays or lists using `for` loops with `do` and `done` to define the loop's logical block. + + ```bash + for server in "${servers[@]}" + do + echo "Processing $server" + done + for (( i = 1; i <= 5; i++ )) + do + echo "Number: $i" + done + for (( i = 5; i >= 1; i-- )) + do + echo "Countdown: $i" + done + for i in {1..5} + do + echo "Count: $i" + done + ``` + +## Arrays + +- **Arrays**: Store multiple values in a single variable. + - Create arrays with parentheses: `ARRAY=("value1" "value2" "value3")` + - Access elements by index: `${ARRAY[0]}`, `${ARRAY[1]}` + - Access all elements: `${ARRAY[@]}` or `${ARRAY[*]}` + - Array indexing starts at 0 + + ```bash + RESPONSES=("Yes" "No" "Maybe" "Ask again later") + echo ${RESPONSES[0]} + echo ${RESPONSES[1]} + echo ${RESPONSES[5]} + echo ${RESPONSES[@]} + echo ${RESPONSES[*]} + ``` + +- **Array inspection with declare**: Use `declare -p` to view array details. + - Shows the array type with `-a` flag + - Displays all array elements and their structure + + ```bash + ARR=("a" "b" "c") + declare -p ARR # ARR=([0]="a" [1]="b" [2]="c") + ``` + +- **Array expansion**: Use `"${array_name[@]}"` syntax to expand an array into individual elements. + +```bash +for server in "${servers[@]}" +``` + +## Functions + +- **Functions**: Create reusable blocks of code. + - Define with `FUNCTION_NAME() { STATEMENTS }` + - Call by using the function name + - Can accept arguments accessible as `$1`, `$2`, etc. + + ```bash + GET_FORTUNE() { + echo "Ask a question:" + read QUESTION + } + GET_FORTUNE + ``` + +- **Function arguments**: Functions can accept arguments just like scripts. + - Arguments are passed when calling the function + - Access arguments inside function using `$1`, `$2`, etc. + - Use conditional logic to handle different arguments + + ```bash + GET_FORTUNE() { + if [[ ! $1 ]] + then + echo "Ask a yes or no question:" + else + echo "Try again. Make sure it ends with a question mark:" + fi + read QUESTION + } + GET_FORTUNE + GET_FORTUNE again + ``` + +## Random Numbers and Mathematical Operations + +- **Random numbers**: Generate random values using the `$RANDOM` variable. + - `$RANDOM` generates numbers between 0 and 32767 + - Use modulus operator to limit range: `$RANDOM % 75` + - Add 1 to avoid zero: `$(( RANDOM % 75 + 1 ))` + - Must use `$(( ... ))` syntax for calculations with `$RANDOM` + + ```bash + NUMBER=$(( RANDOM % 6 )) + DICE=$(( RANDOM % 6 + 1 )) + BINGO=$(( RANDOM % 75 + 1 )) + echo $(( RANDOM % 10 )) + ``` + +- **Random array access**: Use random numbers to access array elements randomly. + - Generate random index within array bounds + - Use random index to access array elements + - Useful for random selections from predefined options + + ```bash + RESPONSES=("Yes" "No" "Maybe" "Outlook good" "Don't count on it" "Ask again later") + N=$(( RANDOM % 6 )) + echo ${RESPONSES[$N]} + ``` + +- **Modulus operator**: Use `%` to get the remainder of division operations. + - Essential for limiting random number ranges + - Works with `$RANDOM` to create bounded random values + - `RANDOM % n` gives numbers from 0 to n-1 + + ```bash + echo $(( 15 % 4 )) + echo $(( RANDOM % 100 )) + echo $(( RANDOM % 10 + 1 )) + ``` + +## Environment and System Information + +- **Environment variables**: Predefined variables available in the shell environment. + - `$RANDOM`: Generates random numbers between 0 and 32767 + - `$LANG`: System language setting + - `$HOME`: User's home directory path + - `$PATH`: Directories searched for executable commands + - View all with `printenv` or `declare -p` + + ```bash + echo $RANDOM + echo $HOME + echo $LANG + printenv + ``` + +- **Variable inspection**: Use `declare` to view and work with variables. + - `declare -p`: Print all variables and their values + - `declare -p VARIABLE`: Print specific variable details + - Shows variable type (string, array, etc.) and attributes + + ```bash + declare -p + declare -p RANDOM + declare -p MY_ARRAY + ``` + +- **Command types**: Different categories of commands available in bash. + - **Built-in commands**: Executed directly by the shell (e.g., `echo`, `read`, `if`) + - **External commands**: Binary files in system directories (e.g., `ls`, `sleep`, `bash`) + - **Shell keywords**: Language constructs (e.g., `then`, `do`, `done`) + - Use `type ` to see what type a command is + + ```bash + type echo + type ls + type if + type ./script.sh + ``` + +## File Creation and Management + +- **File creation**: Use `touch` to create new empty files. + - Creates a new file if it doesn't exist + - Updates the timestamp if the file already exists + - Commonly used to create script files before editing + + ```bash + touch script.sh + touch bingo.sh + touch filename.txt + ``` + +## Creating and Running Bash Scripts + +- **Script execution methods**: Multiple ways to run bash scripts: + - **`sh scriptname.sh`**: Run with the sh shell interpreter. + - **`bash scriptname.sh`**: Run with the bash shell interpreter. + - **`./scriptname.sh`**: Execute directly (requires executable permissions). + +```bash +sh questionnaire.sh +bash questionnaire.sh +./questionnaire.sh +``` + +## File Permissions and Script Execution + +- **Permission denied error**: When using `./scriptname.sh`, you may get "permission denied" if the file lacks executable permissions. +- **Checking permissions**: Use `ls -l` to view file permissions. + + ```bash + ls -l questionnaire.sh + ``` + +- **Permission format**: The output shows permissions as `-rw-r--r--` where: + - First character (`-`): File type (- for regular file, d for directory) + - Next 9 characters: Permissions for owner, group, and others + - `r` = read, `w` = write, `x` = execute + +- **Adding executable permissions**: Use `chmod +x` to give executable permissions to everyone. + + ```bash + chmod +x questionnaire.sh + ``` + +- **Script organization**: Best practices for structuring bash scripts. + - Start with shebang (`#!/bin/bash`) + - Add descriptive comments about script purpose + - Define variables at the top + - Group related functions together + - Main script logic at the bottom + + ```bash + #!/bin/bash + NAME="value" + ARRAY=("item1" "item2") + my_function() { + echo "Function code here" + } + my_function + echo "Script complete" + ``` + +- **Sequential script execution**: Create master scripts that run multiple programs in sequence. + - Useful for automating workflows that involve multiple scripts + - Each script runs to completion before the next one starts + - Can combine different programs into a single execution flow + - Arguments can be passed to individual scripts as needed + - Can include different types of programs (interactive, automated, etc.) + + ```bash + #!/bin/bash + ./setup.sh + ./interactive.sh + ./processing.sh + ./cleanup.sh + ``` # --assignment--