You've already forked devops-exercises
Rename exercises dir
Name it instead "topics" so it won't be strange if some topics included "exercises" directory.
This commit is contained in:
@@ -1,264 +0,0 @@
|
||||
## Shell Scripting
|
||||
|
||||
### Shell Scripting Exercises
|
||||
|
||||
|Name|Topic|Objective & Instructions|Solution|Comments|
|
||||
|--------|--------|------|----|----|
|
||||
|Hello World|Variables|[Exercise](hello_world.md)|[Solution](solutions/hello_world.md) | Basic
|
||||
|Basic date|Variables|[Exercise](basic_date.md)|[Solution](solutions/basic_date.md) | Basic
|
||||
|Great Day|Variables|[Exercise](great_day.md)|[Solution](solutions/great_day.md) | Basic
|
||||
|Factors|Arithmetic|[Exercise](factors.md)|[Solution](solutions/factors.md) | Basic
|
||||
|Argument Check|Conditionals|[Exercise](argument_check.md)|[Solution](solutions/argument_check.md) | Basic
|
||||
|Files Size|For Loops|[Exercise](files_size.md)|[Solution](solutions/files_size.md) | Basic
|
||||
|Count Chars|Input + While Loops|[Exercise](count_chars.md)|[Solution](solutions/count_chars.md) | Basic
|
||||
|Sum|Functions|[Exercise](sum.md)|[Solution](solutions/sum.md) | Basic
|
||||
|Number of Arguments|Case Statement|[Exercise](num_of_args.md)|[Solution](solutions/num_of_args.md) | Basic
|
||||
|Empty Files|Misc|[Exercise](empty_files.md)|[Solution](solutions/empty_files.md) | Basic
|
||||
|Directories Comparison|Misc|[Exercise](directories_comparison.md)| :( | Basic
|
||||
|It's alive!|Misc|[Exercise](host_status.md)|[Solution](solutions/host_status.md) | Intermediate
|
||||
|
||||
## Shell Scripting - Self Assessment
|
||||
|
||||
<details>
|
||||
<summary>What does this line in shell scripts means?: <code>#!/bin/bash</code></summary><br><b>
|
||||
|
||||
|
||||
`#!/bin/bash` is She-bang
|
||||
|
||||
/bin/bash is the most common shell used as default shell for user login of the linux system. The shell’s name is an acronym for Bourne-again shell. Bash can execute the vast majority of scripts and thus is widely used because it has more features, is well developed and better syntax.
|
||||
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>True or False? When a certain command/line fails in a shell script, the shell script, by default, will exit and stop running</summary><br><b>
|
||||
|
||||
Depends on the language and settings used.
|
||||
If the script is a bash script then this statement is true. When a script written in Bash fails to run a certain command it will keep running and will execute all other commands mentioned after the command which failed.
|
||||
|
||||
Most of the time we might actually want the opposite to happen. In order to make Bash exist when a specific command fails, use 'set -e' in your script.
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>What do you tend to include in every script you write?</summary><br><b>
|
||||
|
||||
Few example:
|
||||
|
||||
* Comments on how to run it and/or what it does
|
||||
* If a shell script, adding "set -e" since I want the script to exit if a certain command failed
|
||||
|
||||
You can have an entirely different answer. It's based only on your experience and preferences.
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Today we have tools and technologies like Ansible, Puppet, Chef, ... Why would someone still use shell scripting?</summary><br><b>
|
||||
|
||||
* Speed
|
||||
* Flexibility
|
||||
* The module we need doesn't exist (perhaps a weak point because most CM technologies allow to use what is known as "shell" module)
|
||||
* We are delivering the scripts to customers who don't have access to the public network and don't necessarily have Ansible installed on their systems.
|
||||
</b></details>
|
||||
|
||||
#### Shell Scripting - Variables
|
||||
|
||||
<details>
|
||||
<summary>How to define a variable with the value "Hello World"?</summary><br><b>
|
||||
|
||||
`HW="Hello World`
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How to define a variable with the value of the current date?</summary><br><b>
|
||||
|
||||
`DATE=$(date)`
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How to print the first argument passed to a script?</summary><br><b>
|
||||
|
||||
`echo $1`
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Write a script to print "yay" unless an argument was passed and then print that argument</summary><br><b>
|
||||
|
||||
```
|
||||
echo "${1:-yay}"
|
||||
```
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>What would be the output of the following script?
|
||||
|
||||
```
|
||||
#!/usr/bin/env bash
|
||||
NINJA_TURTLE=Donatello
|
||||
function the_best_ninja_turtle {
|
||||
local NINJA_TURTLE=Michelangelo
|
||||
echo $NINJA_TURTLE
|
||||
}
|
||||
NINJA_TURTLE=Raphael
|
||||
the_best_ninja_turtle
|
||||
```
|
||||
</summary><br><b>
|
||||
Michelangelo
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Explain what would be the result of each command:
|
||||
|
||||
* <code>echo $0</code>
|
||||
* <code>echo $?</code>
|
||||
* <code>echo $$</code>
|
||||
* <code>echo $#</code></summary><br><b>
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>What is <code>$@</code>?</summary><br><b>
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>What is difference between <code>$@</code> and <code>$*</code>?</summary><br><b>
|
||||
|
||||
`$@` is an array of all the arguments passed to the script
|
||||
`$*` is a single string of all the arguments passed to the script
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How do you get input from the user in shell scripts?</summary><br><b>
|
||||
|
||||
Using the keyword <code>read</code> so for example <code>read x</code> will wait for user input and will store it in the variable x.
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How to compare variables length?</summary><br><b>
|
||||
|
||||
```
|
||||
if [ ${#1} -ne ${#2} ]; then
|
||||
...
|
||||
```
|
||||
</b></details>
|
||||
|
||||
#### Shell Scripting - Conditionals
|
||||
|
||||
<details>
|
||||
<summary>Explain conditionals and demonstrate how to use them</summary><br><b>
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>In shell scripting, how to negate a conditional?</summary><br><b>
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>In shell scripting, how to check if a given argument is a number?</summary><br><b>
|
||||
|
||||
```
|
||||
regex='^[0-9]+$'
|
||||
if [[ ${var//*.} =~ $regex ]]; then
|
||||
...
|
||||
```
|
||||
</b></details>
|
||||
|
||||
#### Shell Scripting - Arithmetic Operations
|
||||
|
||||
<details>
|
||||
<summary>How to perform arithmetic operations on numbers?</summary><br><b>
|
||||
|
||||
One way: `$(( 1 + 2 ))`
|
||||
Another way: `expr 1 + 2`
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How to perform arithmetic operations on numbers?</summary><br><b>
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How to check if a given number has 4 as a factor?</summary><br><b>
|
||||
|
||||
`if [ $(($1 % 4)) -eq 0 ]; then`
|
||||
</b></details>
|
||||
|
||||
#### Shell Scripting - Loops
|
||||
|
||||
<details>
|
||||
<summary>What is a loop? What types of loops are you familiar with?</summary><br><b>
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Demonstrate how to use loops</summary><br><b>
|
||||
</b></details>
|
||||
|
||||
#### Shell Scripting - Troubleshooting
|
||||
|
||||
<details>
|
||||
<summary>How do you debug shell scripts?</summary><br><b>
|
||||
|
||||
Answer depends on the language you are using for writing your scripts. If Bash is used for example then:
|
||||
|
||||
* Adding -x to the script I'm running in Bash
|
||||
* Old good way of adding echo statements
|
||||
|
||||
If Python, then using pdb is very useful.
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Running the following bash script, we don't get 2 as a result, why?
|
||||
|
||||
```
|
||||
x = 2
|
||||
echo $x
|
||||
```
|
||||
</summary><br><b>
|
||||
|
||||
Should be `x=2`
|
||||
</b></details>
|
||||
|
||||
#### Shell Scripting - Substring
|
||||
|
||||
<details>
|
||||
<summary>How to extract everything after the last dot in a string?</summary><br><b>
|
||||
|
||||
`${var//*.}`
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>How to extract everything before the last dot in a string?</summary><br><b>
|
||||
|
||||
${var%.*}
|
||||
</b></details>
|
||||
|
||||
#### Shell Scripting - Misc
|
||||
|
||||
<details>
|
||||
<summary>Generate 8 digit random number</summary><br><b>
|
||||
|
||||
shuf -i 9999999-99999999 -n 1
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>Can you give an example to some Bash best practices?</summary><br><b>
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>What is the ternary operator? How do you use it in bash?</summary><br><b>
|
||||
|
||||
A short way of using if/else. An example:
|
||||
|
||||
[[ $a = 1 ]] && b="yes, equal" || b="nope"
|
||||
</b></details>
|
||||
|
||||
<details>
|
||||
<summary>What does the following code do and when would you use it?
|
||||
|
||||
<code>diff <(ls /tmp) <(ls /var/tmp)</code>
|
||||
|
||||
</summary><br>
|
||||
It is called 'process substitution'. It provides a way to pass the output of a command to another command when using a pipe <code>|</code> is not possible. It can be used when a command does not support <code>STDIN</code> or you need the output of multiple commands.
|
||||
https://superuser.com/a/1060002/167769
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>What are you using for testing shell scripts?</summary><br><b>
|
||||
|
||||
bats
|
||||
</b></details>
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
## Argument Check
|
||||
|
||||
### Objectives
|
||||
|
||||
Note: assume the script is executed with an argument
|
||||
|
||||
1. Write a script that will check if a given argument is the string "pizza"
|
||||
1. If it's the string "pizza" print "with pineapple?"
|
||||
2. If it's not the string "pizza" print "I want pizza!"
|
||||
|
||||
### Solution
|
||||
|
||||
```
|
||||
/usr/bin/env bash
|
||||
|
||||
arg_value=${1:-default}
|
||||
|
||||
if [ $arg_value = "pizza" ]; then
|
||||
echo "with pineapple?"
|
||||
else
|
||||
echo "I want pizza!"
|
||||
fi
|
||||
```
|
||||
@@ -1,5 +0,0 @@
|
||||
## Basic Date
|
||||
|
||||
### Objectives
|
||||
|
||||
1. Write a script that will put the current date in a file called "the_date.txt"
|
||||
@@ -1,11 +0,0 @@
|
||||
## Count Chars
|
||||
|
||||
### Objectives
|
||||
|
||||
1. Read input from the user until you get empty string
|
||||
2. For each of the lines you read, count the number of characters and print it
|
||||
|
||||
### Constraints
|
||||
|
||||
1. You must use a while loop
|
||||
2. Assume at least three lines of input
|
||||
@@ -1,5 +0,0 @@
|
||||
## Directories Comparison
|
||||
|
||||
### Objectives
|
||||
|
||||
1. You are given two directories as arguments and the output should be any difference between the two directories
|
||||
@@ -1,5 +0,0 @@
|
||||
## Empty Files
|
||||
|
||||
### Objectives
|
||||
|
||||
1. Write a script to remove all the empty files in a given directory (including nested directories)
|
||||
@@ -1,9 +0,0 @@
|
||||
## Shell Scripting - Factors
|
||||
|
||||
### Objectives
|
||||
|
||||
Write a script that when given a number, will:
|
||||
|
||||
* Check if the number has 2 as factor, if yes it will print "one factor"
|
||||
* Check if the number has 3 as factor, if yes it will print "one factor...actually two!"
|
||||
* If none of them (2 and 3) is a factor, print the number itself
|
||||
@@ -1,7 +0,0 @@
|
||||
## Files Size
|
||||
|
||||
### Objectives
|
||||
|
||||
1. Print the name and size of every file and directory in current path
|
||||
|
||||
Note: use at least one for loop!
|
||||
@@ -1,7 +0,0 @@
|
||||
## Great Day
|
||||
|
||||
### Objectives
|
||||
|
||||
1. Write a script that will print "Today is a great day!" unless it's given a day name and then it should print "Today is <given day>"
|
||||
|
||||
Note: no need to check whether the given argument is actually a valid day
|
||||
@@ -1,6 +0,0 @@
|
||||
## Shell Scripting - Hello World
|
||||
|
||||
### Objectives
|
||||
|
||||
1. Define a variable with the string 'Hello World'
|
||||
2. Print the value of the variable you've defined and redirect the output to the file "amazing_output.txt"
|
||||
@@ -1,5 +0,0 @@
|
||||
## It's Alive!
|
||||
|
||||
### Objectives
|
||||
|
||||
1. Write a script to determine whether a given host is down or up
|
||||
@@ -1,7 +0,0 @@
|
||||
## Number of Arguments
|
||||
|
||||
### Objectives
|
||||
|
||||
* Write a script that will print "Got it: <argument value>" in case of one argument
|
||||
* In case no arguments were provided, it will print "Usage: ./<program name> <argument>"
|
||||
* In case of more than one argument, print "hey hey...too many!"
|
||||
@@ -1,9 +0,0 @@
|
||||
## Shell Scripting - Print Arguments
|
||||
|
||||
### Objectives
|
||||
|
||||
You should include everything mentioned here in one shell script
|
||||
|
||||
1. Print the first argument passed to the script
|
||||
2. Print the number of arguments passed to the script
|
||||
3.
|
||||
@@ -1,13 +0,0 @@
|
||||
## Basic Date
|
||||
|
||||
### Objectives
|
||||
|
||||
1. Write a script that will put the current date in a file called "the_date.txt"
|
||||
|
||||
### Solution
|
||||
|
||||
```
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo $(date) > the_date.txt
|
||||
```
|
||||
@@ -1,24 +0,0 @@
|
||||
## Count Chars
|
||||
|
||||
### Objectives
|
||||
|
||||
1. Read input from the user until you get empty string
|
||||
2. For each of the lines you read, count the number of characters and print it
|
||||
|
||||
### Constraints
|
||||
|
||||
1. You must use a while loop
|
||||
2. Assume at least three lines of input
|
||||
|
||||
### Solution
|
||||
|
||||
```
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo -n "Please insert your input: "
|
||||
|
||||
while read line; do
|
||||
echo -n "$line" | wc -c
|
||||
echo -n "Please insert your input: "
|
||||
done
|
||||
```
|
||||
@@ -1,30 +0,0 @@
|
||||
## Directories Comparison
|
||||
|
||||
### Objectives
|
||||
|
||||
1. You are given two directories as arguments and the output should be any difference between the two directories
|
||||
|
||||
### Solution
|
||||
|
||||
Suppose the name of the bash script is ```dirdiff.sh```
|
||||
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
if test $# -ne 2
|
||||
then
|
||||
echo -e "USAGE: ./dirdiff.sh directory1 directory2"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check for the checksums.
|
||||
# If both the checksums same, then both directories are same
|
||||
if test `ls -1 $1 | sort | md5sum | awk -F " " '{print $1}'` == `ls -1 $2 | sort | md5sum | awk -F " " '{print $1}'`
|
||||
then
|
||||
echo -e "No difference between the 2 directories"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
diff -q $1 $2
|
||||
|
||||
```
|
||||
@@ -1,20 +0,0 @@
|
||||
## Empty Files
|
||||
|
||||
### Objectives
|
||||
|
||||
1. Write a script to remove all the empty files in a given directory (including nested directories)
|
||||
|
||||
### Solution
|
||||
|
||||
```
|
||||
#! /bin/bash
|
||||
for x in *
|
||||
do
|
||||
if [ -s $x ]
|
||||
then
|
||||
continue
|
||||
else
|
||||
rm -rf $x
|
||||
fi
|
||||
done
|
||||
```
|
||||
@@ -1,20 +0,0 @@
|
||||
## Shell Scripting - Factors
|
||||
|
||||
### Objectives
|
||||
|
||||
Write a script that when given a number, will:
|
||||
|
||||
* Check if the number has 2 as factor, if yes it will print "one factor"
|
||||
* Check if the number has 3 as factor, if yes it will print "one factor...actually two!"
|
||||
* If none of them (2 and 3) is a factor, print the number itself
|
||||
|
||||
### Solution
|
||||
|
||||
```
|
||||
#!/usr/bin/env bash
|
||||
|
||||
(( $1 % 2 )) || res="one factor"
|
||||
(( $1 % 3 )) || res+="...actually two!"
|
||||
|
||||
echo ${res:-$1}
|
||||
```
|
||||
@@ -1,17 +0,0 @@
|
||||
## Files Size
|
||||
|
||||
### Objectives
|
||||
|
||||
1. Print the name and size of every file and directory in current path
|
||||
|
||||
Note: use at least one for loop!
|
||||
|
||||
### Solution
|
||||
|
||||
```
|
||||
#!/usr/bin/env bash
|
||||
|
||||
for i in $(ls -S1); do
|
||||
echo $i: $(du -sh "$i" | cut -f1)
|
||||
done
|
||||
```
|
||||
@@ -1,15 +0,0 @@
|
||||
## Great Day
|
||||
|
||||
### Objectives
|
||||
|
||||
1. Write a script that will print "Today is a great day!" unless it's given a day name and then it should print "Today is <given day>"
|
||||
|
||||
Note: no need to check whether the given argument is actually a valid day
|
||||
|
||||
### Solution
|
||||
|
||||
```
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "Today is ${1:-a great day!}"
|
||||
```
|
||||
@@ -1,15 +0,0 @@
|
||||
## Shell Scripting - Hello World
|
||||
|
||||
### Objectives
|
||||
|
||||
1. Define a variable with the string 'Hello World'
|
||||
2. Print the value of the variable you've defined and redirect the output to the file "amazing_output.txt"
|
||||
|
||||
### Solution
|
||||
|
||||
```
|
||||
#!/usr/bin/env bash
|
||||
|
||||
HW_STR="Hello World"
|
||||
echo $HW_STR > amazing_output.txt
|
||||
```
|
||||
@@ -1,20 +0,0 @@
|
||||
## It's Alive!
|
||||
|
||||
### Objectives
|
||||
|
||||
1. Write a script to determine whether a given host is down or up
|
||||
|
||||
### Solution
|
||||
|
||||
```
|
||||
#!/usr/bin/env bash
|
||||
SERVERIP=<IP Address>
|
||||
NOTIFYEMAIL=test@example.com
|
||||
|
||||
ping -c 3 $SERVERIP > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
# Use mailer here:
|
||||
mailx -s "Server $SERVERIP is down" -t "$NOTIFYEMAIL" < /dev/null
|
||||
fi
|
||||
```
|
||||
@@ -1,26 +0,0 @@
|
||||
## Number of Arguments
|
||||
|
||||
### Objectives
|
||||
|
||||
* Write a script that will print "Got it: <argument value>" in case of one argument
|
||||
* In case no arguments were provided, it will print "Usage: ./<program name> <argument>"
|
||||
* In case of more than one argument, print "hey hey...too many!"
|
||||
|
||||
### Solution
|
||||
|
||||
```
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eu
|
||||
|
||||
main() {
|
||||
case $# in
|
||||
0) printf "%s" "Usage: ./<program name> <argument>"; return 1 ;;
|
||||
1) printf "%s" "Got it: $1"; return 0 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
```
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
## Sum
|
||||
|
||||
### Objectives
|
||||
|
||||
1. Write a script that gets two numbers and prints their sum
|
||||
3. Make sure the input is valid (= you got two numbers from the user)
|
||||
2. Test the script by running and passing it two numbers as arguments
|
||||
|
||||
### Constraints
|
||||
|
||||
1. Use functions
|
||||
|
||||
### Solution
|
||||
|
||||
```
|
||||
#!/usr/bin/env bash
|
||||
|
||||
re='^[0-9]+$'
|
||||
|
||||
if ! [[ $1 =~ $re && $2 =~ $re ]]; then
|
||||
echo "Oh no...I need two numbers"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
function sum {
|
||||
echo $(( $1 + $2 ))
|
||||
}
|
||||
|
||||
sum $1 $2
|
||||
```
|
||||
@@ -1,11 +0,0 @@
|
||||
## Sum
|
||||
|
||||
### Objectives
|
||||
|
||||
1. Write a script that gets two numbers and prints their sum
|
||||
3. Make sure the input is valid (= you got two numbers from the user)
|
||||
2. Test the script by running and passing it two numbers as arguments
|
||||
|
||||
### Constraints
|
||||
|
||||
1. Use functions
|
||||
Reference in New Issue
Block a user