From 700322b40bf852ef4bbc64efc5b035e4011a1658 Mon Sep 17 00:00:00 2001 From: ganome Date: Sat, 7 Sep 2024 10:14:32 -0600 Subject: [PATCH] Sanitize Chapter 7 --- 07 - Shell Scripting Basics/Bash Loops.md | 112 +++++++-------- .../Bash Scripting Basics.md | 37 ++--- .../Conditional Statements.md | 128 +++++++++--------- .../Functions in Bash.md | 100 +++++++------- .../Script Debugging Techniques.md | 52 +++---- .../User Iput and Arguments in Bash.md | 126 ++++++++--------- 6 files changed, 265 insertions(+), 290 deletions(-) diff --git a/07 - Shell Scripting Basics/Bash Loops.md b/07 - Shell Scripting Basics/Bash Loops.md index 14de4e4..6e5c43b 100644 --- a/07 - Shell Scripting Basics/Bash Loops.md +++ b/07 - Shell Scripting Basics/Bash Loops.md @@ -7,41 +7,41 @@ Loops are fundamental constructs in programming that allow you to execute a set The 'for' loop is used to iterate over a list of items or a range of values. Syntax: -```bash +``` for variable in list do - commands +commands done ``` Examples: - Iterating over a list of items: -```bash +``` for fruit in apple banana orange do - echo "I like $fruit" +echo "I like $fruit" done ``` - Iterating over a range of numbers: -```bash -for i in {1..5} +``` +for i in {1..5} #{1..5} is using brace expansion for everything in the range of 1-5 do - echo "Number: $i" +echo "Number: $i" done ``` - C-style for loop: -```bash +``` for ((i=0; i<5; i++)) do - echo "Count: $i" +echo "Count: $i" done ``` - Iterating over files in a directory: -```bash +``` for file in *.txt do echo "Processing $file" @@ -54,34 +54,34 @@ done The 'while' loop executes a set of commands as long as a given condition is true. Syntax: -```bash +``` while condition do - commands +commands done ``` Examples: - Basic while loop: -```bash +``` count=1 -while [ $count -le 5 ] +while [ $count -le 5 ] # -le is less than or equal to do - echo "Count: $count" - ((count++)) +echo "Count: $count" +((count++)) done ``` - Reading input until a condition is met: -```bash -while read -p "Enter a number (0 to exit): " num +``` +while read -p "Enter a number (0 to exit): " num # the read command takes user input and stores it as a variable do - if [ "$num" -eq 0 ]; then - echo "Exiting..." - break - fi - echo "You entered: $num" +if [ "$num" -eq 0 ]; then +echo "Exiting..." +break +fi +echo "You entered: $num" done ``` @@ -90,21 +90,21 @@ done The 'until' loop is similar to the while loop, but it executes commands until a condition becomes true. Syntax: -```bash +``` until condition do - commands +commands done ``` Example: -```bash +``` count=1 until [ $count -gt 5 ] do - echo "Count: $count" - ((count++)) +echo "Count: $count" +((count++)) done ``` @@ -116,67 +116,67 @@ Bash provides two main loop control statements: - continue: Skips the rest of the current iteration and moves to the next one Example using both: -```bash +``` for i in {1..10} do - if [ $i -eq 5 ]; then - continue - fi - if [ $i -eq 8 ]; then - break - fi - echo "Number: $i" +if [ $i -eq 5 ]; then +continue +fi +if [ $i -eq 8 ]; then +break +fi +echo "Number: $i" done ``` ## 5. Advanced Loop Techniques - Nested loops: -```bash +``` for i in {1..3} do - for j in {1..3} - do - echo "i=$i, j=$j" - done +for j in {1..3} +do +echo "i=$i, j=$j" +done done ``` - Looping through arrays: -```bash +``` declare -a fruits=("apple" "banana" "orange" "grape") for fruit in "${fruits[@]}" do - echo "I like $fruit" +echo "I like $fruit" done ``` - Infinite loops (use with caution): -```bash -while true +``` +while true # the "true" command always returns TRUE -so this will loop forever! do - echo "This will run forever unless interrupted" - sleep 1 +echo "This will run forever unless interrupted" +sleep 1 done ``` - Looping with command substitution: -```bash -for line in $(cat file.txt) +``` +for line in $(cat file.txt) # $() is command substitution - you can put a command in here and the output will be used! do - echo "Line: $line" +echo "Line: $line" done ``` - Parallel execution of loops: -```bash +``` for job in job1 job2 job3 do - ( - echo "Starting $job" - sleep 2 - echo "Finished $job" - ) & +( +echo "Starting $job" +sleep 2 +echo "Finished $job" +) & done wait echo "All jobs completed" diff --git a/07 - Shell Scripting Basics/Bash Scripting Basics.md b/07 - Shell Scripting Basics/Bash Scripting Basics.md index 441fa92..a75f8a3 100644 --- a/07 - Shell Scripting Basics/Bash Scripting Basics.md +++ b/07 - Shell Scripting Basics/Bash Scripting Basics.md @@ -7,7 +7,7 @@ Bash (Bourne Again SHell) is a command-line interface and scripting language use To create a Bash script: - Open a text editor -- Start the file with a shebang: #!/bin/bash +- Start the file with a shebang: #!/bin/bash # This line tells the shell what to use as the interpreter. Can be bash, python, etc... - Add your commands - Save the file with a .sh extension (e.g., myscript.sh) - Make the script executable: chmod +x myscript.sh @@ -23,7 +23,7 @@ echo "Hello, World!" Variables in Bash are created by assigning a value: -```bash +``` name="John" age=30 echo "Name: $name, Age: $age" @@ -31,16 +31,17 @@ echo "Name: $name, Age: $age" Use `$` to reference variables. For command substitution, use `$(command)`: -```bash +``` current_date=$(date +%Y-%m-%d) echo "Today is $current_date" ``` +- Output: Today is 2024-09-07 ## 3. User Input Use `read` to get user input: -```bash +``` echo "What's your name?" read user_name echo "Hello, $user_name!" @@ -50,7 +51,7 @@ echo "Hello, $user_name!" If-else statements: -```bash +``` if [ "$age" -ge 18 ]; then echo "You are an adult" else @@ -64,21 +65,21 @@ Note the spaces around the brackets and comparison operator. For loop: -```bash +``` for i in {1..5} do - echo "Iteration $i" +echo "Iteration $i" done ``` While loop: -```bash +``` counter=1 while [ $counter -le 5 ] do - echo "Counter: $counter" - ((counter++)) +echo "Counter: $counter" +((counter++)) done ``` @@ -86,9 +87,9 @@ done Define and call functions: -```bash +``` greet() { - echo "Hello, $1!" + echo "Hello, $1!" # $1 takes the first argument passed after the function } greet "Alice" @@ -99,7 +100,7 @@ greet "Bob" Access command-line arguments using `$1`, `$2`, etc.: -```bash +``` echo "Script name: $0" echo "First argument: $1" echo "Second argument: $2" @@ -110,19 +111,19 @@ echo "All arguments: $@" Check if a file exists: -```bash +``` if [ -f "myfile.txt" ]; then - echo "myfile.txt exists" +echo "myfile.txt exists" else - echo "myfile.txt does not exist" +echo "myfile.txt does not exist" fi ``` Read from a file: -```bash +``` while IFS= read -r line do - echo "$line" +echo "$line" done < "myfile.txt" ``` diff --git a/07 - Shell Scripting Basics/Conditional Statements.md b/07 - Shell Scripting Basics/Conditional Statements.md index 796ffa4..1d66a01 100644 --- a/07 - Shell Scripting Basics/Conditional Statements.md +++ b/07 - Shell Scripting Basics/Conditional Statements.md @@ -6,21 +6,21 @@ Conditional statements in Bash allow you to control the flow of your script base The most basic conditional statement is the 'if' statement. Its syntax is: -```bash +``` if [ condition ]; then - # commands to execute if condition is true +# commands to execute if condition is true fi ``` Example: -```bash +``` #!/bin/bash age=18 if [ $age -ge 18 ]; then - echo "You are an adult." +echo "You are an adult." fi ``` @@ -28,25 +28,25 @@ fi The if-else statement allows you to specify actions for both when the condition is true and when it's false: -```bash +``` if [ condition ]; then - # commands to execute if condition is true +# commands to execute if condition is true else - # commands to execute if condition is false +# commands to execute if condition is false fi ``` Example: -```bash +``` #!/bin/bash age=16 if [ $age -ge 18 ]; then - echo "You are an adult." +echo "You are an adult." else - echo "You are a minor." +echo "You are a minor." fi ``` @@ -54,35 +54,35 @@ fi For multiple conditions, use the if-elif-else structure: -```bash +``` if [ condition1 ]; then - # commands for condition1 +# commands for condition1 elif [ condition2 ]; then - # commands for condition2 +# commands for condition2 elif [ condition3 ]; then - # commands for condition3 +# commands for condition3 else - # commands if none of the conditions are true +# commands if none of the conditions are true fi ``` Example: -```bash +``` #!/bin/bash grade=75 if [ $grade -ge 90 ]; then - echo "A" +echo "A" elif [ $grade -ge 80 ]; then - echo "B" +echo "B" elif [ $grade -ge 70 ]; then - echo "C" +echo "C" elif [ $grade -ge 60 ]; then - echo "D" +echo "D" else - echo "F" +echo "F" fi ``` @@ -102,13 +102,13 @@ String comparisons: - =: equal to - !=: not equal to - <: less than (in ASCII alphabetical order) -- >: greater than (in ASCII alphabetical order) +- \>: greater than (in ASCII alphabetical order) - -z: string is null (zero length) - -n: string is not null Example: -```bash +``` #!/bin/bash num1=10 @@ -117,11 +117,11 @@ str1="hello" str2="world" if [ $num1 -lt $num2 ]; then - echo "$num1 is less than $num2" +echo "$num1 is less than $num2" fi if [ $str1 != $str2 ]; then - echo "$str1 is not equal to $str2" +echo "$str1 is not equal to $str2" fi ``` @@ -129,23 +129,23 @@ fi Bash supports logical AND and OR operations: -- &&: AND -- ||: OR +- &&: AND # Double ampersand Shift+7 (qwerty) +- ||: OR # Double Pipe | | with no spaces! Example: -```bash +``` #!/bin/bash age=25 has_license=true if [ $age -ge 18 ] && [ "$has_license" = true ]; then - echo "You can drive a car." +echo "You can drive a car." fi if [ $age -lt 18 ] || [ "$has_license" != true ]; then - echo "You cannot drive a car." +echo "You cannot drive a car." fi ``` @@ -153,40 +153,40 @@ fi The case statement is useful when you have multiple conditions based on a single variable: -```bash +``` case $variable in - pattern1) - # commands for pattern1 - ;; - pattern2) - # commands for pattern2 - ;; - *) - # default case - ;; +pattern1) +# commands for pattern1 +;; +pattern2) +# commands for pattern2 +;; +*) # This is the default or catch-all case +# default case +;; esac ``` Example: -```bash +``` #!/bin/bash fruit="apple" case $fruit in - "apple") - echo "This is a red fruit." - ;; - "banana") - echo "This is a yellow fruit." - ;; - "grape") - echo "This is a purple fruit." - ;; - *) - echo "Unknown fruit." - ;; +"apple") +echo "This is a red fruit." +;; +"banana") +echo "This is a yellow fruit." +;; +"grape") + echo "This is a purple fruit." +;; +*) +echo "Unknown fruit." +;; esac ``` @@ -194,15 +194,15 @@ esac The test command is often used in conditional statements. It's equivalent to using square brackets []. You can use it like this: -```bash +``` if test $a -eq $b; then - echo "a is equal to b" +echo "a is equal to b" fi ``` This is the same as: -```bash +``` if [ $a -eq $b ]; then echo "a is equal to b" fi @@ -212,24 +212,20 @@ fi Bash also supports double square brackets [[ ]] for conditional tests. These provide more features than single brackets, such as pattern matching: -```bash +``` #!/bin/bash string="Hello, World!" if [[ $string == Hello* ]]; then - echo "String starts with 'Hello'" +echo "String starts with 'Hello'" fi ``` Double brackets also allow you to use && and || inside the condition: -```bash -if [[ $a -eq 5 && $b -gt 10 ]]; then - echo "Condition met" -fi ``` - -## Conclusion - -Conditional statements are crucial for creating dynamic and responsive Bash scripts. They allow your scripts to make decisions based on various conditions, making your scripts more versatile and powerful. Practice using these constructs to become proficient in Bash scripting. +if [[ $a -eq 5 && $b -gt 10 ]]; then +echo "Condition met" +fi +``` \ No newline at end of file diff --git a/07 - Shell Scripting Basics/Functions in Bash.md b/07 - Shell Scripting Basics/Functions in Bash.md index 3ab0257..f662a08 100644 --- a/07 - Shell Scripting Basics/Functions in Bash.md +++ b/07 - Shell Scripting Basics/Functions in Bash.md @@ -8,19 +8,19 @@ Bash functions are reusable pieces of code that perform a specific task. They he The basic syntax for defining a function in Bash is: -```bash +``` function_name() { - # Function body - # Commands go here +# Function body +# Commands go here } ``` Alternatively, you can use the `function` keyword: -```bash +``` function function_name { - # Function body - # Commands go here +# Function body +# Commands go here } ``` @@ -28,7 +28,7 @@ function function_name { To call a function, simply use its name: -```bash +``` function_name ``` @@ -43,9 +43,9 @@ Bash functions can accept parameters, which are accessed using special variables Example: -```bash +``` greet() { - echo "Hello, $1! Nice to meet you." +echo "Hello, $1! Nice to meet you." } greet "Alice" # Output: Hello, Alice! Nice to meet you. @@ -55,13 +55,13 @@ greet "Alice" # Output: Hello, Alice! Nice to meet you. Bash functions don't return values in the traditional sense. Instead, they use exit status: -```bash +``` is_even() { - if (( $1 % 2 == 0 )); then - return 0 # Success (true) - else - return 1 # Failure (false) - fi +if (( $1 % 2 == 0 )); then +return 0 # Success (true) +else +return 1 # Failure (false) +fi } is_even 4 @@ -75,9 +75,9 @@ echo $? # Output: 1 (failure) To capture a function's output, use command substitution: -```bash +``` get_date() { - echo $(date +"%Y-%m-%d") +echo $(date +"%Y-%m-%d") } today=$(get_date) @@ -88,10 +88,10 @@ echo "Today is $today" Use the `local` keyword to declare variables that are only accessible within the function: -```bash +``` my_function() { - local my_var="Hello, local variable!" - echo $my_var +local my_var="Hello, local variable!" +echo $my_var } my_function # Output: Hello, local variable! @@ -102,13 +102,13 @@ echo $my_var # Output: (empty, as my_var is not accessible here) Functions in Bash have access to global variables, but it's generally better to pass values as parameters: -```bash +``` global_var="I'm global" my_function() { - echo "Inside function: $global_var" - local local_var="I'm local" - echo "Local variable: $local_var" +echo "Inside function: $global_var" +local local_var="I'm local" +echo "Local variable: $local_var" } my_function @@ -120,14 +120,14 @@ echo "Trying to access local_var: $local_var" # This will be empty You can create function libraries by putting related functions in a separate file and sourcing it: -```bash +``` # In file: my_functions.sh greet() { - echo "Hello, $1!" +echo "Hello, $1!" } farewell() { - echo "Goodbye, $1!" +echo "Goodbye, $1!" } # In your main script @@ -140,10 +140,10 @@ farewell "Bob" ## 10. Advanced Techniques a. Default Parameters: -```bash +``` greet() { - local name=${1:-"Guest"} - echo "Hello, $name!" +local name=${1:-"Guest"} +echo "Hello, $name!" } greet # Output: Hello, Guest! @@ -151,27 +151,27 @@ greet "Alice" # Output: Hello, Alice! ``` b. Variable Number of Arguments: -```bash +``` sum() { - local result=0 - for num in "$@"; do - ((result += num)) - done - echo $result +local result=0 +for num in "$@"; do +((result += num)) +done +echo $result } sum 1 2 3 4 5 # Output: 15 ``` c. Recursive Functions: -```bash +``` factorial() { - if (( $1 <= 1 )); then - echo 1 - else - local prev=$(factorial $(($1 - 1))) - echo $(($1 * prev)) - fi +if (( $1 <= 1 )); then +echo 1 +else +local prev=$(factorial $(($1 - 1))) +echo $(($1 * prev)) +fi } factorial 5 # Output: 120 @@ -190,17 +190,13 @@ factorial 5 # Output: 120 Use the `set -x` command to enable debugging mode, which prints each command before executing it: -```bash +``` set -x # Enable debugging my_function() { - echo "Doing something" - local result=$((2 + 2)) - echo "Result: $result" +echo "Doing something" +local result=$((2 + 2)) +echo "Result: $result" } my_function set +x # Disable debugging -``` - -## Conclusion - -Bash functions are powerful tools for creating modular, reusable code. They can significantly improve the organization and maintainability of your shell scripts. By mastering functions, you'll be able to write more efficient and elegant Bash scripts. +``` \ No newline at end of file diff --git a/07 - Shell Scripting Basics/Script Debugging Techniques.md b/07 - Shell Scripting Basics/Script Debugging Techniques.md index 732846e..42fb4c7 100644 --- a/07 - Shell Scripting Basics/Script Debugging Techniques.md +++ b/07 - Shell Scripting Basics/Script Debugging Techniques.md @@ -6,13 +6,13 @@ The first step in debugging a bash script is to enable debugging mode. You can d - Add the -x option when running the script: -```bash +``` bash -x your_script.sh ``` - Add the set -x command at the beginning of your script: -```bash +``` #!/bin/bash set -x @@ -25,13 +25,13 @@ The -x option enables trace debugging, which prints each command and its argumen Bash provides several set options that can help with debugging: -- set -e: Exit immediately if a command exits with a non-zero status. -- set -u: Treat unset variables as an error when substituting. -- set -o pipefail: The return value of a pipeline is the status of the last command to exit with a non-zero status. +- `set -e`: Exit immediately if a command exits with a non-zero status. +- `set -u`: Treat unset variables as an error when substituting. +- `set -o` pipefail: The return value of a pipeline is the status of the last command to exit with a non-zero status. You can combine these options: -```bash +``` #!/bin/bash set -euo pipefail set -x @@ -43,7 +43,7 @@ set -x Insert echo statements throughout your script to print variable values or to indicate which part of the script is being executed: -```bash +``` echo "Debug: Variable value is $variable" echo "Debug: Entering function foo" ``` @@ -52,12 +52,12 @@ echo "Debug: Entering function foo" Bash provides several built-in commands for debugging: -- set -v: Prints shell input lines as they are read. +- `set -v`: Prints shell input lines as they are read. - trap: Can be used to debug functions or specific parts of your script. Example of using trap: -```bash +``` trap 'echo "Line $LINENO: Command \\"$BASH_COMMAND\\" exited with status $?"' ERR ``` @@ -67,15 +67,11 @@ For more complex scripts, you might want to use a debugger. Bashdb is a popular a) Install bashdb (on Ubuntu/Debian): -``` -sudo apt-get install bashdb -``` +`sudo apt-get install bashdb` b) Run your script with bashdb: -``` -bashdb your_script.sh -``` +`bashdb your_script.sh` This will start an interactive debugging session where you can set breakpoints, step through the code, and inspect variables. @@ -83,9 +79,7 @@ This will start an interactive debugging session where you can set breakpoints, Before diving into debugging, check for syntax errors: -```bash -bash -n your_script.sh -``` +`bash -n your_script.sh` This will check for syntax errors without executing the script. @@ -95,21 +89,17 @@ Shellcheck is a static analysis tool for shell scripts. It can catch common erro a) Install shellcheck (on Ubuntu/Debian): -``` -sudo apt-get install shellcheck -``` +`sudo apt-get install shellcheck` b) Run shellcheck on your script: -``` -shellcheck your_script.sh -``` +`shellcheck your_script.sh` ## 8. Debug specific sections If you only want to debug a specific section of your script, you can use set -x and set +x to turn debugging on and off: -```bash +``` #!/bin/bash # Normal execution @@ -128,7 +118,7 @@ echo "Back to normal execution" You can customize the prefix used for debug output using the PS4 variable: -```bash +``` export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' set -x @@ -141,11 +131,11 @@ This will prefix each debug line with the source file, line number, and function After each important command, check its exit status: -```bash +``` important_command if [ $? -ne 0 ]; then - echo "Error: important_command failed" - exit 1 +echo "Error: important_command failed" +exit 1 fi ``` @@ -153,9 +143,7 @@ fi You can use the DEBUG trap to execute a command before each command in your script: -```bash -trap 'echo "About to execute: $BASH_COMMAND"' DEBUG -``` +`trap 'echo "About to execute: $BASH_COMMAND"' DEBUG` This will print each command before it's executed. diff --git a/07 - Shell Scripting Basics/User Iput and Arguments in Bash.md b/07 - Shell Scripting Basics/User Iput and Arguments in Bash.md index 9704379..6c87725 100644 --- a/07 - Shell Scripting Basics/User Iput and Arguments in Bash.md +++ b/07 - Shell Scripting Basics/User Iput and Arguments in Bash.md @@ -6,7 +6,7 @@ Bash scripts can accept arguments when executed from the command line. These arg Example: -```bash +``` #!/bin/bash echo "The script name is: $0" @@ -16,22 +16,20 @@ echo "All arguments: $@" ``` Usage: -``` -./script.sh arg1 arg2 arg3 -``` +`./script.sh arg1 arg2 arg3` ## 2. The `read` Command The `read` command allows interactive user input during script execution. Basic syntax: -```bash +``` read variable_name ``` Example: -```bash +``` #!/bin/bash echo "What's your name?" @@ -64,7 +62,7 @@ Bash provides special variables for working with command-line arguments: Example: -```bash +``` #!/bin/bash echo "Number of arguments: $#" @@ -83,44 +81,42 @@ You can create scripts that accept options (flags) to modify behavior. Example: -```bash +``` #!/bin/bash verbose=false while [[ $# -gt 0 ]] do - key="$1" - case $key in - -v|--verbose) - verbose=true - shift - ;; - -n|--name) - name="$2" - shift - shift - ;; - *) - echo "Unknown option: $1" - exit 1 - ;; - esac +key="$1" +case $key in +-v|--verbose) +verbose=true +shift +;; +-n|--name) +name="$2" +shift +shift +;; +*) +echo "Unknown option: $1" +exit 1 +;; +esac done if [ "$verbose" = true ] ; then - echo "Verbose mode on" +echo "Verbose mode on" fi if [ ! -z "$name" ] ; then - echo "Hello, $name!" +echo "Hello, $name!" fi ``` Usage: -``` -./script.sh -v --name John -``` +`./script.sh -v --name John` ## 5. Validating Input @@ -128,19 +124,19 @@ It's important to validate user input to ensure your script behaves correctly. Example: -```bash +``` #!/bin/bash read -p "Enter a number between 1 and 10: " number if [[ ! $number =~ ^[0-9]+$ ]] ; then - echo "Error: Not a number" - exit 1 +echo "Error: Not a number" +exit 1 fi if (( number < 1 || number > 10 )) ; then - echo "Error: Number out of range" - exit 1 +echo "Error: Number out of range" +exit 1 fi echo "You entered a valid number: $number" @@ -152,54 +148,52 @@ For more complex option parsing, Bash provides the `getopts` built-in command. Example: -```bash +``` #!/bin/bash usage() { - echo "Usage: $0 [-h] [-v] [-n name]" - echo " -h: Display this help message" - echo " -v: Enable verbose mode" - echo " -n name: Specify a name" +echo "Usage: $0 [-h] [-v] [-n name]" +echo " -h: Display this help message" +echo " -v: Enable verbose mode" +echo " -n name: Specify a name" } verbose=false name="" while getopts ":hvn:" opt; do - case ${opt} in - h ) - usage - exit 0 - ;; - v ) - verbose=true - ;; - n ) - name=$OPTARG - ;; - \? ) - echo "Invalid option: $OPTARG" 1>&2 - usage - exit 1 - ;; - : ) - echo "Invalid option: $OPTARG requires an argument" 1>&2 - usage - exit 1 - ;; - esac +case ${opt} in +h ) +usage +exit 0 +;; +v ) +verbose=true +;; +n ) +name=$OPTARG +;; +\? ) +echo "Invalid option: $OPTARG" 1>&2 +usage +exit 1 +;; +: ) +echo "Invalid option: $OPTARG requires an argument" 1>&2 +usage +exit 1 +;; +esac done if [ "$verbose" = true ] ; then - echo "Verbose mode enabled" +echo "Verbose mode enabled" fi if [ ! -z "$name" ] ; then - echo "Hello, $name!" +echo "Hello, $name!" fi ``` Usage: -``` -./script.sh -v -n Alice -``` +`./script.sh -v -n Alice`