Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...

Full Transcript

**Week 10** **CONTROL STATEMENT** **1. Control Structures / Control Statements** Control structures, also known as control statements, alter the sequence of command execution in shell scripts. They are essential for handling errors and controlling flow. - **1.1 Humans vs. Shell Programs:**...

**Week 10** **CONTROL STATEMENT** **1. Control Structures / Control Statements** Control structures, also known as control statements, alter the sequence of command execution in shell scripts. They are essential for handling errors and controlling flow. - **1.1 Humans vs. Shell Programs:** - Humans manually executing shell commands can respond to errors, whereas shell programs execute commands sequentially regardless of errors. - **1.2 Importance of Control Structures:** - Control structures allow scripts to skip commands upon errors or repeat commands under certain conditions (loops). - **1.3 Example with if Statement:** - An if statement checks the exit status of commands. It executes subsequent commands only if the preceding command succeeds (exit status of zero). - **1.4 Handling Errors with if and else:** - An if-else statement provides alternative commands to execute if the initial command fails (exit status non-zero). - **2. Branch Conditional Shell Control Structures - if, then, else, fi:** Unix/Linux shells use command exit statuses for branching, unlike most programming languages that use logical or arithmetic expressions. - **2.1 Simple if Statement:** - Executes a command or command list if a test condition succeeds. - **2.2 Inverting Command Exit Status:** - Prefixing a command with ! inverts its exit status, useful for executing commands on failure rather than success. - **2.3 if-else Statement:** - Provides two branches based on the success or failure of a test condition. - **2.4 Nested if Statements:** - Allows embedding one if statement inside another to handle more complex conditions sequentially. - **3. Indentation in Shell Scripts:** - Proper indentation enhances readability but is ignored by the shell itself. Clear indentation improves script maintenance and understanding. **4 The test Helper Program -- File Tests, String Tests, and Integer Expressions** Despite the command-oriented nature of Unix/Linux shells, shell scripts often need to make conditional decisions based on file system object properties, string comparisons, and numeric values. Shell if statements rely on the exit status of commands, so a helper command like test is used for comparisons, setting exit statuses based on tests. **4.1 Simple Examples: Testing File Existence with -f** The test command checks file existence silently: - test -f \"/bin/bash\" returns 0 (success) because /bin/bash exists and is a file. - test -f \"/bin/nosuchfile\" returns 1 (failure) as /bin/nosuchfile does not exist. **4.2 Built-in test Commands** Most shells include a built-in test command for essential control statements in shell scripts. Differences from the external test command are documented in the shell\'s manual. **4.3 Three Main Categories of Tests: Pathname, String, Numeric** The test command covers: - Pathname properties: -e, -f, -d, -r, -w, -x, -s. - String comparisons: -z, -n, =, !=. - Integer comparisons: -eq, -ne, -lt, -le, -gt, -ge. **4.4 Using test for Pathname Properties (-f, -d, etc.)** Tests include existence (-e), file (-f), directory (-d), readable (-r), writable (-w), executable (-x), and size (-s). **4.5 Comparing Text Strings (-z, -n, =, !=)** Use -z to test for an empty string, -n for a non-empty string, = for string equality, and != for inequality. **4.6 Warning: Single Argument Test (-n)** A single argument is automatically tested as -n, checking if the string is non-empty. Always use quotes to avoid unexpected behavior. **4.7 Comparing Integer Numbers (-eq, -ne, -lt, -le, -gt, -ge)** Numeric comparisons include -eq (equal), -ne (not equal), -lt (less than), -le (less than or equal), -gt (greater than), and -ge (greater than or equal). **4.8 Comparing Strings vs Integers** String and numeric comparisons differ in syntax and results: - test 0 = 00 fails for strings but succeeds with -eq for numbers. **4.9 Combining Test Expressions with Logical AND -a and OR -o** Combine tests using -a (AND) and -o (OR) but ensure each side of the operator is a valid test expression. **4.10 Negating Test Expressions with !** Use ! to negate the exit status of a test expression. For multiple expressions, use parentheses for clarity. **4.11 Two Ways of Negating Test Expressions** Negate single expressions using ! within test or negate the entire command using ! before test. **4.12 Using test with Variables** Test variables directly in test expressions, ensuring proper quoting. **4.13 Using \[ as a Synonym for test** The \[ command is syntactic sugar for test, allowing more readable conditional expressions in shell scripts. This structure maintains the numbering sequence as requested. 8.1 **Using \| for multiple GLOB patterns:** - Further condense case statements by using \| to list multiple GLOB patterns on the same line. This reduces the script size and enhances clarity. 8.2 **Example: Classify a pathname:** - Demonstrates case usage with GLOB patterns to classify pathnames based on their structure (/, \*/, \*/\*, etc.). This illustrates practical use of GLOB patterns in script logic. 8.3 **Example: Find the star/asterisk/\*:** - Shows more examples of GLOB patterns in case statements, highlighting matching behavior (\*, \*\'\*\', etc.) and practical applications for handling different string patterns. 8.4 **Example: Matching numbers by counting digits:** - Uses GLOB patterns to categorize numeric values into ranges (0, \[1-9\], \[1-4\]\[0-9\], etc.), demonstrating how to use case for numeric comparisons within a script. 8.5 **Example: Validating an argument using a complemented character class:** - Utilizes GLOB patterns with POSIX character classes (\[!\[:alpha:\]\]) in a case statement to validate arguments based on character types (alphabetic vs. non-alphabetic), ensuring input matches expected criteria. 8.5.1 **Detailed explanation of GLOB pattern *\[!\[:digit:\]\]*:** - Provides a step-by-step breakdown of a GLOB pattern (\*\[!\[:digit:\]\]\*) used in script validation, explaining how it matches non-digit characters in an argument. These examples showcase how to leverage case statements with GLOB patterns effectively in shell scripting to simplify logic and improve script readability. If you have any specific questions or need further details on any part, feel free to ask! **9 Loop Conditional Shell Control Structures -- while, for, do, done** Reference: Chapter 9. Repetitive tasks  Unix/Linux shells are designed to find and run commands. This means that the programming control structures of shells are based on the exit statuses of running commands. **9.1 The while... do... done loop statement** The while loop repeats a list of commands based on the success/failure of a command return code. Syntax: bash Copy code while testing\_command\_list ; do zero\_command\_list done Example: bash Copy code while who \| fgrep \"\$1\" ; do echo \"User \'\$1\' is still signed on\" sleep 10 done **9.2 The for... do... done loop statement** The for loop iterates over a list of words, either explicitly specified or derived from command line arguments. Syntax: bash Copy code for name in word1 word2 ; do command\_list done Example: bash Copy code for i in dog cow pig ; do echo \"See the \$i run!\" done **9.3 Exit a loop in the middle: break** The break statement exits a loop prematurely based on a condition. Example: bash Copy code while \[ \$count -lt 100 \] ; do if ! touch \"\$name\" ; then echo 1\>&2 \"\$0: Failed to touch \'\$name\'\" break fi done **9.4 Return to the top of a loop: continue** The continue statement skips the remaining commands in a loop iteration and moves to the next iteration. Example: bash Copy code for name do if \[ ! -e \"\$name\" \] ; then echo \"\$0: \'\$name\' is inaccessible or does not exist; skipped\" continue fi done These control structures provide flexibility in shell scripting to manage repetitive tasks effectively. **10. Shifting positional parameters: shift so \$2 becomes \$1** - Scripts often need to handle varying numbers of command-line arguments using positional parameters like \$1, \$2, etc. - The shift command in shell scripts moves all positional parameters down by one. For example: shell Copy code \#!/bin/sh -u echo \"\'\$1\' is the first argument of \$\#: \$\*\" shift echo \"\'\$1\' is the first argument of \$\#: \$\*\" shift echo \"\'\$1\' is the first argument of \$\#: \$\*\" shift echo \"\'\$1\' is the first argument of \$\#: \$\*\" shift echo \"\'\$1\' is the first argument of \$\#: \$\*\" - Running the script with ./example.sh one two three four five six results in: - Using shift in a loop can process all command-line arguments until none are left, using \$\# to check argument count. **11. Shell functions** - Functions in shell scripts allow encapsulating reusable code with parameters. - Example syntax: shell Copy code Foo () { echo \"Hello \$\*\" ; } Foo a b c - Functions are defined within the shell session and lost on exit unless defined in .bashrc. - Parameters passed to functions become their positional parameters (\$1, \$2, etc.). **11.1 Example: ErrorExit function to exit a script** - Centralizes error handling in functions for better script readability and maintenance. shell Copy code ErrorExit () { echo 1\>&2 \"\$0: \$\*\" echo 1\>&2 \"Usage \$0 \[filename\]\" exit 1 } - Example usage: shell Copy code if \[ \$\# -ne 1 \]; then ErrorExit \"Expecting one filename argument; found \$\# (\$\*)\" fi **12. Short-circuit command list operators: && and \|\|** - Used to conditionally execute commands based on previous command success or failure. - Examples: shell Copy code command\_1 \|\| command\_2 \# Execute command\_2 only if command\_1 fails command\_1 && command\_2 \# Execute command\_2 only if command\_1 succeeds - Useful for compact error handling in scripts but lacks detailed error messages compared to traditional if-statements. **13. Reading input in shell scripts -- read** - Built-in command read in Bourne shell family reads input from standard input. - Examples: shell Copy code read -p \"Enter a number: \" num1 read -p \"Enter a number: \" num2 echo \"The sum is \$(( num1 + num2 ))\" - Handles input from terminals or files/pipes, splitting input into variables based on whitespace. This summary condenses the key points from each section while maintaining the original numbering and content structure. **GOOD ERROR MESSAGE** **1. Good Error Messages and Usage Messages** 1.1 **Must appear on standard error, not standard output: 1\>&2** - Error messages should be directed to standard error (stderr) using 1\>&2. - This ensures messages appear on the terminal and not redirected into files unintentionally. 1.2 **Must contain the name of the program from \$0** - Error messages should include the script\'s name from the \$0 variable, not hardcoded. - This ensures clarity and adaptability if the script is renamed. 1.3 **Must state what kind of input was expected** - Error messages should specify exactly what type and how many inputs were expected. - Avoid vague terms like \"argument\" or \"parameter\". 1.4 **Must display what input the user actually entered** - Error messages should show both the number of arguments (\$\#) and their values (\$\*). - Enclose user inputs in quotes to clarify their nature. 1.5 **Example** - Example of a well-formed error message: - Provides all necessary details: stderr redirection, script name, expected input type and count, and user-entered values. 1.6 **Summary: Four properties of Good Error Messages** - Good error messages must: - Appear on stderr (1\>&2). - Include the script\'s name (\$0). - Clearly specify expected input type and count. - Display user-supplied input values (\$\# and \$\*). **2. The Usage Message** - After detecting a usage error, print a clear error message followed by usage instructions. - Usage messages should follow standard syntax conventions (like man pages) for optional and repeated arguments. 2.1 **Only display for actual Usage Errors** - Display the usage message only when the script usage is incorrect. - Avoid displaying it for unrelated errors (e.g., permissions issues, missing files) where the script was used correctly. **SHELL SCRIPT PROBLEMS**  **Avoiding Common Script Problems** - Shell scripts often produce vague error messages. - Write scripts incrementally to locate errors easily. - Use debug options like -x or -v for debugging.  **Scripts Don't Do Arithmetic** - Shells execute commands; use commands in if statements. - Incorrect use example: if \$\# -gt 0.  **Don't Mix Square Brackets and Command Names** - Incorrect: if \[ fgrep foo /etc/passwd \]. - Correct: if fgrep foo /etc/passwd.  **The Square Bracket Syntax Needs Surrounding Blanks** - Incorrect: if \[1 -eq 1 \]. - Correct: if \[ 1 -eq 1 \].  **Don't Forget Blanks Around Test Operators** - Incorrect: test 1=2. - Correct: test 1 = 2.  **Don't Use Redirection Operators \< or \> for -lt or -gt** - Incorrect: test 1 \> 2. - Correct: test 1 -gt 2.  **The Test String Equality Operator is = Not ==** - Correct: \[ \"\$1\" = \'\--help\' \].  **Don't Confuse Empty/Null Arguments with Missing Ones** - Difference between missing, empty, and space arguments.  **Avoid Double Negatives or Double Exit Status Inversions** - Avoid confusing negation operators.  **For Programmers: Don't Use Shell Boolean Operators && or \|\| for -a AND or -o OR** - Correct usage of -a and -o.  **Don't Mix Comparing Strings and Comparing Numbers in Test** - Correct use of operators for strings and numbers.  **Opposites and False Opposites in Test** - Understand logical opposites in test operations.  **The Multiple Causes of Failure of Test Pathname Tests** - Be specific in error messages for pathname tests.  **Multiple Test Expressions Cloud Error Message** - Avoid complex error messages by separating tests.  **Use Less Code** - Simplify scripts for better readability and efficiency.

Use Quizgecko on...
Browser
Browser