diff --git a/README.md b/README.md index c0835e1..df27106 100644 --- a/README.md +++ b/README.md @@ -89,9 +89,9 @@ This function *should* print some message which can help the user accomplish his ##### validate This function is called after every command entered. -The last command the user has entered is passed in arguments. +The last command the user has entered is passed in the arguments. You may inspect each bit with `$` or the whole command as one with `$*`. -Since task files are sourced, all variables the user's shell has is available to you. +Since task files are sourced, all variables of the user's shell are available to you. You may use this fact to perform arbitrary checks, for example inspect files in `$PWD`. To make a task considered complete and to initiate moving on to the next one, `return 1`. diff --git a/bash_module/task_list.sh b/bash_module/task_list.sh index c45fb24..cdcece6 100644 --- a/bash_module/task_list.sh +++ b/bash_module/task_list.sh @@ -1,4 +1,3 @@ -# XXX 'program' might not be the best word, but neither is 'command' BASHTUTOR_TASK_FILE_LIST+=(tasks/greeting.sh) BASHTUTOR_TASK_FILE_LIST+=(tasks/command.sh) BASHTUTOR_TASK_FILE_LIST+=(tasks/arguments_1.sh) # echo is learned diff --git a/bash_module/tasks/complex_expension_monk_task.sh b/bash_module/tasks/complex_expension_monk_task.sh index 2ffffc3..944da12 100644 --- a/bash_module/tasks/complex_expension_monk_task.sh +++ b/bash_module/tasks/complex_expension_monk_task.sh @@ -1,19 +1,19 @@ function description() { - if [ -n "$SECRET_MESSAGE" ]; then + if ! [ -v "SECRET_MESSAGE" ]; then SECRET_KEY_ENCODED=$(echo "Terry is King" | base64) - SECRET_MESSAGE=$(echo "\ + SECRET_MESSAGE="\ /o\\ The key is partial, append ${SECRET_KEY_ENCODED:(-4)} to it! \ $(echo "Line 1 Col 0, the dev was an antihero" | base64) \ -/o\\ Erase from the key as many runes as 2 raised to the number of monks is! \ +/o\\ Erase from the key as many runes as 2 times the number of monks there are! \ $(echo "Copyleft your DNA for free beer" | base64) \ /o\\ Every . is a &! \ $(echo "Emacs > Vim. Simple as." | base64) \ /o\\ The key lays to the right! \ $(echo "Linux is a cancer that attaches itself..." | base64) \ /0\\ The key lays to the left! \ -uWpvUaq2mciBetKEK${SECRET_KEY_ENCODED::(-4)} +uWpvUaqKEK${SECRET_KEY_ENCODED::(-4)} /o\\ Not everyone is a monk here!\ -") +" SECRET_MESSAGE=${SECRET_MESSAGE//2/\.} SECRET_MESSAGE=${SECRET_MESSAGE//&/2} SECRET_MESSAGE=$(echo "$SECRET_MESSAGE" | base64) @@ -51,12 +51,13 @@ uWpvUaq2mciBetKEK${SECRET_KEY_ENCODED::(-4)} echo -e " ${YELLOW}\${parameter/%pattern/string}${NORMAL}" echo -e " As above, but matched against the end. Useful for adding a common suffix with a null pattern. " echo "" - echo "Hold it close, because you will need it for the hooded GNU monks" \ - "to let you past. Their message for you have been stored in \$SECRET_MESSAGE." + echo -e "You don't have to understand everything above, but hold this table close,"\ + "because you will need it for the ${BOLD}hooded GNU monks${NORMAL}" \ + "to let you past. Their message for you have been stored in \$SECRET_MESSAGE." echo "They also told me to teach you this 'sorcery' (as they refered to it):" echo -e " ${YELLOW}$ base64 (--decode)${NORMAL}" echo -e "You can use this to communicate in their anchient language called base-64." \ - "By adding '${YELLOW}--decode${NORMAL}' as an argument you will be understand them." \ + "By adding '${YELLOW}--decode${NORMAL}' as an argument you will be able to understand them." \ "It's important to know that you can't give a string as an argument to base64," \ "you will have to pipe in the string." echo "" @@ -76,7 +77,7 @@ function hint() { echo "6) Append according to the first monk." echo "7) Decode the key and store it." echo "Bonus) You can check the rest of the messages." \ - "On them you will not need to perform step 5 and 6." + "On those you will not need to perform step 5 and 6." } function validate() { diff --git a/bash_module/tasks/conditional_execution.sh b/bash_module/tasks/conditional_execution.sh index f4d263a..80a6e53 100644 --- a/bash_module/tasks/conditional_execution.sh +++ b/bash_module/tasks/conditional_execution.sh @@ -2,7 +2,7 @@ function description() { echo -e "Now that we know what exit codes are," \ "and that an exit code of '${CYAN}0${NORMAL}'" \ "means the command's execution was ${BOLD}successful${NORMAL}," \ - "we'll learn to use this information." \ + "we'll learn how to use this information." \ "The easiest way of performing a certain action depending" \ "on the success of a previous command is through the use of control operators." \ "These operators are ${YELLOW}&&${NORMAL} and ${YELLOW}||${NORMAL}," \ @@ -27,11 +27,11 @@ function description() { "tho she is quite old and she is digital" \ "so you may make as many (copies) as you wish:" echo -e " ${YELLOW}$ cat ${NORMAL}" - echo "She can be used to conveniently print file contents to you console or" \ - "as primarily intended con${BOLD}CAT${NORMAL}enate multiple files." \ - "You should also know that she has a long history of being abused by pointed" \ - "usage in scripts. You will see about that in time..." - echo "" + echo -e "She can be used to conveniently print file contents to you console or" \ + "as primarily intended con${BOLD}CAT${NORMAL}enate multiple files." \ + "You should also know that she has a long history of being abused by pointless" \ + "usage in scripts. You will see about that in time..." + echo "" echo -e "${BLUE}# Ensure that the following condition becomes true:${NORMAL}" INTERNAL_CONDITION='touch "${MYFILE}" && cat "new file" || false && ! [ "" == "$a" ]' echo -e " ${YELLOW}${INTERNAL_CONDITION}${NORMAL}" diff --git a/bash_module/tasks/control.sh b/bash_module/tasks/control.sh index 830136d..2bcd15f 100644 --- a/bash_module/tasks/control.sh +++ b/bash_module/tasks/control.sh @@ -13,10 +13,10 @@ function description() { "Sometimes we need to repeat things. For that," \ "we need to use a ${ITALICS}loop${NORMAL}." echo "" - echo "Bash has a stunning number of loop variations:" + echo "Bash has a stunning number of loop variants:" echo -e " ${GREEN}+${NORMAL} while : Repeat based on a condition." echo -e " ${GREEN}+${NORMAL} until : Repeat based on the negate of condition." - echo -e " ${GREEN}+${NORMAL} for-in : Repeat the loop for each word. Think 'for-each'." + echo -e " ${GREEN}+${NORMAL} for in : Repeat the loop for each word. Think 'for-each'." echo -e " ${GREEN}+${NORMAL} for (()) : Repeat with counter. C style loop." echo -e " ${GREEN}+${NORMAL} select : Interactive switch-like loop." echo "" @@ -34,7 +34,7 @@ function description() { "taking up the value of each word." echo "" echo "You are one command away from being able to pull of a trick which I'm sure" \ - "will come handy in the future time to time." + "will come handy in the future from time to time." echo -e "${YELLOW} $ mv ${NORMAL}" echo -e "With mv you can '${BOLD}M${NORMAL}o${BOLD}V${NORMAL}e' files." \ "You only have to specify the current name and the new one." diff --git a/bash_module/tasks/exit_statuses.sh b/bash_module/tasks/exit_statuses.sh index 7c31130..51a19e4 100644 --- a/bash_module/tasks/exit_statuses.sh +++ b/bash_module/tasks/exit_statuses.sh @@ -2,7 +2,7 @@ function description() { echo -e "Every command results in an exit code whenever it terminates." \ "This exit code is used by whatever application started it" \ "to evaluate whether everything went OK." \ - "This exit code is like a return value from functions." \ + "Conceptually this is like a return value from a function." \ "It's an integer between 0 and 255 (inclusive)." \ "Convention dictates that we use 0 to denote success," \ "and any other number to denote failure of some sort." \ @@ -10,7 +10,7 @@ function description() { "and is used to hint as to what exactly went wrong." echo "" echo "For example the test program you have seen before ('[ 0 == 0 ]')" \ - "utalizes exit statuses." + "utilizes exit statuses." echo "" echo -e "${BLUE}# Find a way to execute a command with a non-zero exit value.${NORMAL}" } diff --git a/bash_module/tasks/functions.sh b/bash_module/tasks/functions.sh index e803356..2b1ecfc 100644 --- a/bash_module/tasks/functions.sh +++ b/bash_module/tasks/functions.sh @@ -25,10 +25,10 @@ function description() { "and potentially a more economic replacement for a five year-old." echo "" echo -e "Inside functions you get access to a special program: '${YELLOW}return${NORMAL}'." \ - "It can be used to make specify the functions exit value by passing" \ - "it as an argument." \ + "It can be used to specify the function's exit value by passing" \ + "it a numeric argument." \ "If you do not use return, the function's exit value will be the same as the" \ - "last executed commands exit value." + "last executed command's exit value." echo "" echo -e "${BLUE}# Find a way to execute a command with an exit value of 231.${NORMAL}" } diff --git a/bash_module/tasks/glob.sh b/bash_module/tasks/glob.sh index 74a4ff7..8245300 100644 --- a/bash_module/tasks/glob.sh +++ b/bash_module/tasks/glob.sh @@ -9,23 +9,23 @@ function description() { echo "Globs are a type of pattern matching." \ "They can be used to match filenames or other strings." echo "" - echo "Globs are composed of normal characters and metacharacters." \ - "Metacharacters are characters that have a special meaning." \ - "These are the metacharacters that can be used in globs:" - echo " *: Matches any string, including the null string." - echo " ?: Matches any single character." - echo " [...]: Matches any one of the enclosed characters." - echo "" + echo -e "Globs are composed of normal characters and metacharacters." \ + "Metacharacters are characters that have a special meaning." \ + "These are the metacharacters available to us in Bash globs:${YELLOW}" + echo " * : Matches any string, including the null string." + echo " ? : Matches any single character." + echo " [...] : Matches any one of the enclosed characters." + echo -e "${NORMAL}" echo "Globs are implicitly anchored at both ends." \ "What this means is that a glob must match a whole string" \ "(filename or data string)." \ - "A glob of a* will not match the string cat," \ - "because it only matches the at, not the whole string." \ - "A glob of ca*, however, would match cat." + "A glob of a* will not match the string 'cat'," \ + "because it only matches the 'at', not the whole string." \ + "A glob of ca*, however, would match 'cat'." echo "" echo -e "${BLUE}# A bunch of files have been created in your directory." \ - "Glob your way out of this hole by producing the printing the exact text" \ - "as below!${NORMAL}" + "Glob your way out of this hole by printing the exact text" \ + "as below using globs!${NORMAL}" echo -e "${GREEN}a aa aaa aaaa bc bűb aaaa bbbb cccc${NORMAL}" } diff --git a/bash_module/tasks/help.sh b/bash_module/tasks/help.sh index c8c518c..fc3afec 100644 --- a/bash_module/tasks/help.sh +++ b/bash_module/tasks/help.sh @@ -1,15 +1,17 @@ function description() { + echo "And now for something completely different!" + echo "" echo -e "To master tools and concepts you will often have to consult documentation." \ "Depending on the subject we have different ways to access documentation" \ - "from the command line. The most common are:${YELLOW}" - echo " $ man ${blue}# for Unix conforming tools${NORMAL}" - echo " $ info ${blue}# for GNU conforming tools${NORMAL}" - echo " $ help ${blue}# for Bash builtins${NORMAL}" - echo " $ <--help> ${blue}# Every same executable${NORMAL}" - echo " $ <-h> ${blue}# Every only slightly unhinged executable${NORMAL}" - echo -e "${NORMAL}" + "from the command line. The most common are:" + echo -e "${YELLOW} $ man ${blue}# for Unix conforming tools${NORMAL}" + echo -e "${YELLOW} $ info ${blue}# for GNU conforming tools${NORMAL}" + echo -e "${YELLOW} $ help ${blue}# for Bash builtins${NORMAL}" + echo -e "${YELLOW} $ <--help> ${blue}# Every same executable${NORMAL}" + echo -e "${YELLOW} $ <-h> ${blue}# Every only slightly unhinged executable${NORMAL}" + echo "" echo "The reason why we have both man and info is GNU wanting to innovate," \ - "but kernel developers other many others wanting to stick with man." \ + "but kernel developers and many others wanting to stick with man." \ "Sometimes the best you can do is to check for both." echo "" echo -e "${BLUE}# Continue by briefly opening the bash man page!${NORMAL}" diff --git a/bash_module/tasks/logic.sh b/bash_module/tasks/logic.sh index d9890b1..df33306 100644 --- a/bash_module/tasks/logic.sh +++ b/bash_module/tasks/logic.sh @@ -1,8 +1,8 @@ function description() { echo "Conditional execution is useful, but it can get real ugly real fast." - echo -e "If is a shell keyword that executes a command (or a set of commands)," \ + echo -e "'if' is a shell keyword that executes a command (or a set of commands)," \ "and checks that command's exit code to see whether it was successful." \ - "Depending on that exit code, if executes a specific, different," \ + "Depending on that exit code, 'if' executes a specific, different," \ "block of commands.${YELLOW}" echo " $ if true" echo " > then echo \"It was true.\"" diff --git a/bash_module/tasks/redirections.sh b/bash_module/tasks/redirections.sh index a597f4c..a7531a3 100644 --- a/bash_module/tasks/redirections.sh +++ b/bash_module/tasks/redirections.sh @@ -39,7 +39,7 @@ and much appreciation." echo "GUI applications also have these FDs," \ "but they don't normally work with them." echo -e "${YELLOW}" - echo " \$ read -p \"What is your name? \" name; echo \"Good day, $name. Would you like some tea?\"" + echo " \$ read -p \"What is your name? \" name; echo \"Good day, $$name. Would you like some tea?\"" echo " What is your name? lhunath" echo " Good day, lhunath. Would you like some tea?" echo -e "${NORMAL}" @@ -58,27 +58,27 @@ and much appreciation." "${ITALICS}stderr${NORMAL} makes it easy to" \ "keep errors separated from the application's normal messages." echo "" - echo "File Redirection involves changing a single FD to point to a file." \ - "It only to ${BOLD}one command${NORMAL}." \ - "The pattern of how it works is actually harder to describe than to" \ - "recognize, so here is an example:" + echo -e "File Redirection involves manipulating a single FD, to make it point to a file." \ + "It only applies to ${BOLD}one command${NORMAL}." \ + "The pattern of how it works is actually harder to describe than to" \ + "recognize, so here is an example:" echo -e " ${YELLOW}$ echo 'The End. Never forget.' > b-ook.txt${NORMAL}" - echo -e "And here is a list:${YELLOW}" - echo " > # stdout to file with overwriting" - echo " >> # stdout to file with appending" - echo " 1> # stdout to file with overwriting" - echo " 1>> # stdout to file with appending" - echo " 2> # stderr to file with overwriting" - echo " 2>> # stderr to file with appending" - echo " &> # stdout and stderr to file with overwriting" - echo " &>> # stdout and stderr to file with appending" - echo " 1>&2 # stdout to stderr" - echo " 2>&1 # stderr to stdout" - echo " < # file to stdin" + echo -e "And here is a list:" + echo -e "${YELLOW} > ${BLUE}# stdout to file with overwriting" + echo -e "${YELLOW} >> ${BLUE}# stdout to file with appending" + echo -e "${YELLOW} 1> ${BLUE}# stdout to file with overwriting" + echo -e "${YELLOW} 1>> ${BLUE}# stdout to file with appending" + echo -e "${YELLOW} 2> ${BLUE}# stderr to file with overwriting" + echo -e "${YELLOW} 2>> ${BLUE}# stderr to file with appending" + echo -e "${YELLOW} &> ${BLUE}# stdout and stderr to file with overwriting" + echo -e "${YELLOW} &>> ${BLUE}# stdout and stderr to file with appending" + echo -e "${YELLOW} 1>&2 ${BLUE}# stdout to stderr" + echo -e "${YELLOW} 2>&1 ${BLUE}# stderr to stdout" + echo -e "${YELLOW} < ${BLUE}# file to stdin" echo -e "${NORMAL}" echo "" echo -e "${CYAN}Note:${NORMAL} there exists a special virtual file" \ - "'${YELLOW}/dev/null'." \ + "'${YELLOW}/dev/null${NORMAL}'." \ "You can write whatever to it and it will just discard it." \ "It is often used to silence command output, errors or both" \ "with a redirection to it." diff --git a/bash_module/tasks/sourcing.sh b/bash_module/tasks/sourcing.sh index ed39ab1..0a8a0f9 100644 --- a/bash_module/tasks/sourcing.sh +++ b/bash_module/tasks/sourcing.sh @@ -14,9 +14,9 @@ function description() { "your current working directory for you." echo "" echo -e "What you can do is to source the script," \ - "instead of running it as a child." + "instead of running it as a child." \ "You can do this using the '${YELLOW}source${NORMAL}'" \ - "(or '${YELLOW}.${NORMAL}') command: " + "(or '${YELLOW}.${NORMAL}') command: " \ echo -e " ${YELLOW}\$ source ./myscript${NORMAL}" echo "" echo -e "${BLUE}# I'm sorry, but there is not much fun to be had with sourcing." \