diff --git a/Self-solutions/Day_1/day1_challange_solution.sh b/Self-solutions/Day_1/day1_challange_solution.sh new file mode 100755 index 0000000..a80d04d --- /dev/null +++ b/Self-solutions/Day_1/day1_challange_solution.sh @@ -0,0 +1,95 @@ +#!/bin/bash + +##################################################################### +# Script Name: day1_challange_solution.sh +# Author: Salwad Basha Shaik +# Date: July 31, 2023 +# Description: This script contains solution for all the 6 tasks for Day-1 part of BashBlaze: 7 Days of Bash Scripting Challenge. +# Usage: ./day1_challange_solution.sh +# Email: salvathshaik786143@gmail.com +# LinkedIn: https://www.linkedin.com/in/salwad-basha-shaik/ +# Github: https://github.com/salvathshaik/ +##################################################################### + +# set -x Used it while debugging the script. + +#Task 1: Comments +#In bash scripts, comments are used to add explanatory notes or disable certain lines of code. Your task is to create a bash script with comments explaining what the script does. + +#Task_1 Solution: + ## This is a comment in shell script + + +#Task 2: Echo +#The echo command is used to display messages on the terminal. Your task is to create a bash script that uses echo to print a message of your choice. + +#Task-2 solution: +echo "This is Day-1 task-2 echo example" + + +#Task 3: Variables +#Variables in bash are used to store data and can be referenced by their name. Your task is to create a bash script that declares variables and assigns values to them. + +#Task 4: Using Variables +#Now that you have declared variables, let's use them to perform a simple task. Create a bash script that takes two variables (numbers) as input and prints their sum using those variables. + + +#Task-3 and Task-4 solution: +#note: Don't give space after '=' operand below , otherwise you will get errors +a=3 +b=7 +c=$(( a + b )) #The double parentheses are used for arithmetic evaluation in Bash. It allows you to perform arithmetic operations on numerical values within the shell script. +echo "sum of two elements $a + $b = $c" + +#Improvising the task3&4 +echo "enter the first number: " +read a + +echo "enter the second number: " +read b + +c=$(( a + b )) +echo "sum of $a and $b is $c" + + + +#Task 5: Using Built-in Variables +#Bash provides several built-in variables that hold useful information. Your task is to create a bash script that utilizes at least three different built-in variables to display relevant information. + +#task-5 solution: +echo "Disk usage: " +df -h + +echo "Checking exit status of the last commmand $?" #If we get 0 means successful + +echo "To install any module, let's say net-tools for checking network connections" +sudo apt-get update +sudo apt-get install net-tools + + +echo "Checking network connections: " +echo "Display listening TCP and UDP ports" +netstat -tuln + +#netstat -rn # Display routing table + + +echo "Checking DNS resolution of google: " +nslookup www.google.com + +echo "Checking if service is running: " +systemctl status ssh + + +#Task-6 Wildcards +#Wildcards are special characters used to perform pattern matching when working with files. Your task is to create a bash script that utilizes wildcards to list all the files with a specific extension in a directory. + +#Task-6 solution: +#Wildcards in shell scripting are special characters used to represent one or more characters in a file or directory name. example ls, mv, cp rm etc. commonly used wildcards in shell scripting: + +#* (Asterisk): Represents zero or more characters. +ls *.txt # *.txt matches all files with the .txt extension within the directory. + +#Wildcards are powerful tools for batch processing and manipulating files in shell scripts. However, it's essential to be cautious when using wildcards, especially with commands like rm. + + diff --git a/Self-solutions/Day_1/day_1_solution_practice.sh b/Self-solutions/Day_1/day_1_solution_practice.sh new file mode 100755 index 0000000..3655715 --- /dev/null +++ b/Self-solutions/Day_1/day_1_solution_practice.sh @@ -0,0 +1,140 @@ +#!/bin/bash + +set -x + +#Task 1: Comments +#In bash scripts, comments are used to add explanatory notes or disable certain lines of code. Your task is to create a bash script with comments explaining what the script does. + +#Task_1 Solution: + ## This is a comment in shell script + + +#Task 2: Echo +#The echo command is used to display messages on the terminal. Your task is to create a bash script that uses echo to print a message of your choice. + +#Task-2 solution: +echo "This is Day-1 task-2 echo example" + + +#Task 3: Variables +#Variables in bash are used to store data and can be referenced by their name. Your task is to create a bash script that declares variables and assigns values to them. + +#Task 4: Using Variables +#Now that you have declared variables, let's use them to perform a simple task. Create a bash script that takes two variables (numbers) as input and prints their sum using those variables. + + +#Task-3 and Task-4 solution: +#note: Don't give space after '=' operand below , otherwise you will get errors +a=3 +b=7 +c=$(( a + b )) #The double parentheses are used for arithmetic evaluation in Bash. It allows you to perform arithmetic operations on numerical values within the shell script. +echo "sum of two elements $a + $b = $c" + +#Improvising the task3&4 +echo "enter the first number: " +read a + +echo "enter the second number: " +read b + +c=$(( a + b )) +echo "sum of $a and $b is $c" + + + +#Task 5: Using Built-in Variables +#Bash provides several built-in variables that hold useful information. Your task is to create a bash script that utilizes at least three different built-in variables to display relevant information. + +#task-5 solution: +echo "Disk usage: " +df -h + +echo "Checking exit status of the last commmand $?" #If we get 0 means successful + +echo "To install any module, let's say net-tools for checking network connections" +sudo apt-get update +sudo apt-get install net-tools + + +echo "Checking network connections: " +echo "Display listening TCP and UDP ports" +netstat -tuln + +#netstat -rn # Display routing table + + +echo "Checking DNS resolution of google: " +nslookup www.google.com + +echo "Checking if service is running: " +systemctl status ssh + +## There are more as follows + +#Download a file using wget: wget http://example.com/file.zip +#Generate an SSH key pair: ssh-keygen -t rsa -b 4096 +#Install Python dependencies from requirements.txt: pip install -r requirements.txt +#Monitor log files in real-time: tail -f /var/log/ +#Search for a specific pattern in files: grep "pattern" /path/to/files/* +#Check the content of a log file: cat /var/log/ +#Use curl to test APIs or URLs: curl http://example.com/api +#Restart a service: sudo systemctl restart +#Create a backup of a directory using tar: tar -czvf backup.tar.gz /path/to/directory +#View running processes: ps aux +#Monitor system resources with top: top +#to check and list all runnig services: systemctl list-units --type=service --state=running + #service --status all +## Display the name of the script file: echo "Script name: $0" +# Display the number of arguments passed to the script: echo "Number of arguments: $#" +## Display the process ID of the current script: echo "Process ID of the current script: $$" +## Display the parent process ID: echo "Parent process ID: $PPID" +## Display the username of the current user: echo "Current username: $USER" +# Display the home directory of the current user: echo "Home directory: $HOME" +# Display the exit status of the last executed command: echo "Exit status of the last command: $?" +## Display the current working directory: echo "Current working directory: $PWD" + + +## + + +#Task-6 Wildcards +#Wildcards are special characters used to perform pattern matching when working with files. Your task is to create a bash script that utilizes wildcards to list all the files with a specific extension in a directory. + +#Task-6 solution: +#Wildcards in shell scripting are special characters used to represent one or more characters in a file or directory name. example ls, mv, cp rm etc. commonly used wildcards in shell scripting: + +#* (Asterisk): Represents zero or more characters. +#Example: *.txt matches all files with the .txt extension. +ls *.txt + +#? (Question Mark): Represents a single character. +#Example: file?.txt matches files like file1.txt, file2.txt, etc. + +#[] (Square Brackets): Represents a range of characters or a character set. +#Example: [aeiou] matches any vowel character. +#Example: [0-9] matches any digit. + +#! (Exclamation Mark): Negates the pattern. +#Example: !*.txt matches all files except those with the .txt extension. + +#{} (Curly Braces): Used for brace expansion, which generates multiple strings based on a pattern. +#Example: file{1,2,3}.txt expands to file1.txt, file2.txt, file3.txt. + +#Wildcards are powerful tools for batch processing and manipulating files in shell scripts. However, it's essential to be cautious when using wildcards, especially with commands like rm, to avoid accidentally deleting important files. Always double-check your patterns before executing commands with wildcards. + + + + + + + + + + + + + + + + + diff --git a/Self-solutions/Day_1/readme.txt b/Self-solutions/Day_1/readme.txt new file mode 100644 index 0000000..6178965 --- /dev/null +++ b/Self-solutions/Day_1/readme.txt @@ -0,0 +1 @@ +please run 'day1_challange_solution.sh' diff --git a/Self-solutions/Day_2/day2.0_challange_solution.sh b/Self-solutions/Day_2/day2.0_challange_solution.sh new file mode 100755 index 0000000..d89d96a --- /dev/null +++ b/Self-solutions/Day_2/day2.0_challange_solution.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +##################################################################### +# Script Name: day_2.0_challange_solution.sh +# Author: Salwad Basha Shaik +# Date: August 1, 2023 +# Description: This script contains solution for Day 2 Bash Scripting Challenge - Interactive File and Directory Explorer part of BashBlaze: 7 Days of Bash Scripting Challenge. +# Usage: ./day_2.0__challange_solution.sh +# Email: salvathshaik786143@gmail.com +# LinkedIn: https://www.linkedin.com/in/salwad-basha-shaik/ +# Github: https://github.com/salvathshaik/ +##################################################################### + +####################Day 2 Bash Scripting Challenge - Interactive File and Directory Explorer +#Welcome to Day 2 of the Bash Scripting Challenge! In this challenge, you will create a bash script that serves as an interactive file and directory explorer. The script will allow you to explore the files and directories in the current path and provide a character counting feature for the user's input. + +####################Challenge Description####################### +#The script will have two main parts: + +###################Part 1: File and Directory Exploration + #Upon execution without any command-line arguments, the script will display a welcome message and list all the files and directories in the current path. + #For each file and directory, the script will print its name and size in human-readable format (e.g., KB, MB, GB). This information will be obtained using the ls command with appropriate options. + #The list of files and directories will be displayed in a loop until the user decides to exit the explorer. +##################Part 2: Character Counting + #After displaying the file and directory list, the script will prompt the user to enter a line of text. + #The script will read the user's input until an empty string is entered (i.e., the user presses Enter without any text). + #For each line of text entered by the user, the script will count the number of characters in that line. + #The character count for each line entered by the user will be displayed. + + +#################Example Interaction + #$ ./explorer.sh + #Welcome to the Interactive File and Directory Explorer! + +#Files and Directories in the Current Path: +#- file1.txt (100 KB) +#- dir1 (2 MB) +#- script.sh (3 KB) +#... + +#Enter a line of text (Press Enter without text to exit): Hello, this is a sample line. +#Character Count: 27 + +#Enter a line of text (Press Enter without text to exit): Another line to count. +#Character Count: 25 + +#Enter a line of text (Press Enter without text to exit): +#Exiting the Interactive Explorer. Goodbye! + +echo +echo "Welcome to the Interactive File and Directory Explorer!" +while true; do #this will be worked as infinite loop in shell script + + echo + echo "Files and Directories in the Current Path:" + + #This extract each and every directory and file in current path using $PWD and for loop to iterate over every item + for directoryItemName in $PWD/*; do + + if [ -f "$directoryItemName" ]; then #checking if the item is file then we use ls -lh to get the file size + directoryItemSize=$(ls -lh "$directoryItemName" | awk '{print $5}') #we are using awk command to extract the 5th item from ls output + + elif [ -d "$directoryItemName" ]; then #here we are checking if item is directory or not using -d + directoryItemSize=$(du -sh "$directoryItemName" | awk '{print $1}') #using du -sh for directory size as ls will not gonna give and extractin g the first argument for size. + fi + + directoryItemBaseName=$(basename "$directoryItemName") #using basename keyword to extract only name of the file otherwise we wil get whole path + echo "- $directoryItemBaseName ($directoryItemSize)" + + done + echo + read -p "Enter a line of text (Press Enter without text to exit): " userInputString #taking input from the user using read with -p argument , if we mention -p then it will ask the prompt and store the input to variable. + if [ -z "$userInputString" ]; then #checking if the statement length is 0 using -z means it is empty then we will exit the infinite loop. + echo "Exiting the Interactive Explorer. Goodbye!" + echo + break #using break to exit from the infinite loop + else + characterCountOfStatement=$( echo -n "$userInputString" | wc -c ) #counting the characters of a statement using wc -c means word count with -c argument for character counting. and we are eliminating newline with the help of echo -n here. + echo "Character Count: $characterCountOfStatement" + fi +done diff --git a/Self-solutions/Day_2/day2.1_challange_solution.sh b/Self-solutions/Day_2/day2.1_challange_solution.sh new file mode 100755 index 0000000..a163cb6 --- /dev/null +++ b/Self-solutions/Day_2/day2.1_challange_solution.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +#set -x #For debugging the script + +##################################################################### +# Script Name: day2.1_challange_solution.sh +# Author: Salwad Basha Shaik +# Date: August 1, 2023 +# Description: This script contains solution for Day 2.1 Directory Backup with Rotation part of BashBlaze: 7 Days of Bash Scripting Challenge. +# Usage: ./day2.1_challange_solution.sh +# Email: salvathshaik786143@gmail.com +# LinkedIn: https://www.linkedin.com/in/salwad-basha-shaik/ +# Github: https://github.com/salvathshaik/ +##################################################################### + + +################################Directory Backup with Rotation + #This is another challenge for Day 2 of the Bash Scripting Challenge! In this challenge, you will create a bash script that performs a backup of a specified directory and implements a rotation mechanism to manage backups. + + + +################################Challenge Description +#Your task is to create a bash script that takes a directory path as a command-line argument and performs a backup of the directory. The script should create timestamped backup folders and copy all the files from the specified directory into the backup folder. + +#Additionally, the script should implement a rotation mechanism to keep only the last 3 backups. This means that if there are more than 3 backup folders, the oldest backup folders should be removed to ensure only the most recent backups are retained. + +#The script will create a timestamped backup folder inside the specified directory and copy all the files into it. It will also check for existing backup folders and remove the oldest backups to keep only the last 3 backups. + + +directoryPath=$1 #taking first command line argument + +#this is to check the count of files starts with 'backup' name. +backupFilesCount=$( ls -1 /root| grep -c ^backup ) +# ls -1 : It will give the filenames in single column +# '|' pipe symbol will transfer the output of previous command to next command here +# grep -c ^backup: grep command useful to search the file starts with 'backup' name. ^ symbol useful to starts with and -c will give the count. + + +if [ $backupFilesCount -le 3 ]; then + + #trying to give the unique name for every backup including date as below format as a file name + # Get the current date to use in the backup filename + backup_date=$(date +%Y%m%d%H%M%S) #date with the format YYYYMMDDHHMMSS + + #defining full name of the backup file + backup_filename="backup_$backup_date.tar.gz" + + # Create the backup archive using tar + tar -czf /root/"$backup_filename" --absolute-names "$directoryPath" + + #first parameter is the backup file name with it's path to store + # second paramter is from where we should take the backup(path of the backup folder) + #here we are taking backup from curent folder + #-cvzf is for compressinng the tar file and we can use -xvzf is for extractinv the tar file . + #just a first letter change c:Create a new archive , x:extract here, z:Compress the archive using gzip, f:Specify the name of the archive file, v:output will of backup directorypath will be return.will display the names of the files it is processing as it performs its operations. + echo "Backup created: $directoryPath/$backup_filename" + +elif [ $backupFilesCount -gt 3 ]; then #this elif block will check for count is 3 + oldestFileName=$( ls -1 /root | grep ^backup | sort -nr | tail -1 ) + #ls -1 /root: will give us the filenames in single column + #grep ^backup: extract only files starts with backup' from previous command output + #sort -nr: # sorting the files in descending order , for ascending we can use sort -n + #tail -1 : taking the last file name from previous output as oldest file will be in descending order + rm /root/"$oldestFileName" #removing the oldest file + echo "Removed the oldest file: $oldestFileName" + #creating the backup with the new file name, it's like replacing the new file after deleting the old file among 3 backup files. + backup_date=$(date +%Y%m%d%H%M%S) + backup_filename="backup_$backup_date.tar.gz" + tar -czf /root/"$backup_filename" --absolute-names "$directoryPath" + echo "Backup created: $directoryPath/$backup_filename" +fi + + + +#############################Improvised and automated this script using crontab like below as an advancement. +#I have used crontab to schedule the backup script to run every day at 11:50 PM. +#opened the crontab configuration by running : crontab -e and then you can run crontab -l to see the scheduled configurations. +#and added the following line at the end of the crontab file: 50 23 * * * /root/shell-scripting-projects/2_backup_log_files.sh >> /root/backup_log.log 2>&1 + #the >> operator appends the output (both standard output and standard error) of the cron job to the specified log file (backup_log.log). The 2>&1 part ensures that both standard output (1) and standard error (2) are redirected to the log file. + diff --git a/Self-solutions/Day_2/day_2.0_solution_practice.sh b/Self-solutions/Day_2/day_2.0_solution_practice.sh new file mode 100755 index 0000000..d8770a6 --- /dev/null +++ b/Self-solutions/Day_2/day_2.0_solution_practice.sh @@ -0,0 +1,184 @@ +#!/bin/bash + +##################################################################### +# Script Name: day_2.0_challange_solution.sh +# Author: Salwad Basha Shaik +# Date: August 1, 2023 +# Description: This script contains solution for Day 2 Bash Scripting Challenge - Interactive File and Directory Explorer part of BashBlaze: 7 Days of Bash Scripting Challenge. +# Usage: ./day_2.0__challange_solution.sh +# Email: salvathshaik786143@gmail.com +# LinkedIn: https://www.linkedin.com/in/salwad-basha-shaik/ +# Github: https://github.com/salvathshaik/ +##################################################################### + +####################Day 2 Bash Scripting Challenge - Interactive File and Directory Explorer +#Welcome to Day 2 of the Bash Scripting Challenge! In this challenge, you will create a bash script that serves as an interactive file and directory explorer. The script will allow you to explore the files and directories in the current path and provide a character counting feature for the user's input. + +####################Challenge Description####################### +#The script will have two main parts: + +###################Part 1: File and Directory Exploration + #Upon execution without any command-line arguments, the script will display a welcome message and list all the files and directories in the current path. + #For each file and directory, the script will print its name and size in human-readable format (e.g., KB, MB, GB). This information will be obtained using the ls command with appropriate options. + #The list of files and directories will be displayed in a loop until the user decides to exit the explorer. +##################Part 2: Character Counting + #After displaying the file and directory list, the script will prompt the user to enter a line of text. + #The script will read the user's input until an empty string is entered (i.e., the user presses Enter without any text). + #For each line of text entered by the user, the script will count the number of characters in that line. + #The character count for each line entered by the user will be displayed. + + +#################Example Interaction + #$ ./explorer.sh + #Welcome to the Interactive File and Directory Explorer! + +#Files and Directories in the Current Path: +#- file1.txt (100 KB) +#- dir1 (2 MB) +#- script.sh (3 KB) +#... + +#Enter a line of text (Press Enter without text to exit): Hello, this is a sample line. +#Character Count: 27 + +#Enter a line of text (Press Enter without text to exit): Another line to count. +#Character Count: 25 + +#Enter a line of text (Press Enter without text to exit): +#Exiting the Interactive Explorer. Goodbye! + +echo +echo "Welcome to the Interactive File and Directory Explorer!" +while true; do #this will be worked as infinite loop in shell script + + echo + echo "Files and Directories in the Current Path:" + + #This extract each and every directory and file in current path using $PWD and for loop to iterate over every item + for directoryItemName in $PWD/*; do + + if [ -f "$directoryItemName" ]; then #checking if the item is file then we use ls -lh to get the file size + directoryItemSize=$(ls -lh "$directoryItemName" | awk '{print $5}') #we are using awk command to extract the 5th item from ls output + + elif [ -d "$directoryItemName" ]; then #here we are checking if item is directory or not using -d + directoryItemSize=$(du -sh "$directoryItemName" | awk '{print $1}') #using du -sh for directory size as ls will not gonna give and extractin g the first argument for size. + fi + + directoryItemBaseName=$(basename "$directoryItemName") #using basename keyword to extract only name of the file otherwise we wil get whole path + echo "- $directoryItemBaseName ($directoryItemSize)" + + done + echo + read -p "Enter a line of text (Press Enter without text to exit): " userInputString #taking input from the user using read with -p argument , if we mention -p then it will ask the prompt and store the input to variable. + if [ -z "$userInputString" ]; then #checking if the statement length is 0 using -z means it is empty then we will exit the infinite loop. + echo "Exiting the Interactive Explorer. Goodbye!" + echo + break #using break to exit from the infinite loop + else + characterCountOfStatement=$( echo -n "$userInputString" | wc -c ) #counting the characters of a statement using wc -c means word count with -c argument for character counting. and we are eliminating newline with the help of echo -n here. + echo "Character Count: $characterCountOfStatement" + fi +done + + +######################################################################################### +#practice-1 +#practicing infinite loop in shell script +#!/bin/bash + +while true; do + # Your code inside the infinite loop goes here + + # Example: Ask the user for input + read -p "Enter 'exit' to stop the loop: " user_input + + # Check if the user wants to exit + if [ "$user_input" = "exit" ]; then + echo "Exiting the loop." + break + fi +done + + + + +#practice-2 +#check if the user entered an empty string by comparing the input variable with an empty string. +#!/bin/bash + +read -p "Enter your input: " user_input + +if [ -z "$user_input" ]; then + echo "You entered an empty string." +else + echo "Your input is: $user_input" +fi + +#practice-3: +#practicing to get the file and directory size in a human-readable format. The -h option (or --human-readable) formats the sizes into KB, MB, GB, etc. +#!/bin/bash + +# Replace "path/to/your/file_or_directory" with the actual file or directory path +path="path/to/your/file_or_directory" + +# Get the size in human-readable format using du command +size=$(du -h "$path") + +echo "Size of $path: $size" + +#practice-4: +#practicing to get all the files and directories in specified path and get the size and its basename +#!/bin/bash + +# Replace "path/to/your/directory" with the actual directory path +directory="path/to/your/directory" + +# Loop through each item in the directory +for item in "$directory"/*; do + # Get the size and name of the file/directory in human-readable format using ls command + size=$(ls -lh "$item" | awk '{print $5}') + name=$(basename "$item") + + echo "$name: $size" +done + + +#practice-5: +#practiciing to get the word count of statment +#!/bin/bash + +# Replace "Your statement here" with the actual statement you want to count characters for +statement="Your statement here" + +# Get the character count using echo and wc commands +char_count=$(echo -n "$statement" | wc -c) + +echo "Character count: $char_count" + + +#practice-6: +#practicing to check if the directory is having file or directory and extracting size based on the type and using ls -h and du -sh for file and directory accordingly. +#!/bin/bash + +# Replace "path/to/your/directory" with the actual directory path +directory="path/to/your/directory" + +# Loop through each item in the directory +for item in "$directory"/*; do + if [ -f "$item" ]; then + # For files, get the size using ls command + size=$(ls -lh "$item" | awk '{print $5}') + elif [ -d "$item" ]; then + # For directories, get the size using du command + size=$(du -sh "$item" | awk '{print $1}') + fi + + name=$(basename "$item") + + echo "$name: $size" +done + + + + + diff --git a/Self-solutions/Day_2/day_2.1_solution_practice.sh b/Self-solutions/Day_2/day_2.1_solution_practice.sh new file mode 100644 index 0000000..822b515 --- /dev/null +++ b/Self-solutions/Day_2/day_2.1_solution_practice.sh @@ -0,0 +1,134 @@ +#!/bin/bash + +#this script is to take the backup of logs or any work you done. and this is automated shell script that runs everyday at 11:50PM IST using cronttab + +#trying to give the uniqueu name for every backup including date as below format as a file name +# Get the current date to use in the backup filename +backup_date=$(date +%Y%m%d%H%M%S) + +#defining full name of the backup file +backup_filename="backup_$backup_date.tar.gz" + +# Create the backup archive using tar +tar -cvzf /root/"$backup_filename" ./* #first parameter is the backup file name with it's path to store + # second paramter is from where we should take the backup(path of the backup folder) + #here we are taking backup from curent folder + #-cvzf is for compressinng the tar file and -xvzf is for extractinv the tar file . + #just a first letter change c:compress , x:extract here. + +echo "Backup created: $backup_filename" + + +#I have used crontab to schedule the backup script to run every day at 11:50 PM. +#opened the crontab configuration by running : crontab -e and then you can run crontab -l to see the scheduled configurations. +#and added the following line at the end of the crontab file: 50 23 * * * /root/shell-scripting-projects/2_backup_log_files.sh >> /root/backup_log.log 2>&1 + #the >> operator appends the output (both standard output and standard error) of the cron job to the specified log file (backup_log.log). The 2>&1 part ensures that both standard output (1) and standard error (2) are redirected to the log file. +#then it will run this at specified timing and take the logs or your work done. +#To remove all crontab schedules for the current user, you can use the crontab -r command. +#Remember to be cautious when editing crontab, especially with root privileges, as incorrect changes can cause unintended issues with your scheduled tasks. Double-check your changes before saving the crontab file. so prepare first and setup at once. + + +#practice-1 +#practicing the To count the number of files that start with "backup" in a given directory path +#!/bin/bash + +# Directory path where you want to count files +directory="/path/to/directory" + +# Count the number of files starting with "backup" in the directory +file_count=$(ls -1 "$directory" | grep -c '^backup') + +echo "Number of files starting with 'backup': $file_count" + +#practice-2 +#To find the oldest file among the files starting with "backup" in the given directory path +#!/bin/bash + +# Directory path where you want to find the files +directory="/path/to/directory" + +# Find all files starting with "backup" and get their modification time +oldest_file=$(find "$directory" -maxdepth 1 -name 'backup*' -type f -exec stat -c '%Y %n' {} + | sort -n | head -n 1 | awk '{print $2}') + +echo "The oldest file among files starting with 'backup' is: $oldest_file" + + + +#practice-3 +#To get the files in descending order (from the newest to the oldest) among the files starting with "backup" in the given directory path +#!/bin/bash + +# Directory path where you want to find the files +directory="/path/to/directory" + +# Find all files starting with "backup" and get their modification time +newest_file=$(find "$directory" -maxdepth 1 -name 'backup*' -type f -exec stat -c '%Y %n' {} + | sort -nr | head -n 1 | awk '{print $2}') + +echo "The newest file among files starting with 'backup' is: $newest_file" +#The modification made to the script is in the sort -nr part, where we use the -r flag to sort the files in reverse (descending) order based on their modification time. + +#practice-4 +#practicing the conditional statements in shell scripting +#!/bin/bash + +# Variables for comparison +number1=10 +number2=20 + +# Check if the numbers are equal +if [ "$number1" == "$number2" ]; then + echo "Numbers are equal" +else + echo "Numbers are not equal" +fi + +# Check if the numbers are not equal +if [ "$number1" != "$number2" ]; then + echo "Numbers are not equal" +else + echo "Numbers are equal" +fi + +# Check if number1 is greater than number2 +if [ "$number1" -gt "$number2" ]; then + echo "Number1 is greater than Number2" +else + echo "Number1 is not greater than Number2" +fi + +# Check if number1 is less than or equal to number2 +if [ "$number1" -le "$number2" ]; then + echo "Number1 is less than or equal to Number2" +else + echo "Number1 is not less than or equal to Number2" +fi + + +#practice-5 +#following the below approach to avoice the error tar: Removing leading `/' from member names +tar -czf your_archive.tar.gz --absolute-names /path/to/files + +#practice-6 +#practicing the command line arguments in shell scripting + +#These arguments allow you to provide input to the script at runtime, enabling you to customize the script's behavior based on the provided values. +# In bash (a popular shell used on many Unix-like systems), you can access command-line arguments using special variables: + +# $0: The name of the script itself. +# $1, $2, $3, ...: These variables represent the first, second, third, and so on, command-line arguments passed to the script. +# $@: Represents all the command-line arguments as separate words. It is an array-like variable. +# $#: The number of command-line arguments passed to the script. +#!/bin/bash + +# Access command-line arguments using $1 and $2 +echo "First argument: $1" +echo "Second argument: $2" + +# Access all command-line arguments using $@ +echo "All arguments: $@" + +# Access the number of arguments using $# +echo "Number of arguments: $#" + + + diff --git a/Self-solutions/Day_2/readme.txt b/Self-solutions/Day_2/readme.txt new file mode 100644 index 0000000..7aa766b --- /dev/null +++ b/Self-solutions/Day_2/readme.txt @@ -0,0 +1,47 @@ +please run 'day2.0_challange_solution.sh' and day2.1_challange_solution.sh + + +sample output for the script day2.0_challange_solution.sh: + +~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_2# ./day2.0_challange_solution.sh + +Welcome to the Interactive File and Directory Explorer! + +Files and Directories in the Current Path: +- day2.0_challange_solution.sh (4.6K) +- day_2.0_solution_practice.sh (4.6K) +- readme.txt (40) +- temp (8.0K) + +Enter a line of text (Press Enter without text to exit): Hello, this is a sample line. +Character Count: 29 + +Files and Directories in the Current Path: +- day2.0_challange_solution.sh (4.6K) +- day_2.0_solution_practice.sh (4.6K) +- readme.txt (40) +- temp (8.0K) + +Enter a line of text (Press Enter without text to exit): Another line to count. +Character Count: 22 + +Files and Directories in the Current Path: +- day2.0_challange_solution.sh (4.6K) +- day_2.0_solution_practice.sh (4.6K) +- readme.txt (40) +- temp (8.0K) + +Enter a line of text (Press Enter without text to exit): +Exiting the Interactive Explorer. Goodbye! + + +sample output for the script day2.1_challange_solution.sh +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_2# ./day2.1_challange_solution.sh /root/backup_directory/ +Backup created: /root/backup_directory//backup_20230801124651.tar.gz +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_2# ./day2.1_challange_solution.sh /root/backup_directory/ +Backup created: /root/backup_directory//backup_20230801124655.tar.gz +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_2# ./day2.1_challange_solution.sh /root/backup_directory/ +Backup created: /root/backup_directory//backup_20230801124656.tar.gz +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_2# ./day2.1_challange_solution.sh /root/backup_directory/ +Removed the oldest file: backup_20230801124651.tar.gz +Backup created: /root/backup_directory//backup_20230801124657.tar.gz diff --git a/Self-solutions/Day_3/day3_challenge_solution.sh b/Self-solutions/Day_3/day3_challenge_solution.sh new file mode 100755 index 0000000..0207a43 --- /dev/null +++ b/Self-solutions/Day_3/day3_challenge_solution.sh @@ -0,0 +1,337 @@ +#!/bin/bash +#set -x + +##################################################################### +# Script Name: day_3_challange_solution.sh +# Author: Salwad Basha Shaik +# Date: August 2, 2023 +# Description: This script contains solution for Day 3 User Account Management as part of BashBlaze: 7 Days of Bash Scripting Challenge. +# Usage: ./day_3__challange_solution.sh +# Email: salvathshaik786143@gmail.com +# LinkedIn: https://www.linkedin.com/in/salwad-basha-shaik/ +# Github: https://github.com/salvathshaik/ +##################################################################### + +######################################## Day-3 Challenge: User Account Management ######################################### + +#In this challenge, you will create a bash script that provides options for managing user accounts on the system. The script should allow users to perform various user account-related tasks based on command-line arguments. + +###########Part 1: Account Creation +#Implement an option -c or --create that allows the script to create a new user account. The script should prompt the user to enter the new username and password. + +#Ensure that the script checks whether the username is available before creating the account. If the username already exists, display an appropriate message and exit gracefully. + +#After creating the account, display a success message with the newly created username. + + +#########Part 2: Account Deletion +#Implement an option -d or --delete that allows the script to delete an existing user account. The script should prompt the user to enter the username of the account to be deleted. + +#Ensure that the script checks whether the username exists before attempting to delete the account. If the username does not exist, display an appropriate message and exit gracefully. + +#After successfully deleting the account, display a confirmation message with the deleted username. + + +#########Part 3: Password Reset +#Implement an option -r or --reset that allows the script to reset the password of an existing user account. The script should prompt the user to enter the username and the new password. + +#Ensure that the script checks whether the username exists before attempting to reset the password. If the username does not exist, display an appropriate message and exit gracefully. + +#After resetting the password, display a success message with the username and the updated password. + + +########Part 4: List User Accounts +#Implement an option -l or --list that allows the script to list all user accounts on the system. The script should display the usernames and their corresponding user IDs (UID). + + +#######Part 5: Help and Usage Information +#Implement an option -h or --help that displays usage information and the available command-line options for the script. + + +#######Bonus Points (Optional) +#If you want to challenge yourself further, you can add additional features to the script, such as: + +#Displaying more detailed information about user accounts (e.g., home directory, shell, etc.). +#Allowing the modification of user account properties (e.g., username, user ID, etc.). +#Remember to handle errors gracefully, provide appropriate user prompts, and add comments to explain the logic and purpose of each part of the script. + +#Created function to list out the User Options to run the script. +displayUserOptions() { + +echo +echo "Usage: ./day3_challenge_solution.py [OPTIONS]" +echo "Options:" +echo " -c, --create Create a new user account" +echo " -d, --delete Delete an existing user account" +echo " -r, --reset Reset password for an existing user account" +echo " -l, --list List all user accounts on the system" +echo " -h, --help Display this help and exit." +echo +echo "For Bonus features please use below options" +echo " -ui, --userinfo Display more information about an existed user account" +echo " -mu, --modusername Modify username for an existing user account" +echo " -muid, --moduserid Modify user ID for an existing user account" +echo " -mh, --modhome Modify home directory for an existing user account " +echo " -ms, --modshell Modify default shell for an existing user account" +echo " -mg, --modgroup Modify group for an existing user account " +echo " -mpa, --modpassage Modify password expiration date for an existing user account" +echo " -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account" +echo + +} + +#Created the function to check if user is already existed or not in our system. +is_user_exists() { + userName=$1 #we are taking function argument that passess while calling the function. here $1 is for user provided username input. + + if grep -q "^$userName:" /etc/passwd; then #checking if user already present or not using + #grep command checks if the specifie username that starts with $username is present in /etc/passwd output or #not + #-q option with grep will hide the output of the grep command + + return 0 #returning 0 if username is present otherwise sending 1. + else + return 1 + fi + +} + +displayUserOptions #calling this function to dispay the user option at the time of script runs. + +userOption=$1 #taking the command line 1st argument that pass while running the script and assigning to this variable. + +if [ "$userOption" == "-c" ] || [ "$userOption" == "--create" ]; then #putting two conditions to check -c OR --create user option to create the user. + + + read -p "Enter username to create the user account: " usernameByUser #taking username input from the user to create the user + is_user_exists "$usernameByUser" #passing the user provided username to the is_user_exists function as a command line argument. + + if [ $? -eq 0 ]; then #here $? - checks the previous command output and get the output here and i am comparing it with 0 means user exists. + echo "user $usernameByUser already existed, so please create the user with different username!" + exit 0 #existing from the script with safe command exit 0 with successful run if user exists. + fi + read -p "Enter password to create the account: " passwordByUser + sudo useradd "$usernameByUser" #using useradd command with sudo permission to create the user + echo "$usernameByUser:$passwordByUser" | chpasswd #assigning the user provided password to created user using echo to pass the output to chpasswd. + echo "user account $usernameByUser has been created successfully!" + +elif [ "$userOption" == "-d" ] || [ "$userOption" == "--delete" ]; then + read -p "Enter username to delete the user account: " usernameByUser + + is_user_exists "$usernameByUser" + + if [ $? -eq 0 ]; then + sudo userdel "$usernameByUser" #deleting the user if user is present in our system. + echo "user account $usernameByUser has been deleted successfully!" + else + echo "user $usernameByUser is not existed, so please choose a existed user to delete!" + + fi +elif [ "$userOption" == "-r" ] || [ "$userOption" == "--reset" ]; then + read -p "Enter username to reset the user account password: " usernameByUser + + is_user_exists "$usernameByUser" + + if [ $? -eq 0 ]; then + echo "please enter a new password for $usernameByUser: " + read -s newUserPasswordByUser #read with -s option is to take the password by hiding the password to user while he enters. + echo "$usernameByUser:$newUserPasswordByUser" | chpasswd #same as assiging the password but also can useful to reset the new password. + echo "user account $usernameByUser reset password has completed successfully!" + else + echo "user $usernameByUser is not existed, so please choose a existed user to reset the password!" + + fi + +elif [ "$userOption" == "-l" ] || [ "$userOption" == "--list" ]; then + + echo "Username UID GID" #printing the username UID(User ID) and GID(group ID) + echo "---------------------" + while IFS=: read -r username _ uid gid _; do #here IFS is a field seperator which seperates the all the lines output of /etc/passwd with : semicolon + echo "$username $uid $gid" # that's why I have put = and : with IFS means IFS=: and after seperating with semicolon i have read the + done < /etc/passwd #username with $1 first argument , assigning $2 argument with dummy variable as we don't need this for now + #$2 argument is password basically and $3 and $4 arguments are UID and GID and leaving remaining arguments + #with _ dummy variable till end and we are iterating till last line so using while loop to iterate and + #/etc/passwd contains all the usernames with details. + + + #we can also implement this with other approach as below + # Using awk to print the username (first field) and UID (third field) + #awk -F: '{print "Username:", $1, "UID:", $3}' /etc/passwd + #here we use awk with print to display the output to terminal +elif [ "$userOption" == "-h" ] || [ "$userOption" == "--help" ]; then + displayUserOptions #displaying the user options for help option. + + +#From here is for the bonus features!! +elif [ "$userOption" == "-ui" ] || [ "$userOption" == "--userinfo" ]; then + + read -p "Enter username to know more information about the user account: " usernameByUser + + is_user_exists "$usernameByUser" + + if [ $? -eq 0 ]; then + sudo grep "$usernameByUser" /etc/passwd | awk -F: '{print "\n Username: ", $1"\n", "UID:", $3"\n", "Home directory:", $6"\n", "Default shell:", $7"\n"}' + #the above command will print out the Username, UID, Home directory, Default shell details for specific user. + #here we are using grep to find the username in the /etc/passwd file this will return whole line of output with : semicolon + #passing the output via | pipe symbol to awk command and here we are splitting line of output with : semicolon using F: + #using print to display the output to the terminal + else + echo "user $usernameByUser is not existed, so please choose an existed user to display more information about the user!" + + fi + + +elif [ "$userOption" == "-mu" ] || [ "$userOption" == "--modusername" ]; then #this is for modification of username + + read -p "Enter username that you wanted to modify it's username: " oldUsernameByUser + + is_user_exists "$oldUsernameByUser" + + if [ $? -eq 0 ]; then + read -p "Enter new username that you wanted to modify for user $oldUsernameByUser: " newUsernameByUser #taking new username as a input + sudo usermod -l "$newUsernameByUser" "$oldUsernameByUser" #using -l option with usermod to change the username + echo "Successfully Updated the username from $oldUsernameByUser to $newUsernameByUser! " + else + echo "user $usernameByUser is not existed, so please choose an existed user to modify it's username!" + fi + + +elif [ "$userOption" == "-muid" ] || [ "$userOption" == "--moduserid" ]; then #this is for modification of userID of an user + + read -p "Enter username that you wanted to modify it's user ID(UUID): " usernameByUser + + is_user_exists "$usernameByUser" + + if [ $? -eq 0 ]; then + oldUserID=$(id -u "$usernameByUser") #extracting the existing userID using id command with -u it will return the userID of an user + echo "Existed userID for user $usernameByUser is: $oldUserID" + read -p "Enter new userID that you wanted to modify for user $usernameByUser: " newUserIdByUser #taking new userID input + sudo usermod -u "$newUserIdByUser" "$usernameByUser" #using -u option with usermod command to modify it's userID + echo "Successfully Updated the userID for user $usernameByUser from $oldUserID to $newUserIdByUser ! " + else + echo "user $usernameByUser is not existed, so please choose an existed user to modify it's user ID !" + fi + + +elif [ "$userOption" == "-mh" ] || [ "$userOption" == "--modhome" ]; then #this is for modification of default home directory of an user + + read -p "Enter username that you wanted to modify it's default home directory: " usernameByUser + + is_user_exists "$usernameByUser" + + if [ $? -eq 0 ]; then + oldHomeDirectory=$(grep "^$usernameByUser" /etc/passwd | awk -F: '{print $6}') ##extracting the existing home directory with the help of + #grep to search the username in the /etc/passwd file and + #pass the output to awk command and given -F: for splitting + #with semicolon and using print with $6 6th argument to throw + #the default home directory as an output and assigning to varaible. + + echo "Default user home directory for user $usernameByUser is: $oldHomeDirectory" + read -p "Enter new user home directory that you wanted to modify for user $usernameByUser: " newUserHomeDirByUser + sudo usermod -d "$newUserHomeDirByUser" -m "$usernameByUser" # using -d option with usermod command to modify the default home directory. + #-m: moving all the files there in old directory to new directory. + echo "Successfully Updated the home directory for user $usernameByUser from $oldHomeDirectory to $newUserHomeDirByUser ! " + else + echo "user $usernameByUser is not existed, so please choose an existed user to modify it's user default home directory !" + fi + + +elif [ "$userOption" == "-ms" ] || [ "$userOption" == "--modshell" ]; then ##this is for modification of default shell of an user + + read -p "Enter username that you wanted to modify it's default shell: " usernameByUser + + is_user_exists "$usernameByUser" + + if [ $? -eq 0 ]; then + oldShell=$(grep "^$usernameByUser" /etc/passwd | awk -F: '{print $7}') #extracting the existing home directory with the help of + #grep to search the username in the /etc/passwd file and + #pass the output to awk command and given -F: for splitting + #with semicolon and using print with $7 7th argument to throw + #the default shell path as an output and assigning to varaible. + echo "Default Shell for user $usernameByUser is: $oldShell" + read -p "Enter new shell path that you wanted to modify for user $usernameByUser: " newShell + sudo usermod -s "$newShell" "$usernameByUser" + echo "Successfully Updated the new Shell for user $usernameByUser from $oldShell to $newShell ! " + else + echo "user $usernameByUser is not existed, so please choose an existed user to modify it's user default shell !" + fi + + +elif [ "$userOption" == "-mg" ] || [ "$userOption" == "--modgroup" ]; then ##this is for modification user group of an user + + read -p "Enter username that you wanted to modify it's group: " usernameByUser + + is_user_exists "$usernameByUser" + + if [ $? -eq 0 ]; then + oldGroup=$(id -gn $usernameByUser) #-g: Display the numeric group ID (GID) of the user. + #-n: Display the name of the user or group. + # using -gn, combines both options, and the command will display the name of the primary group associated with the user. + echo "Existed group name for user $usernameByUser is: $oldGroup" + read -p "Enter group name that you wanted to modify for user $usernameByUser: " newGroup + + if grep -q "^$newGroup:" /etc/group; then #checking if provided group name is exists or not in /etc/group file and add the username to group. + sudo usermod -aG $newGroup $usernameByUser #using -aG option with usermod command to add the specified group to the user. + #-a: This option tells the usermod command to append the user to the specified group(s) without r removing them from any other groups. + #-G: This option specifies the list of supplementary groups to which the user should be added. Mu ltiple group names can be provided, separated by commas, to add the user to multiple groups at once. + echo "Successfully Updated the new group for user $usernameByUser from $oldGroup to $newGroup ! " + else + echo "mentioned group is not present in system , please provided the existed group name !" + fi + else + echo "user $usernameByUser is not existed, so please choose an existed user to modify it's group name !" + fi + + +elif [ "$userOption" == "-mpa" ] || [ "$userOption" == "--modpassage" ]; then #this is for modification of password expiration date for user account. + + read -p "Enter username that you wanted to add a account password expiration date: " usernameByUser + + is_user_exists "$usernameByUser" + + if [ $? -eq 0 ]; then + read -p "Enter how many number of days password will expire for user $usernameByUser: " passExpireDays #taking password expiry in days as a input + passwd -x "$passExpireDays" "$usernameByUser" #The passwd command is used to set or change a user's password in Linux + #The -x option is used to set the maximum number of days a password can be used before it expires. + + echo "Successfully Updated the password expiry for user $usernameByUser ! " + echo + echo "Now the password expiry date information as follows..." + chage -l $usernameByUser #The chage command in Linux is used to manage user password aging information. It allows you to view and modify passwor d expiration. + #The -l option is used with the chage command to display the password aging information for a user account + else + echo "user $usernameByUser is not existed, so please choose an existed user to modify it's password expiry !" + fi + + +elif [ "$userOption" == "-mas" ] || [ "$userOption" == "--modaccstatus" ]; then #this is for locking/unlocking the user account. + + read -p "Enter username that you wanted to Lock/Unlock: " usernameByUser + + is_user_exists "$usernameByUser" + + if [ $? -eq 0 ]; then + echo "Enter your choice 1 or 2: " + echo "choose 1 to Lock the user account" + echo "choose 2 to unlock the user account" + read accountStatusByUser + if [ $accountStatusByUser == 1 ]; then + usermod -L $usernameByUser #-L option is to lock the useraccount with usermod command. + echo "user account $usernameByUser is locked successfully !" + elif [ $accountStatusByUser == 2 ]; then + usermod -U $usernameByUser #-U option is to unlock the useraccount with usermod command. + echo "user account $usernameByUser is unlocked successfully !" + else + echo "Please enter the valid option !" + + #To view the user account status whether it is locked or not we can use: passwd -S "$username" + fi + else + echo "user $usernameByUser is not existed, so please choose an existed user to Lock/Unlock !" + fi + +else #if user enters any different option prompting the user to provide correct option. + echo "Invalid option, Please enter the correct user option!" +fi + + + diff --git a/Self-solutions/Day_3/day3_solution_practice.sh b/Self-solutions/Day_3/day3_solution_practice.sh new file mode 100644 index 0000000..76b2aea --- /dev/null +++ b/Self-solutions/Day_3/day3_solution_practice.sh @@ -0,0 +1,837 @@ +#!/bin/bash +#set -x + +##################################################################### +# Script Name: day_3_challange_solution.sh +# Author: Salwad Basha Shaik +# Date: August 2, 2023 +# Description: This script contains solution for Day 3 User Account Management as part of BashBlaze: 7 Days of Bash Scripting Challenge. +# Usage: ./day_3__challange_solution.sh +# Email: salvathshaik786143@gmail.com +# LinkedIn: https://www.linkedin.com/in/salwad-basha-shaik/ +# Github: https://github.com/salvathshaik/ +##################################################################### + +######################################## Day-3 Challenge: User Account Management ######################################### + +#In this challenge, you will create a bash script that provides options for managing user accounts on the system. The script should allow users to perform various user account-related tasks based on command-line arguments. + +###########Part 1: Account Creation +#Implement an option -c or --create that allows the script to create a new user account. The script should prompt the user to enter the new username and password. + +#Ensure that the script checks whether the username is available before creating the account. If the username already exists, display an appropriate message and exit gracefully. + +#After creating the account, display a success message with the newly created username. + + +#########Part 2: Account Deletion +#Implement an option -d or --delete that allows the script to delete an existing user account. The script should prompt the user to enter the username of the account to be deleted. + +#Ensure that the script checks whether the username exists before attempting to delete the account. If the username does not exist, display an appropriate message and exit gracefully. + +#After successfully deleting the account, display a confirmation message with the deleted username. + + +#########Part 3: Password Reset +#Implement an option -r or --reset that allows the script to reset the password of an existing user account. The script should prompt the user to enter the username and the new password. + +#Ensure that the script checks whether the username exists before attempting to reset the password. If the username does not exist, display an appropriate message and exit gracefully. + +#After resetting the password, display a success message with the username and the updated password. + + +########Part 4: List User Accounts +#Implement an option -l or --list that allows the script to list all user accounts on the system. The script should display the usernames and their corresponding user IDs (UID). + + +#######Part 5: Help and Usage Information +#Implement an option -h or --help that displays usage information and the available command-line options for the script. + + +#######Bonus Points (Optional) +#If you want to challenge yourself further, you can add additional features to the script, such as: + +#Displaying more detailed information about user accounts (e.g., home directory, shell, etc.). +#Allowing the modification of user account properties (e.g., username, user ID, etc.). +#Remember to handle errors gracefully, provide appropriate user prompts, and add comments to explain the logic and purpose of each part of the script. + +#Created function to list out the User Options to run the script. +displayUserOptions() { + +echo +echo "Usage: ./day3_challenge_solution.py [OPTIONS]" +echo "Options:" +echo " -c, --create Create a new user account" +echo " -d, --delete Delete an existing user account" +echo " -r, --reset Reset password for an existing user account" +echo " -l, --list List all user accounts on the system" +echo " -h, --help Display this help and exit." +echo +echo "For Bonus features please use below options" +echo " -ui, --userinfo Display more information about an existed user account" +echo " -mu, --modusername Modify username for an existing user account" +echo " -muid, --moduserid Modify user ID for an existing user account" +echo " -mh, --modhome Modify home directory for an existing user account " +echo " -ms, --modshell Modify default shell for an existing user account" +echo +echo "############## Below options are for the future implementation ##############################" +echo " -mg, --modgroup Modify group for an existing user account " +echo " -mpa, --modpassage Modify password expiration date for an existing user account" +echo " -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account" +echo + +} + +#Created the function to check if user is already existed or not in our system. +is_user_exists() { + userName=$1 #we are taking function argument that passess while calling the function. here $1 is for user provided username input. + + if grep -q "^$userName:" /etc/passwd; then #checking if user already present or not using + #grep command checks if the specifie username that starts with $username is present in /etc/passwd output or #not + #-q option with grep will hide the output of the grep command + + return 0 #returning 0 if username is present otherwise sending 1. + else + return 1 + fi + +} + +displayUserOptions #calling this function to dispay the user option at the time of script runs. + +userOption=$1 #taking the command line 1st argument that pass while running the script and assigning to this variable. + +if [ "$userOption" == "-c" ] || [ "$userOption" == "--create" ]; then #putting two conditions to check -c OR --create user option to create the user. + + + read -p "Enter username to create the user account: " usernameByUser #taking username input from the user to create the user + is_user_exists "$usernameByUser" #passing the user provided username to the is_user_exists function as a command line argument. + + if [ $? -eq 0 ]; then #here $? - checks the previous command output and get the output here and i am comparing it with 0 means user exists. + echo "user $usernameByUser already existed, so please create the user with different username!" + exit 0 #existing from the script with safe command exit 0 with successful run if user exists. + fi + read -p "Enter password to create the account: " passwordByUser + sudo useradd "$usernameByUser" #using useradd command with sudo permission to create the user + echo "$usernameByUser:$passwordByUser" | chpasswd #assigning the user provided password to created user using echo to pass the output to chpasswd. + echo "user account $usernameByUser has been created successfully!" + +elif [ "$userOption" == "-d" ] || [ "$userOption" == "--delete" ]; then + read -p "Enter username to delete the user account: " usernameByUser + + is_user_exists "$usernameByUser" + + if [ $? -eq 0 ]; then + sudo userdel "$usernameByUser" #deleting the user if user is present in our system. + echo "user account $usernameByUser has been deleted successfully!" + else + echo "user $usernameByUser is not existed, so please choose a existed user to delete!" + + fi +elif [ "$userOption" == "-r" ] || [ "$userOption" == "--reset" ]; then + read -p "Enter username to reset the user account password: " usernameByUser + + is_user_exists "$usernameByUser" + + if [ $? -eq 0 ]; then + echo "please enter a new password for $usernameByUser: " + read -s newUserPasswordByUser #read with -s option is to take the password by hiding the password to user while he enters. + echo "$usernameByUser:$newUserPasswordByUser" | chpasswd #same as assiging the password but also can useful to reset the new password. + echo "user account $usernameByUser reset password has completed successfully!" + else + echo "user $usernameByUser is not existed, so please choose a existed user to reset the password!" + + fi + +elif [ "$userOption" == "-l" ] || [ "$userOption" == "--list" ]; then + + echo "Username UID GID" #printing the username UID(User ID) and GID(group ID) + echo "---------------------" + while IFS=: read -r username _ uid gid _; do #here IFS is a field seperator which seperates the all the lines output of /etc/passwd with : semicolon + echo "$username $uid $gid" # that's why I have put = and : with IFS means IFS=: and after seperating with semicolon i have read the + done < /etc/passwd #username with $1 first argument , assigning $2 argument with dummy variable as we don't need this for now + #$2 argument is password basically and $3 and $4 arguments are UID and GID and leaving remaining arguments + #with _ dummy variable till end and we are iterating till last line so using while loop to iterate and + #/etc/passwd contains all the usernames with details. + + + #we can also implement this with other approach as below + # Using awk to print the username (first field) and UID (third field) + #awk -F: '{print "Username:", $1, "UID:", $3}' /etc/passwd + #here we use awk with print to display the output to terminal +elif [ "$userOption" == "-h" ] || [ "$userOption" == "--help" ]; then + displayUserOptions #displaying the user options for help option. + + +#From here is for the bonus learning +elif [ "$userOption" == "-ui" ] || [ "$userOption" == "--userinfo" ]; then + + read -p "Enter username to know more information about the user account: " usernameByUser + + is_user_exists "$usernameByUser" + + if [ $? -eq 0 ]; then + sudo grep "$usernameByUser" /etc/passwd | awk -F: '{print "\n Username: ", $1"\n", "UID:", $3"\n", "Home directory:", $6"\n", "Default shell:", $7"\n"}' + #the above command will print out the Username, UID, Home directory, Default shell details for specific user. + #here we are using grep to find the username in the /etc/passwd file this will return whole line of output with : semicolon + #passing the output via | pipe symbol to awk command and here we are splitting line of output with : semicolon using F: + #using print to display the output to the terminal + else + echo "user $usernameByUser is not existed, so please choose an existed user to display more information about the user!" + + fi + + +elif [ "$userOption" == "-mu" ] || [ "$userOption" == "--modusername" ]; then #this is for modification of username + + read -p "Enter username that you wanted to modify it's username: " oldUsernameByUser + + is_user_exists "$oldUsernameByUser" + + if [ $? -eq 0 ]; then + read -p "Enter new username that you wanted to modify for user $oldUsernameByUser: " newUsernameByUser #taking new username as a input + sudo usermod -l "$newUsernameByUser" "$oldUsernameByUser" #using -l option with usermod to change the username + echo "Successfully Updated the username from $oldUsernameByUser to $newUsernameByUser! " + else + echo "user $usernameByUser is not existed, so please choose an existed user to modify it's username!" + fi + + +elif [ "$userOption" == "-muid" ] || [ "$userOption" == "--moduserid" ]; then #this is for modification of userID of an user + + read -p "Enter username that you wanted to modify it's user ID(UUID): " usernameByUser + + is_user_exists "$usernameByUser" + + if [ $? -eq 0 ]; then + oldUserID=$(id -u "$usernameByUser") #extracting the existing userID using id command with -u it will return the userID of an user + echo "Existed userID for user $usernameByUser is: $oldUserID" + read -p "Enter new userID that you wanted to modify for user $usernameByUser: " newUserIdByUser #taking new userID input + sudo usermod -u "$newUserIdByUser" "$usernameByUser" #using -u option with usermod command to modify it's userID + echo "Successfully Updated the userID for user $usernameByUser from $oldUserID to $newUserIdByUser ! " + else + echo "user $usernameByUser is not existed, so please choose an existed user to modify it's user ID !" + fi + + +elif [ "$userOption" == "-mh" ] || [ "$userOption" == "--modhome" ]; then #this is for modification of default home directory of an user + + read -p "Enter username that you wanted to modify it's default home directory: " usernameByUser + + is_user_exists "$usernameByUser" + + if [ $? -eq 0 ]; then + oldHomeDirectory=$(grep "^$usernameByUser" /etc/passwd | awk -F: '{print $6}') ##extracting the existing home directory with the help of + #grep to search the username in the /etc/passwd file and + #pass the output to awk command and given -F: for splitting + #with semicolon and using print with $6 6th argument to throw + #the default home directory as an output and assigning to varaible. + + echo "Default user home directory for user $usernameByUser is: $oldHomeDirectory" + read -p "Enter new user home directory that you wanted to modify for user $usernameByUser: " newUserHomeDirByUser + sudo usermod -d "$newUserHomeDirByUser" "$usernameByUser" # using -d option with usermod command to modify the default home directory. + echo "Successfully Updated the home directory for user $usernameByUser from $oldHomeDirectory to $newUserHomeDirByUser ! " + else + echo "user $usernameByUser is not existed, so please choose an existed user to modify it's user default home directory !" + fi + + +elif [ "$userOption" == "-ms" ] || [ "$userOption" == "--modshell" ]; then ##this is for modification of default shell of an user + + read -p "Enter username that you wanted to modify it's default shell: " usernameByUser + + is_user_exists "$usernameByUser" + + if [ $? -eq 0 ]; then + oldShell=$(grep "^$usernameByUser" /etc/passwd | awk -F: '{print $7}') #extracting the existing home directory with the help of + #grep to search the username in the /etc/passwd file and + #pass the output to awk command and given -F: for splitting + #with semicolon and using print with $7 7th argument to throw + #the default shell path as an output and assigning to varaible. + echo "Default Shell for user $usernameByUser is: $oldShell" + read -p "Enter new shell path that you wanted to modify for user $usernameByUser: " newShell + sudo usermod -s "$newShell" "$usernameByUser" + echo "Successfully Updated the new Shel for user $usernameByUser from $oldShell to $newShell ! " + else + echo "user $usernameByUser is not existed, so please choose an existed user to modify it's user default shell !" + fi + + + +else #if user enters any different option prompting the user to provide correct option. + echo "Invalid option, Please enter the correct user option!" +fi + +##############################################Future implementation plan for more user modification############################### +#pla-1 +#input the group name(s) and add the user to the group. +#usermod -G sudo,ftp username + +#plan-2 +#input the date as same as format(2023-12-31) to set password expiration prefereably 90days and it will automatically send warning before expring the password in 7days using -w 7 as below. +#usermod -e 2023-12-31 -w 7 username + +#plan-3 +#take input option to (lock use -L) and (-U for unlock) the user account +#usermod -L username + +################################################################################################################### + + + + +#########################practice################# + +#practice-1 +sudo useradd username +sudo passwd username + + +#practice-2 +#practicing to provide a customized home directory, shell, or other settings for a user while creating or after creating the user, +#To specify a custom home directory, use the -d or --home option: +sudo useradd -d /path/to/custom_home_dir username +#To set a custom default shell, use the -s or --shell option: +sudo useradd -s /path/to/custom_shell username +#After Creating the User: +#If you have already created the user and want to modify their settings, with various options: +#To change the user's home directory, use the -d or --home option: +sudo usermod -d /path/to/custom_home_dir username +#To change the user's default shell, use the -s or --shell option: +sudo usermod -s /path/to/custom_shell username +#Provide Custom Configuration Files: +#can also provide custom configuration files for the user in their home directory. For example, you can create a .bashrc file in the user's home directory to customize their bash shell behavior. + + +#practice-3 +#practicing to view various user account details in a Unix-like operating system using different commands. +#id: This command displays user and group information for the current user or a specified user. +id # Display information for the current user +id username # Display information for the specified username + +whoami: #This command prints the username of the current user. + +finger: #The finger command provides information about a user's login name, real name, terminal, login time, idle time, and more. but we need to install this tool before use. + +cat /etc/passwd: #This command shows the user account details stored in the /etc/passwd file, including the username, user ID (UID), group ID (GID), home directory, and default shell. + +getent passwd: #This command retrieves user account details from the system database. + +grep: #You can use grep to filter specific user details from /etc/passwd or other files. + +grep username /etc/passwd # Display details for the specified username +cat /etc/passwd | grep shell # Display users with a specific shell + +ls -l /home: #This command shows the list of user home directories and their permissions. + +cat /etc/shells: #This command displays the available shells on the system. + + + +#practice-4 +#practicing logical AND (&&) and logical OR (||) operators to perform conditional operations based on the success or failure of commands. These operators allow you to chain multiple commands together and control the flow of execution. + +#Logical AND (&&): +#The && operator is used to execute the next command only if the previous command succeeds (returns an exit status of 0). +ls /path/to/directory && echo "Directory listing successful" + +#Logical OR (||): +#The || operator is used to execute the next command only if the previous command fails (returns a non-zero exit status). +rm /path/to/file || echo "File not found" +#command1 && command2 || command3 + + +#use the logical AND (&&) and logical OR (||) operators within an if statement to perform conditional checks based on the success or failure of commands. +if command1 && command2 +then + # Code block to execute if both command1 and command2 succeed +elif command3 || command4 +then + # Code block to execute if command3 succeeds or command4 fails +else + # Code block to execute if all commands fail +fi + +if ls /path/to/directory && grep "pattern" /path/to/file +then + echo "Both commands succeeded." +elif grep "pattern1" /path/to/file || grep "pattern2" /path/to/file +then + echo "At least one of the grep commands succeeded." +else + echo "Both commands failed." +fi + +#!/bin/bash + +file="example.txt" + +# Check if the file exists and is readable +if [ -r "$file" ] && [ -f "$file" ] +then + echo "The file exists and is readable." +else + echo "The file does not exist or is not readable." +fi + + +#practice-5 +# find out if specific user present or not before deleting the user in shell scripting +#!/bin/bash + +# Replace "username" with the username you want to check +username="testuser" + +# Check if the user exists using the getent command and grep +if getent passwd | grep -q "^$username:"; then + echo "User $username exists. Deleting the user..." + + # Add your code here to delete the user, e.g., using the userdel command + # For example: + # userdel "$username" + + echo "User $username has been deleted." +else + echo "User $username does not exist." +fi + + + +#practice-6 +#Using grep to search for the user in /etc/passwd file: +username="someuser" + +if grep -q "^$username:" /etc/passwd; then + echo "User $username exists." +else + echo "User $username does not exist." +fi + + +#practice-7 +#practicing functions +# Function definition with arguments +add_numbers() { + num1=$1 + num2=$2 + sum=$((num1 + num2)) + echo "The sum of $num1 and $num2 is: $sum" +} + +# Function call with arguments +add_numbers 10 20 + +#exaple2 +# Function definition with arguments +add_numbers() { + num1=$1 + num2=$2 + sum=$((num1 + num2)) + + # Set the sum as the exit status + exit $sum +} + +# Function call with arguments +add_numbers 10 20 + +# Access the exit status and print the result +result=$? +echo "The sum is: $result" + +#note: we cannot return the non-integer values from function + +#example3 +# Function definition to check if a number is even +is_even() { + num=$1 + if (( num % 2 == 0 )); then + return 0 # Exit status 0 means the number is even + else + return 1 # Exit status 1 means the number is not even + fi +} + +# Function call within an if statement +number=10 +if is_even "$number"; then + echo "$number is even." +else + echo "$number is not even." +fi + + + +#for safe exit use exit 0 +#exit [status] +#status: The exit status that will be returned to the calling process. By convention, an exit status of 0 indicates success, and any non-zero value indicates an error or failure. +#!/bin/bash + +# Your script commands here... + +# Some error occurred, exit the script with a non-zero status +exit 1 + + + + +#practice-8 +#practicing To reset the password for a user in a shell script, you can use the passwd command along with some echo statements to provide the new password. +#!/bin/bash + +# Function to reset password for a user +reset_password() { + local username="$1" + + # Check if the user exists + if id "$username" &>/dev/null; then + echo "Resetting password for user: $username" + echo "Enter the new password for $username:" + read -s new_password + echo "$username:$new_password" | chpasswd + echo "Password reset successfully." + else + echo "User $username does not exist." + fi +} + +# Call the function and pass the username as an argument +reset_password "your_username" + + + + + +#practice-9 +#To display all the usernames and their associated user IDs (UIDs) and group IDs (GIDs) in a shell script, you can use the cut command along with the /etc/passwd file. The /etc/passwd file contains information about all the users on the system +#!/bin/bash + +# Function to display all user information +display_all_users_info() { + echo "Username UID GID" + echo "---------------------" + while IFS=: read -r username _ uid gid _; do + echo "$username $uid $gid" + done < /etc/passwd +} + +# Call the function to display all user information +display_all_users_info + +#The -r option with the read command is used to prevent backslashes \ from being interpreted as escape characters. When reading input from a file, using the -r option ensures that backslashes are treated as regular characters and not escape characters. + +#how IFS=: works and each its = and ; +# shell scripting, IFS stands for "Internal Field Separator." It is a special environment variable that defines the delimiter used to split a line of text into fields when using commands like read or for loops. + +#By default, the value of IFS is set to whitespace characters (space, tab, and newline). However, you can change its value to a different character or a string of characters to split input lines based on that specific separator. + +#In the example you provided, IFS=:, the = sign is used to set the value of IFS, and : is the delimiter that will be used to split the input lines into fields. + +#while IFS=: read -r username _ _ uid _; do: This is a while loop that reads each line from the users.txt file, splits it into fields using : as the delimiter (because of the IFS=: setting), and assigns those fields to the variables username, uid, and two dummy variables _. The dummy variables _ are used to skip the other fields that are not needed. + +#practice-10 +#to display all the username and its IDs in shell script with awk -F: optin +#!/bin/bash + +# Assuming the user data is stored in a file called users.txt +# The format is: username:password:UID:GID:gecos:home:shell + +# Using awk to print the username (first field) and UID (third field) +awk -F: '{print "Username:", $1, "UID:", $3}' users.txt +#we use awk with the -F option to specify that the field separator is : (colon). Then, we use $1 and $3 to refer to the first and third fields, respectively, which correspond to the username and UID in each line of the users.txt file. +#The print statement in awk is used to print text or data to the output. + +#practice-11 +#function that takes a string as a parameter +#!/bin/bash + +# Define a function that takes a string as a parameter +print_string() { + local input_string=$1 + echo "The input string is: $input_string" +} + +# Call the function and pass a string as an argument +my_string="Hello, this is a sample string." +print_string "$my_string" + + +#practice-12 +#function with passing the string and storing the return value and using in if statement +#!/bin/bash + +# Define a function that takes a string as a parameter +check_string() { + local input_string=$1 + + # Check if the string is empty + if [ -z "$input_string" ]; then + return 1 + else + return 0 + fi +} + +# Call the function and pass a string as an argument +my_string="Hello, this is a sample string." +check_string "$my_string" + +# Check the return value of the function in the if statement +if [ $? -eq 0 ]; then + echo "The string is not empty." +else + echo "The string is empty." +fi + + +#practice-13 +#o add a new user and set a password in a shell script, you can use the useradd and passwd commands. +#!/bin/bash + +# Function to add a new user and set the password +add_user_with_password() { + local username=$1 + local password=$2 + + # Check if the user already exists + if id "$username" &>/dev/null; then + echo "User '$username' already exists." + else + # Add the new user + useradd "$username" + + # Set the password for the new user + echo "$username:$password" | chpasswd + + echo "User '$username' added with the provided password." + fi +} + +# Call the function and pass the username and password as arguments +new_username="newuser" +new_password="mypassword" +add_user_with_password "$new_username" "$new_password" + + +#practice-14 +#To add a new user and set a password in a shell script, you can use the useradd and passwd commands. +#!/bin/bash + +# Define the username and password +new_username="newuser" +new_password="mypassword" + +# Check if the user already exists +if id "$new_username" &>/dev/null; then + echo "User '$new_username' already exists." +else + # Add the new user + useradd "$new_username" + + # Set the password for the new user + echo "$new_username:$new_password" | chpasswd + + echo "User '$new_username' added with the provided password." +fi + + +#practice-15 +#To modify user account details like UID, username, and home directory in a shell script, you can use the usermod command. +#!/bin/bash + +# Define the old and new usernames +old_username="olduser" +new_username="newuser" + +# Define the new UID +new_uid="1001" + +# Define the new home directory +new_home="/path/to/new/home/directory" + +# Check if the old user exists +if id "$old_username" &>/dev/null; then + # Modify the username + if [ "$old_username" != "$new_username" ]; then + usermod -l "$new_username" "$old_username" + fi + + # Modify the UID + if [ "$(id -u "$old_username")" != "$new_uid" ]; then + usermod -u "$new_uid" "$new_username" + fi + + # Modify the home directory + if [ "$(eval echo ~$old_username)" != "$new_home" ]; then + usermod -d "$new_home" -m "$new_username" + fi + + echo "User details modified successfully." +else + echo "User '$old_username' does not exist." +fi + + + + + +#more modifications for an existed user +#n addition to modifying the username, UID, and home directory, the usermod command can be used to modify various other attributes of a user account. Some common attributes that can be modified with usermod include: + +#Shell: You can change the default shell for the user using the -s option. For example, to change the shell to /bin/bash, use usermod -s /bin/bash username. + +#User's groups: You can add or remove the user from specific groups using the -G option. For example, to add the user to the sudo and ftp groups, use usermod -G sudo,ftp username. + +#Account expiration date: You can set an expiration date for the user account using the -e option. For example, to set the account to expire on a specific date, use usermod -e YYYY-MM-DD username. + +#Account status: You can lock or unlock the user account using the -L (lock) and -U (unlock) options, respectively. For example, to lock the account, use usermod -L username. + +#Password aging: You can modify password aging settings like password expiration and warning days using the -e and -w options. For example, to set the password to expire after 90 days and provide a 7-day warning, use usermod -e 2023-12-31 -w 7 username. + +#User's full name or comment: You can change the user's full name or add a comment using the -c option. For example, to set the full name to "John Doe" and add a comment "DevOps Engineer", use usermod -c "John Doe, DevOps Engineer" username. + +#Disable login: To disable login for a user, you can use the -s /sbin/nologin option. This will prevent the user from logging in with a shell. + + +#note +## Modify the home directory + if [ "$(eval echo ~$old_username)" != "$new_home" ]; then + usermod -d "$new_home" -m "$new_username" + fi + +#what is -d and -m here +#-d: This option is used to change the user's home directory. When -d is followed by a directory path, it will set the new home directory for the user account. + +#-m: This option is used to move the contents of the user's old home directory to the new home directory. It is typically used in conjunction with the -d option to move the home directory when changing the user's home directory. + + +#practice-16 +#get the UID of a user by their username: +#!/bin/bash + +username="your_username_here" + +# Get the UID using the 'id' command +user_id=$(id -u "$username") + +# Print the UID +echo "User ID for $username: $user_id" + + +#practice-17 +#To find out the primary group of a user in shell scripting, +#use the id command along with the -gn option. +#!/bin/bash + +# Replace 'username' with the actual username you want to check +username="username" + +# Get the primary group name of the user +group_name=$(id -gn $username) + +echo "The primary group of $username is: $group_name" +#In the id command, the -gn option is used to display the group name of a user. +#-g: Display the numeric group ID (GID) of the user. +#-n: Display the name of the user or group. + + +#practice-18 +#To check if a group exists before adding a user to it in shell scripting, +#use the grep command to search for the group in the /etc/group file. +#!/bin/bash + +group_name="developers" +user_name="john" + +# Check if the group exists +if grep -q "^$group_name:" /etc/group; then + echo "Group $group_name exists." + # Add the user to the group + usermod -aG "$group_name" "$user_name" + echo "User $user_name added to group $group_name." +else + echo "Group $group_name does not exist." +fi +#In the shell script provided above, the -aG options are used with the usermod command to add a user to a group +#a: This option tells the usermod command to append the user to the specified group(s) without removing them from any other groups. +#-G: This option specifies the list of supplementary groups to which the user should be added. Multiple group names can be provided, separated by commas, to add the user to multiple groups at once. +#In the script, the line usermod -aG "$group_name" "$user_name" is used to add the user specified by $user_name to the group specified by $group_name without affecting their membership in any other groups. + + +#practice-19 +#To check the expiration date of a user account password in shell scripting, +#use the chage command with the -l option. The chage command is used to change user password expiry information, and the -l option displays the current password expiry details for the user. +#!/bin/bash + +# Provide the username whose password expiry information you want to check +username="your_username" + +# Get the password expiry information using chage -l command +password_expiry_info=$(chage -l "$username" 2>/dev/null) + +# Check if the password expiry information is available +if [ -n "$password_expiry_info" ]; then + echo "Password Expiry Information for User: $username" + echo "$password_expiry_info" +else + echo "User $username does not exist or password expiry information is not available." +fi + +#practice-20 +#checking command to set the password expiration for a user: +passwd -x +#ex:passwd -x 30 john +#The passwd command is used to set or change a user's password in Linux. The -x option is used to set the maximum number of days a password can be used before it expires. +#When you run the passwd command with the -x option and a number (e.g., passwd -x 30 john), it means that you are setting the password expiration policy for the user "john" to 30 days. This means that after 30 days, the user "john" will be required to change their password. + + + +#practice-21 +#To display the password expiration date for a user account in Linux, +# use the chage command. The chage command allows you to view and modify the password aging information for a user. To see the password expiration date, +chage -l username +#The chage command in Linux is used to manage user password aging information. It allows you to view and modify password expiration and other related settings for user accounts. When you run the chage command without any options, it displays the current password aging information for the specified user. +#The -l option is used with the chage command to display the password aging information for a user account. + +#When you run chage -l username, it shows the following information for the specified user: +#Last password change date: This is the date when the user's password was last changed. + +#Password expiration date: This is the date when the user's password will expire, and the user will be required to change it. + +#Minimum password age: This is the minimum number of days a password must be used before it can be changed again. + +#Maximum password age: This is the maximum number of days a password can be used before it expires. + +#Password inactive days: This is the number of days after the password has expired before the account is locked. + +#Account expiration date: This is the date when the user account will expire, and the user will no longer be able to log in. + +#Account inactive days: This is the number of days after the account has expired before it is permanently disabled. + +#By using the chage -l command, you can check the password aging settings for a user account and ensure that password policies are properly configured for security purposes. + + + +#practice-22 +#practicing to check if a user account is locked or not in shell scripting by using the passwd command along with the -S option. The passwd -S username command will display the status of the user account, including whether it is locked or not. +#!/bin/bash + +# Replace "username" with the actual username you want to check +username="username" + +# Use passwd -S to check the status of the user account +status=$(passwd -S "$username" | awk '{print $2}') + +# Check if the account is locked +if [ "$status" = "L" ]; then + echo "The account $username is locked." +else + echo "The account $username is not locked." +fi +# use the passwd -S command to get the status of the user account +#The status code "L" indicates that the account is locked, and "P" indicates that the account is active and not locked. + + + + + diff --git a/Self-solutions/Day_3/readme.txt b/Self-solutions/Day_3/readme.txt new file mode 100644 index 0000000..7c346e8 --- /dev/null +++ b/Self-solutions/Day_3/readme.txt @@ -0,0 +1,649 @@ +please run 'day3_challange_solution.sh' + + +sample output for the script day3_challange_solution.sh: + + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Invalid option, Please enter the correct user option! + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh --create + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Enter username to create the user account: user6 +Enter password to create the account: user6 +user account user6 has been created successfully! + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh --create + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Enter username to create the user account: user6 +user user6 already existed, so please create the user with different username! + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh --reset + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Enter username to reset the user account password: user6 +please enter a new password for user6: +user account user6 reset password has completed successfully! + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh --list + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Username UID GID +--------------------- +root 0 0 +daemon 1 1 +bin 2 2 +sys 3 3 +sync 4 65534 +games 5 60 +man 6 12 +lp 7 7 +mail 8 8 +news 9 9 +uucp 10 10 +proxy 13 13 +www-data 33 33 +backup 34 34 +list 38 38 +irc 39 39 +gnats 41 41 +nobody 65534 65534 +systemd-network 100 102 +systemd-resolve 101 103 +messagebus 102 105 +systemd-timesync 103 106 +syslog 104 111 +_apt 105 65534 +tss 106 112 +uuidd 107 113 +tcpdump 108 114 +sshd 109 65534 +pollinate 110 1 +landscape 111 116 +fwupd-refresh 112 117 +ec2-instance-connect 113 65534 +_chrony 114 121 +ubuntu 1000 1000 +lxd 999 100 +devops 1001 1001 user1 1002 1002 +user2 1009 1003 +user3 1010 1010 +user44 1022 1011 +user6 1023 1023 + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh --delete + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Enter username to delete the user account: user6 +user account user6 has been deleted successfully! + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh --delete + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Enter username to delete the user account: user6 +user user6 is not existed, so please choose a existed user to delete! + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh --help + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh -c + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Enter username to create the user account: user7 +Enter password to create the account: user7 +user account user7 has been created successfully! + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh --userinfo + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Enter username to know more information about the user account: user7 + + Username: user7 + UID: 1024 + Home directory: /home/user7 + Default shell: /bin/sh + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh --modusername + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Enter username that you wanted to modify it's username: user7 +Enter new username that you wanted to modify for user user7: user77 +Successfully Updated the username from user7 to user77! + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh --userinfo + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Enter username to know more information about the user account: user7 +user user7 is not existed, so please choose an existed user to display more information about the user! + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh --userinfo + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Enter username to know more information about the user account: user77 + + Username: user77 + UID: 1024 + Home directory: /home/user7 + Default shell: /bin/sh + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh --moduserid + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Enter username that you wanted to modify it's user ID(UUID): user77 +Existed userID for user user77 is: 1024 +Enter new userID that you wanted to modify for user user77: 1025 +Successfully Updated the userID for user user77 from 1024 to 1025 ! + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh --userinfo + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Enter username to know more information about the user account: user77 + + Username: user77 + UID: 1025 + Home directory: /home/user7 + Default shell: /bin/sh + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh --modhome + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Enter username that you wanted to modify it's default home directory: user77 +Default user home directory for user user77 is: /home/user7 +Enter new user home directory that you wanted to modify for user user77: /home/user77 +Successfully Updated the home directory for user user77 from /home/user7 to /home/user77 ! + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh --userinfo + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Enter username to know more information about the user account: user77 + + Username: user77 + UID: 1025 + Home directory: /home/user77 + Default shell: /bin/sh + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh --modshell + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Enter username that you wanted to modify it's default shell: user77 +Default Shell for user user77 is: /bin/sh +Enter new shell path that you wanted to modify for user user77: /bin/bash +Successfully Updated the new Shell for user user77 from /bin/sh to /bin/bash ! + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh --userinfo + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Enter username to know more information about the user account: user77 + + Username: user77 + UID: 1025 + Home directory: /home/user77 + Default shell: /bin/bash + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh --modgroup + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Enter username that you wanted to modify it's group: user77 +Existed group name for user user77 is: user7 +Enter group name that you wanted to modify for user user77: user4 +Successfully Updated the new group for user user77 from user7 to user4 ! + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh --modpassage + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Enter username that you wanted to add a account password expiration date: user77 +Enter how many number of days password will expire for user user77: 120 +passwd: password expiry information changed. +Successfully Updated the password expiry for user user77 ! + +Now the password expiry date information as follows... +Last password change : Aug 02, 2023 +Password expires : Nov 30, 2023 +Password inactive : never +Account expires : never +Minimum number of days between password change : 0 +Maximum number of days between password change : 120 +Number of days of warning before password expires : 7 + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh --modaccstatus + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Enter username that you wanted to Lock/Unlock: user77 +Enter your choice 1 or 2: +choose 1 to Lock the user account +choose 2 to unlock the user account +1 +user account user77 is locked successfully ! + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# passwd -S user77 +user77 L 08/02/2023 0 120 7 -1 + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# ./day3_challenge_solution.sh --modaccstatus + +Usage: ./day3_challenge_solution.py [OPTIONS] +Options: + -c, --create Create a new user account + -d, --delete Delete an existing user account + -r, --reset Reset password for an existing user account + -l, --list List all user accounts on the system + -h, --help Display this help and exit. + +For Bonus features please use below options + -ui, --userinfo Display more information about an existed user account + -mu, --modusername Modify username for an existing user account + -muid, --moduserid Modify user ID for an existing user account + -mh, --modhome Modify home directory for an existing user account + -ms, --modshell Modify default shell for an existing user account + -mg, --modgroup Modify group for an existing user account + -mpa, --modpassage Modify password expiration date for an existing user account + -mas, --modaccstatus Modfiy account status(Lock/Unlock) for an existing user account + +Enter username that you wanted to Lock/Unlock: user77 +Enter your choice 1 or 2: +choose 1 to Lock the user account +choose 2 to unlock the user account +2 +user account user77 is unlocked successfully ! + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_3# passwd -S user77 +user77 P 08/02/2023 0 120 7 -1 + + + diff --git a/Self-solutions/Day_4/Part1README.md b/Self-solutions/Day_4/Part1README.md new file mode 100644 index 0000000..3231f17 --- /dev/null +++ b/Self-solutions/Day_4/Part1README.md @@ -0,0 +1,83 @@ +please run "day4_part1_challlenge_solution.sh" + +sample output for the script day3_challange_solution.sh: + +``` +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_4# ./day4_part1_challenge_solution.sh nginx + +Mentioned process 'nginx' is running in the system !!! +● nginx.service - A high performance web server and a reverse proxy server + Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) + Active: active (running) since Thu 2023-08-03 13:37:51 UTC; 3min 22s ago + Docs: man:nginx(8) + Process: 46948 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS) + Process: 46949 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS) + Main PID: 46950 (nginx) + Tasks: 2 (limit: 1141) + Memory: 2.5M + CPU: 20ms + CGroup: /system.slice/nginx.service + ├─46950 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;" + └─46952 "nginx: worker process" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" + +Aug 03 13:37:51 ip-172-31-91-38 systemd[1]: Starting A high performance web server and a reverse proxy server... +Aug 03 13:37:51 ip-172-31-91-38 systemd[1]: Started A high performance web server and a reverse proxy server. + + + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_4# #stopping manually + + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_4# systemctl stop nginx + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_4# ./day4_part1_challenge_solution.sh nginx + +Mentioned process 'nginx' is not running in the system, Attempting to restart... + +Attempting restart to the process 'nginx' automatically ! +Attempt number: '1' +process 'nginx' is running successfully after restart attempt-'1' !!! + +● nginx.service - A high performance web server and a reverse proxy server + Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) + Active: active (running) since Thu 2023-08-03 13:44:00 UTC; 25ms ago + Docs: man:nginx(8) + Process: 47056 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS) + Process: 47057 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS) + Main PID: 47058 (nginx) + Tasks: 2 (limit: 1141) + Memory: 2.5M + CPU: 22ms + CGroup: /system.slice/nginx.service + ├─47058 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;" + └─47060 "nginx: worker process" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" + +Aug 03 13:44:00 ip-172-31-91-38 systemd[1]: Starting A high performance web server and a reverse proxy server... +Aug 03 13:44:00 ip-172-31-91-38 systemd[1]: Started A high performance web server and a reverse proxy server. + + + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_4# ./day4_part1_challenge_solution.sh dummy-nginx + +Mentioned process 'dummy-nginx' is not running in the system, Attempting to restart... + +Attempting restart to the process 'dummy-nginx' automatically ! +Attempt number: '1' +Failed to start dummy-nginx.service: Unit dummy-nginx.service not found. +Attempt number: '2' +Failed to start dummy-nginx.service: Unit dummy-nginx.service not found. +Attempt number: '3' +Failed to start dummy-nginx.service: Unit dummy-nginx.service not found. +After 3 attempts to restart we could not able to start the process 'dummy-nginx' please try manually ! + +Sending slack notification !!!!!!!!!!! + +ok +Slack notification sent successfully !!! +``` + +#After sending the slack notification below notification we can see. + +![slack-notification](https://github.com/salvathshaik/BashBlaze-7-Days-of-Bash-Scripting-Challenge/assets/39498166/133e4dd7-fb64-44a5-a5b5-24b5808addeb) + + diff --git a/Self-solutions/Day_4/Part2README.md b/Self-solutions/Day_4/Part2README.md new file mode 100644 index 0000000..3a9935b --- /dev/null +++ b/Self-solutions/Day_4/Part2README.md @@ -0,0 +1,163 @@ +please run day4_part2_challenge_solution.sh file. + +sample output of this script as follows + +``` +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_4# ./day4_part2_challenge_solution.sh + +Main Menu + +------ Monitoring Metrics Script ------- + +Choose below options + 1. View System Metrics + 2. Monitor a Specific Service + 3. Exit + +Enter your option: 1 +CPU Usage: 6.20% Mem Usage: 26.00% Disk Usage: 39%% + +Main Menu + +------ Monitoring Metrics Script ------- + +Choose below options + 1. View System Metrics + 2. Monitor a Specific Service + 3. Exit + +Enter your option: 1 + +Showing metrics again in 5 seconds... please wait! + +CPU Usage: 0.00% Mem Usage: 26.00% Disk Usage: 39%% + +Main Menu + +------ Monitoring Metrics Script ------- + +Choose below options + 1. View System Metrics + 2. Monitor a Specific Service + 3. Exit + +Enter your option: 2 +Enter the name of the service to monitor: nginx + +Mentioned process 'nginx' is running in the system !!! +● nginx.service - A high performance web server and a reverse proxy server + Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) + Active: active (running) since Thu 2023-08-03 13:44:00 UTC; 3h 19min ago + Docs: man:nginx(8) + Process: 47056 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS) + Process: 47057 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS) + Main PID: 47058 (nginx) + Tasks: 2 (limit: 1141) + Memory: 2.7M + CPU: 171ms + CGroup: /system.slice/nginx.service + ├─47058 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;" + └─47060 "nginx: worker process" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" + +Aug 03 13:44:00 ip-172-31-91-38 systemd[1]: Starting A high performance web server and a reverse proxy server... +Aug 03 13:44:00 ip-172-31-91-38 systemd[1]: Started A high performance web server and a reverse proxy server. + +Main Menu + +------ Monitoring Metrics Script ------- + +Choose below options + 1. View System Metrics + 2. Monitor a Specific Service + 3. Exit + +Enter your option: 4 +Invalid option '4'. please try again wtih the availiable options. + +Main Menu + +------ Monitoring Metrics Script ------- + +Choose below options + 1. View System Metrics + 2. Monitor a Specific Service + 3. Exit + +Enter your option: 3 + +Exiting .. + + +Stopping the nginx service manually to check this scenario + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_4# systemctl stop nginx + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_4# ./day4_part2_challenge_solution.sh + +Main Menu + +------ Monitoring Metrics Script ------- + +Choose below options + 1. View System Metrics + 2. Monitor a Specific Service + 3. Exit + +Enter your option: 2 +Enter the name of the service to monitor: nginx + +Mentioned service 'nginx' is not running in the system... + +Do you want to start nginx? (Y/N): Y +'nginx' service started successfully!! +● nginx.service - A high performance web server and a reverse proxy server + Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) + Active: active (running) since Thu 2023-08-03 17:07:11 UTC; 17ms ago + Docs: man:nginx(8) + Process: 48414 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS) + Process: 48415 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS) + Main PID: 48416 (nginx) + Tasks: 2 (limit: 1141) + Memory: 2.5M + CPU: 22ms + CGroup: /system.slice/nginx.service + ├─48416 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;" + └─48418 "nginx: worker process" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" + +Aug 03 17:07:11 ip-172-31-91-38 systemd[1]: Starting A high performance web server and a reverse proxy server... +Aug 03 17:07:11 ip-172-31-91-38 systemd[1]: Started A high performance web server and a reverse proxy server. + + +Main Menu + +------ Monitoring Metrics Script ------- + +Choose below options + 1. View System Metrics + 2. Monitor a Specific Service + 3. Exit + +Enter your option: 2 +Enter the name of the service to monitor: dummy-nginx-service + +Mentioned service 'dummy-nginx-service' is not running in the system... + +Do you want to start dummy-nginx-service? (Y/N): Y +Failed to start dummy-nginx-service.service: Unit dummy-nginx-service.service not found. +Failed to start the service dummy-nginx-service. Please check the service name and try again!!! + +Main Menu + +------ Monitoring Metrics Script ------- + +Choose below options + 1. View System Metrics + 2. Monitor a Specific Service + 3. Exit + +Enter your option:3 + +Exiting .. + +``` + diff --git a/Self-solutions/Day_4/day4_part1_challenge_solution.sh b/Self-solutions/Day_4/day4_part1_challenge_solution.sh new file mode 100755 index 0000000..2f91682 --- /dev/null +++ b/Self-solutions/Day_4/day4_part1_challenge_solution.sh @@ -0,0 +1,120 @@ +#!/bin/bash + +##################################################################### +# Script Name: day4_part1_challange_solution.sh +# Author: Salwad Basha Shaik +# Date: August 3, 2023 +# Description: This script contains solution for Day 4 part-1 process monitoring and management as part of BashBlaze: 7 Days of Bash Scripting Challenge. +# Usage: ./day4_part1__challange_solution.sh +# Email: salvathshaik786143@gmail.com +# LinkedIn: https://www.linkedin.com/in/salwad-basha-shaik/ +# Github: https://github.com/salvathshaik/ +##################################################################### + + + +########################################### BashBlaze Scripting Challenge - Day 4 ####################################### +#Welcome to the Bash Scripting Challenge - Day 4! This challenge is designed to test your Bash scripting skills and problem-solving abilities in the context of process monitoring and management. + +############################################# Scenario ############### +#You are tasked with writing a Bash script that efficiently monitors a specific process on a Linux system. The script's primary goal is to ensure the process is always running, and if it unexpectedly stops, it should be restarted automatically. + +############################################ Task ############## +#1.Process Selection: +#The script should accept a command-line argument to specify the target process to monitor. For example: ./monitor_process.sh . + +#2.Process Existence Check: +#Implement a function that checks if the specified process is currently running on the system. +#If the process is running, print a message indicating its presence. + +#3.Restarting the Process: +#If the process is not running, implement a function that attempts to restart the process automatically. +#Print a message indicating the attempt to restart the process. +#Ensure the script does not enter an infinite loop while restarting the process. Limit the number of restart attempts. + +#4.Automation: +#Provide instructions on how to schedule the script to run at regular intervals using a cron job or any other appropriate scheduling method. + +#5.Documentation: +#Include clear and concise comments in the script to explain its logic and functionality. +#Write a separate document describing the purpose of the script, how to use it, and any specific considerations. + +#6.Bonus +#Implement a notification mechanism (e.g., email, Slack message) to alert administrators if the process requires manual intervention after a certain number of restart attempts. + +processNameByUser=$1 #taking first command line argument as a process name from user. + +check_if_process_running() { + + process_name=$1 + + if pgrep "$process_name" >/dev/null; then #checking if provided process is running or not + #The >/dev/null part in the shell script is used for redirecting the standard output of a command to the null dev -ice (/dev/null),which is a special device that discards any data written to it. + #If the process is running, pgrep will return a success status (exit code 0), and the output will be discarded. + # If the process is not running, pgrep will return a non-zero status, and the output will be discarded as well. + #The if statement checks the exit status, and based on that, it print the appropriate message without showing any output from the pgrep command itself. + return 0 + else + return 1 + fi +} + + +check_if_process_running "$processNameByUser" #passing the process name to the function + +if [ $? == 0 ]; then #comparing the output of above function usign $? with 0 means process is running. + echo + echo "Mentioned process '$processNameByUser' is running in the system !!!" + sudo systemctl status "$processNameByUser" #displaying the status of process. +else + echo + echo "Mentioned process '$processNameByUser' is not running in the system, Attempting to restart..." + echo + echo "Attempting restart to the process '$processNameByUser' automatically !" + + for ((restartAttempt=1; restartAttempt<=3; restartAttempt++)) #for loop to attempt for 3 times to restart the process + do + + echo "Attempt number: '$restartAttempt'" + + sudo systemctl start "$processNameByUser" #using systemctl command to start the service. + + + #checking if our restart attempt is succsfull or not. + check_if_process_running "$processNameByUser" + if [ $? == 0 ]; then + echo "process '$processNameByUser' is running successfully after restart attempt-'$restartAttempt' !!!" + echo + sudo systemctl status "$processNameByUser" #displaying the status of the process. + break #if success then we break the loop. + fi + + if [ $restartAttempt == 3 ]; then #after 3 attempts also if not restarted showing message. + echo "After 3 attempts to restart we could not able to start the process '$processNameByUser' please try manually !" + echo + echo "Sending slack notification !!!!!!!!!!!" + echo + SLACK_WEBHOOK_URL="https://hooks.slack.com/services/place-your-webhook-url" + SLACK_CHANNEL="#shell-scripting-projects" + SLACK_USERNAME="Process Monitor" + SLACK_ICON_EMOJI=":warning:" + MESSAGE=":warning: Process '$processNameByUser' is not running! So please check and restart manually!" + PAYLOAD="{\"channel\": \"$SLACK_CHANNEL\", \"username\": \"$SLACK_USERNAME\", \"icon_emoji\": \"$SLACK_ICON_EMOJI\", \"text\": \"$MESSAGE\"}" + curl -s -X POST -H "Content-type: application/json" --data "$PAYLOAD" "$SLACK_WEBHOOK_URL" + echo + echo "Slack notification sent successfully !!! " + echo + fi + done +fi + + +################################## Automation ######################### +#############################Improvised and automated this script using crontab like below as an advancement. +#I have used crontab to schedule the backup script to run for every 30 minutes. +#opened the crontab configuration by running : crontab -e and then you can run crontab -l to see the scheduled configurations. +#and added the following line at the end of the crontab file: */30 * * * * /root/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_4/day4_part1__challange_solution.sh >> /root/backup_log.log 2>&1 + #the >> operator appends the output (both standard output and standard error) of the cron job to the specified log file (backup_log.log). The 2>&1 part ensures that both standard output (1) and standard error (2) are redirected to the log file. + + + diff --git a/Self-solutions/Day_4/day4_part1_solution_practice.sh b/Self-solutions/Day_4/day4_part1_solution_practice.sh new file mode 100644 index 0000000..9081457 --- /dev/null +++ b/Self-solutions/Day_4/day4_part1_solution_practice.sh @@ -0,0 +1,360 @@ +#!/bin/bash + +##################################################################### +# Script Name: day4_part1_challange_solution.sh +# Author: Salwad Basha Shaik +# Date: August 3, 2023 +# Description: This script contains solution for Day 4 part-1 process monitoring and management as part of BashBlaze: 7 Days of Bash Scripting Challenge. +# Usage: ./day4_part1__challange_solution.sh +# Email: salvathshaik786143@gmail.com +# LinkedIn: https://www.linkedin.com/in/salwad-basha-shaik/ +# Github: https://github.com/salvathshaik/ +##################################################################### + + + +########################################### BashBlaze Scripting Challenge - Day 4 ####################################### +#Welcome to the Bash Scripting Challenge - Day 4! This challenge is designed to test your Bash scripting skills and problem-solving abilities in the context of process monitoring and management. + +############################################# Scenario ############### +#You are tasked with writing a Bash script that efficiently monitors a specific process on a Linux system. The script's primary goal is to ensure the process is always running, and if it unexpectedly stops, it should be restarted automatically. + +############################################ Task ############## +#1.Process Selection: +#The script should accept a command-line argument to specify the target process to monitor. For example: ./monitor_process.sh . + +#2.Process Existence Check: +#Implement a function that checks if the specified process is currently running on the system. +#If the process is running, print a message indicating its presence. + +#3.Restarting the Process: +#If the process is not running, implement a function that attempts to restart the process automatically. +#Print a message indicating the attempt to restart the process. +#Ensure the script does not enter an infinite loop while restarting the process. Limit the number of restart attempts. + +#4.Automation: +#Provide instructions on how to schedule the script to run at regular intervals using a cron job or any other appropriate scheduling method. + +#5.Documentation: +#Include clear and concise comments in the script to explain its logic and functionality. +#Write a separate document describing the purpose of the script, how to use it, and any specific considerations. + +#6.Bonus +#Implement a notification mechanism (e.g., email, Slack message) to alert administrators if the process requires manual intervention after a certain number of restart attempts. + +processNameByUser=$1 #taking first command line argument as a process name from user. + +check_if_process_running() { + + process_name=$1 + + if pgrep "$process_name" >/dev/null; then #checking if provided process is running or not + #The >/dev/null part in the shell script is used for redirecting the standard output of a command to the null dev -ice (/dev/null),which is a special device that discards any data written to it. + #If the process is running, pgrep will return a success status (exit code 0), and the output will be discarded. + # If the process is not running, pgrep will return a non-zero status, and the output will be discarded as well. + #The if statement checks the exit status, and based on that, it print the appropriate message without showing any output from the pgrep command itself. + return 0 + else + return 1 + fi +} + + +check_if_process_running "$processNameByUser" #passing the process name to the function + +if [ $? == 0 ]; then #comparing the output of above function usign $? with 0 means process is running. + echo + echo "Mentioned process '$processNameByUser' is running in the system !!!" + sudo systemctl status "$processNameByUser" #displaying the status of process. +else + echo + echo "Mentioned process '$processNameByUser' is not running in the system, Attempting to restart..." + echo + echo "Attempting restart to the process '$processNameByUser' automatically !" + + for ((restartAttempt=1; restartAttempt<=3; restartAttempt++)) #for loop to attempt for 3 times to restart the process + do + + echo "Attempt number: '$restartAttempt'" + + sudo systemctl start "$processNameByUser" #using systemctl command to start the service. + + + #checking if our restart attempt is succsfull or not. + check_if_process_running "$processNameByUser" + if [ $? == 0 ]; then + echo "process '$processNameByUser' is running successfully after restart attempt-'$restartAttempt' !!!" + echo + sudo systemctl status "$processNameByUser" #displaying the status of the process. + break #if success then we break the loop. + fi + + if [ $restartAttempt == 3 ]; then #after 3 attempts also if not restarted showing message. + echo "After 3 attempts to restart we could not able to start the process '$processNameByUser' please try manually !" + echo + echo "Sending slack notification !!!!!!!!!!!" + echo + SLACK_WEBHOOK_URL="https://hooks.slack.com/services/place-your-webhook-url" + SLACK_CHANNEL="#shell-scripting-projects" + SLACK_USERNAME="Process Monitor" + SLACK_ICON_EMOJI=":warning:" + MESSAGE=":warning: Process '$processNameByUser' is not running! So please check and restart manually!" + PAYLOAD="{\"channel\": \"$SLACK_CHANNEL\", \"username\": \"$SLACK_USERNAME\", \"icon_emoji\": \"$SLACK_ICON_EMOJI\", \"text\": \"$MESSAGE\"}" + curl -s -X POST -H "Content-type: application/json" --data "$PAYLOAD" "$SLACK_WEBHOOK_URL" + echo + echo "Slack notification sent successfully !!! " + echo + fi + done +fi + + +################################## Automation ######################### +#############################Improvised and automated this script using crontab like below as an advancement. +#I have used crontab to schedule the backup script to run for every 30 minutes. +#opened the crontab configuration by running : crontab -e and then you can run crontab -l to see the scheduled configurations. +#and added the following line at the end of the crontab file: */30 * * * * /root/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_4/day4_part1__challange_solution.sh >> /root/backup_log.log 2>&1 + #the >> operator appends the output (both standard output and standard error) of the cron job to the specified log file (backup_log.log). The 2>&1 part ensures that both standard output (1) and standard error (2) are redirected to the log file. + + +###################### practice #################### + +#practice-1 +#check if a particular process is running in shell scripting +#!/bin/bash + +# Process name to check +process_name="example_process" + +# Check if the process is running +if ps aux | grep -q "[${process_name:0:1}]${process_name:1}"; then + echo "The process '$process_name' is running." +else + echo "The process '$process_name' is not running." +fi +#sing the ps command and then filtering the output. +#we use ps aux to list all running processes and then use grep to search for the process name in the output +#The -q option of grep is used to make it quiet, so it doesn't print anything to the output. If the process is found, the if statement will be true, indicating that the process is running. Otherwise, it will print that the process is not running. + +#[${process_name:0:1}]${process_name:1} +#${process_name:0:1}: This part of the expression extracts the first character of the process_name variable. +#${process_name:1}: This part of the expression extracts all characters of process_name starting from the second character (index 1) to the end of the string. This effectively removes the first character from process_name, leaving only the rest of the characters. + +#checking the output of 'ps aux | grep [s]sh' +#it will print all the output that matchs with ssh but except grep itself due to [s] this bracket. +#ps aux: This command is used to list all running processes on the system. +#|: This is the pipe symbol, which is used to redirect the output of the ps aux command to the grep command. +#grep [s]sh: The grep command is used to search for a pattern in the input. In this case, it is searching for the pattern [s]sh. +#without the brackets, the grep command would normally match itself, resulting in an additional line in the output that includes the grep process. + + +#practice-2 +#check if a particular process is running or not in shell scripting using various commands like pgrep, ps, or pidof. +######Using pgrep: +if pgrep "process_name" >/dev/null; then + echo "Process is running." +else + echo "Process is not running." +fi + +#Using ps: +if ps -C "process_name" &>/dev/null; then + echo "Process is running." +else + echo "Process is not running." +fi + +#Using pidof: +if pidof "process_name" >/dev/null; then + echo "Process is running." +else + echo "Process is not running." +fi + + +# +#>/dev/null : usage +#The >/dev/null part in the shell script is used for redirecting the standard output of a command to the null device (/dev/null), which is a special device that discards any data written to it. + +#>: Redirects the standard output of the command to a file or device. +#/dev/null: A special device in Unix-like systems that discards any data written to it. +if pgrep "process_name" >/dev/null; then + echo "Process is running." +else + echo "Process is not running." +fi + + +#practice-3 +#for loop in shell scritping +# the for loop is used to iterate over a list of items and perform a set of commands for each item in the list. +for item in list +do + # Commands to be executed for each item +done + +#exaple-2 +for fruit in apple orange banana +do + echo "I like $fruit" +done + +#exaple-3 +for file in $(ls *.txt) +do + echo "Processing file: $file" + # Add commands to process the file here +done + + +#example-4 for loop with with break statement + +#he break statement is used within loops (like for or while loops) to prematurely exit the loop. When the break statement is encountered, the loop immediately terminates, and the control of the program moves to the first line of code following the loop. + +for number in 1 2 3 4 5 +do + echo "Processing number $number" + + # Check if the current number is equal to 3 + if [ "$number" -eq 3 ]; then + echo "Found number 3. Exiting loop." + break # Exit the loop when the number is 3 + fi +done + + +#loop 3 times and break + +#!/bin/bash + +# Initialize a counter variable +counter=0 + +# Loop 3 times +for ((i=1; i<=3; i++)) +do + echo "Iteration $i" + + # Increment the counter + ((counter++)) + + # Check if the counter is equal to 3 + if [ $counter -eq 3 ]; then + echo "Reached 3 iterations. Exiting loop." + break # Exit the loop + fi +done + + +#practice-5 +#practicing to send slack notification if process is not running in shell scripting +#To send a Slack notification from a shell script when a certain process is not running, + +#Set Up Incoming Webhook in Slack: +#Go to your Slack workspace. +#Click on your workspace name in the top left corner, then click "Settings & administration" > "Manage apps." +#In the "Apps" section, search for "Incoming Webhooks" and click on it. +#Click "Add to Slack" next to the channel where you want to receive the notifications. +#Follow the prompts to complete the setup. You'll get a webhook URL that you'll use in the shell script. + +#!/bin/bash + +# Function to check if the process is running +check_process() { + if pgrep -x "$1" >/dev/null; then + return 0 # Process is running + else + return 1 # Process is not running + fi +} + +# Replace these variables with your values +SLACK_WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL" +SLACK_CHANNEL="#your-slack-channel" +SLACK_USERNAME="Process Monitor" +SLACK_ICON_EMOJI=":warning:" + +# Process to check (replace "your-process" with the actual process name) +PROCESS_NAME="your-process" + +# Check if the process is not running +if ! check_process "$PROCESS_NAME"; then + # Send Slack notification + MESSAGE=":warning: Process '$PROCESS_NAME' is not running!" + PAYLOAD="{\"channel\": \"$SLACK_CHANNEL\", \"username\": \"$SLACK_USERNAME\", \"icon_emoji\": \"$SLACK_ICON_EMOJI\", \"text\": \"$MESSAGE\"}" + + curl -s -X POST -H "Content-type: application/json" --data "$PAYLOAD" "$SLACK_WEBHOOK_URL" +fi + +#Schedule the Script: +#To regularly check if the process is running and send notifications if it's not, you can schedule the script to run at a specific interval using cron. For example, to run the script every 5 minutes +*/5 * * * * /path/to/check_process.sh + + +#practice-6 +#practicing the switch case in shell scripting +#!/bin/bash + +day="Monday" + +case $day in + Monday) + echo "It's the start of the week." + ;; + Tuesday|Wednesday|Thursday) + echo "It's a weekday." + ;; + Friday) + echo "TGIF! It's Friday." + ;; + Saturday|Sunday) + echo "It's the weekend!" + ;; + *) + echo "Invalid day." + ;; +esac + +#the script checks the value of the variable day and executes different code blocks based on the day of the week. The esac marks the end of the case statement. + + +#exaple-2 +#infinite loop using a while loop with switch cases in shell scripting: +#!/bin/bash + +while true; do + echo "Enter your choice:" + echo "1. Option 1" + echo "2. Option 2" + echo "3. Option 3" + echo "4. Exit" + + read choice + + case $choice in + 1) + echo "You chose Option 1" + # Add your logic for Option 1 here + ;; + 2) + echo "You chose Option 2" + # Add your logic for Option 2 here + ;; + 3) + echo "You chose Option 3" + # Add your logic for Option 3 here + ;; + 4) + echo "Exiting..." + break + ;; + *) + echo "Invalid choice, please try again." + ;; + esac +done + + + + + diff --git a/Self-solutions/Day_4/day4_part2_challenge_solution.sh b/Self-solutions/Day_4/day4_part2_challenge_solution.sh new file mode 100755 index 0000000..03cb809 --- /dev/null +++ b/Self-solutions/Day_4/day4_part2_challenge_solution.sh @@ -0,0 +1,158 @@ +#!/bin/bash + +##################################################################### +# Script Name: day4_part2_challange_solution.sh +# Author: Salwad Basha Shaik +# Date: August 3, 2023 +# Description: This script contains solution for Day 4 part-2 Monitoring Metrics Script with Sleep Mechanism as part of BashBlaze: 7 Days of Bash Scripting Challenge. +# Usage: ./day4_part2__challange_solution.sh +# Email: salvathshaik786143@gmail.com +# LinkedIn: https://www.linkedin.com/in/salwad-basha-shaik/ +# Github: https://github.com/salvathshaik/ +##################################################################### + +#set -x +#################################################### Day-4 part2 Monitoring Metrics Script with Sleep Mechanism ############################# +####################### Challenge Description #################### +#This project aims to create a Bash script that monitors system metrics like CPU usage, memory usage, and disk space usage. The script will provide a user-friendly interface, allow continuous monitoring with a specified sleep interval, and extend its capabilities to monitor specific services like Nginx. + + +#Tasks +#Task 1: Implementing Basic Metrics Monitoring +#Write a Bash script that monitors the CPU usage, memory usage, and disk space usage of the system. The script should display these metrics in a clear and organized manner, allowing users to interpret the data easily. The script should use the top, free, and df commands to fetch the metrics. + +#Task 2: User-Friendly Interface +#Enhance the script by providing a user-friendly interface that allows users to interact with the script through the terminal. Display a simple menu with options to view the metrics and an option to exit the script. + +#Task 3: Continuous Monitoring with Sleep +#Introduce a loop in the script to allow continuous monitoring until the user chooses to exit. After displaying the metrics, add a "sleep" mechanism to pause the monitoring for a specified interval before displaying the metrics again. Allow the user to specify the sleep interval. + +#Task 4: Monitoring a Specific Service (e.g., Nginx) +#Extend the script to monitor a specific service like Nginx. Check if the service is running and display its status. If it is not running, provide an option for the user to start the service. Use the systemctl or appropriate command to check and control the service. + +#Task 5: Allow User to Choose a Different Service +#Modify the script to give the user the option to monitor a different service of their choice. Prompt the user to enter the name of the service they want to monitor, and display its status accordingly. + +#Task 6: Error Handling +#Implement error handling in the script to handle scenarios where commands fail or inputs are invalid. Display meaningful error messages to guide users on what went wrong and how to fix it. + +#Task 7: Documentation +#Add comments within the script to explain the purpose of each function, variable, and section of the code. Provide a clear and concise README file explaining how to use the script, the available options, and the purpose of the script. + +#Remember, the main goal of this challenge is to utilize various monitoring commands, implement a user-friendly interface, and create a script that is easy to understand and use. + +check_if_process_running() { + + process_name=$1 + + if pgrep "$process_name" >/dev/null; then #checking if provided process is running or not + #The >/dev/null part in the shell script is used for redirecting the standard output of a command to the null dev -ice (/dev/null),which is a special device that discards any data written to it. + #If the process is running, pgrep will return a success status (exit code 0), and the output will be discarded. + # If the process is not running, pgrep will return a non-zero status, and the output will be discarded as well. + #The if statement checks the exit status, and based on that, it print the appropriate message without showing any output from the pgrep command itself. + return 0 + else + return 1 + fi +} + + +while true; do + echo + echo "Main Menu" + echo + echo "------ Monitoring Metrics Script -------" + echo + echo "Choose below options" + echo " 1. View System Metrics " + echo " 2. Monitor a Specific Service " + echo " 3. Exit" + echo + + read -p "Enter your option: " userOption + + case $userOption in + 1) + + if [ "$reEnterTheMetrix" == 1 ]; then + echo + echo "Showing metrics again in 5 seconds... please wait! " + echo + sleep 5 #implementing the sleep mechanism if user wants to see metric details from second timewe will show the metrics detaisl with hiafter 5 seonds. + reEnterTheMetrix=0 + + fi + cpu_metric_usage=$( top -bn1 | grep 'Cpu(s)' | awk '{print $2 + $4}' ) #the awk command is used to extract specific columns from the output of the top command. and '{print $2 + $4}': will sum the second %CPU column from the output of the top command and $4: Represents the fourth column of the input (in this case, the %us column, which represents the percentage of CPU used by user processes). + + cpu_metric_usage_percentage=$( printf "%.2f" "$cpu_metric_usage" ) #displaying only 2 decimal values. + + memory_metric_total=$( free | grep 'Mem:' | awk '{print $2}' ) #this free command will give us the memory usage details. and here we are taking 2nd and 3rd argument of free command output and calculating the percentage. + memory_metric_total_used=$( free | grep 'Mem:' | awk '{print $3}' ) + memory_metric_usage_percentage=$(echo "scale=2; $memory_metric_total_used / $memory_metric_total * 100" | bc) + #bc: basic calculator operation and to store only two decimal value as a output we are using scal=2. + + disk_usage_metric=$( df -h / | awk 'NR == 2 {print $5}' ) #here NR===2 means taking the second line from df -h / disk space outpur and extracting 5th argument as a disk usage metric. + + echo "CPU Usage: $cpu_metric_usage_percentage% Mem Usage: $memory_metric_usage_percentage% Disk Usage: $disk_usage_metric%" + + reEnterTheMetrix=1 + + ;; + + + 2) + + read -p "Enter the name of the service to monitor: " serviceNameByUser #taking service nameinput to monitor. + check_if_process_running "$serviceNameByUser" #passing the service name to the function. + + if [ $? == 0 ]; then #comparing the output of above function usign $? with 0 means service is running. + echo + echo "Mentioned process '$serviceNameByUser' is running in the system !!!" + sudo systemctl status "$serviceNameByUser" #displaying the status of process. + + else + echo + echo "Mentioned service '$serviceNameByUser' is not running in the system..." + echo + + read -p "Do you want to start $serviceNameByUser? (Y/N): " userOptionToStart + + if [ "$userOptionToStart" == "Y" ]; then + sudo systemctl start "$serviceNameByUser" #using systemctl command to start the service. + + check_if_process_running $serviceNameByUser + if [ $? == 0 ]; then + echo "'$serviceNameByUser' service started successfully!! " + sudo systemctl status $serviceNameByUser + echo + else + echo "Failed to start the service $serviceNameByUser. Please check the service name and try again!!!" + fi + else + echo "We did not try to start the service, Exiting..." + fi + fi + + ;; + + + + 3) + echo + echo "Exiting .." + echo + break + + ;; + + + *) + echo "Invalid option '$userOption'. please try again wtih the availiable options." + + ;; + esac + +done + + + diff --git a/Self-solutions/Day_4/day4_part2_solution_practice.sh b/Self-solutions/Day_4/day4_part2_solution_practice.sh new file mode 100644 index 0000000..889a715 --- /dev/null +++ b/Self-solutions/Day_4/day4_part2_solution_practice.sh @@ -0,0 +1,278 @@ +#!/bin/bash + +##################################################################### +# Script Name: day4_part2_challange_solution.sh +# Author: Salwad Basha Shaik +# Date: August 3, 2023 +# Description: This script contains solution for Day 4 part-2 Monitoring Metrics Script with Sleep Mechanism as part of BashBlaze: 7 Days of Bash Scripting Challenge. +# Usage: ./day4_part2__challange_solution.sh +# Email: salvathshaik786143@gmail.com +# LinkedIn: https://www.linkedin.com/in/salwad-basha-shaik/ +# Github: https://github.com/salvathshaik/ +##################################################################### + +#set -x +#################################################### Day-4 part2 Monitoring Metrics Script with Sleep Mechanism ############################# +####################### Challenge Description #################### +#This project aims to create a Bash script that monitors system metrics like CPU usage, memory usage, and disk space usage. The script will provide a user-friendly interface, allow continuous monitoring with a specified sleep interval, and extend its capabilities to monitor specific services like Nginx. + + +#Tasks +#Task 1: Implementing Basic Metrics Monitoring +#Write a Bash script that monitors the CPU usage, memory usage, and disk space usage of the system. The script should display these metrics in a clear and organized manner, allowing users to interpret the data easily. The script should use the top, free, and df commands to fetch the metrics. + +#Task 2: User-Friendly Interface +#Enhance the script by providing a user-friendly interface that allows users to interact with the script through the terminal. Display a simple menu with options to view the metrics and an option to exit the script. + +#Task 3: Continuous Monitoring with Sleep +#Introduce a loop in the script to allow continuous monitoring until the user chooses to exit. After displaying the metrics, add a "sleep" mechanism to pause the monitoring for a specified interval before displaying the metrics again. Allow the user to specify the sleep interval. + +#Task 4: Monitoring a Specific Service (e.g., Nginx) +#Extend the script to monitor a specific service like Nginx. Check if the service is running and display its status. If it is not running, provide an option for the user to start the service. Use the systemctl or appropriate command to check and control the service. + +#Task 5: Allow User to Choose a Different Service +#Modify the script to give the user the option to monitor a different service of their choice. Prompt the user to enter the name of the service they want to monitor, and display its status accordingly. + +#Task 6: Error Handling +#Implement error handling in the script to handle scenarios where commands fail or inputs are invalid. Display meaningful error messages to guide users on what went wrong and how to fix it. + +#Task 7: Documentation +#Add comments within the script to explain the purpose of each function, variable, and section of the code. Provide a clear and concise README file explaining how to use the script, the available options, and the purpose of the script. + +#Remember, the main goal of this challenge is to utilize various monitoring commands, implement a user-friendly interface, and create a script that is easy to understand and use. + +check_if_process_running() { + + process_name=$1 + + if pgrep "$process_name" >/dev/null; then #checking if provided process is running or not + #The >/dev/null part in the shell script is used for redirecting the standard output of a command to the null dev -ice (/dev/null),which is a special device that discards any data written to it. + #If the process is running, pgrep will return a success status (exit code 0), and the output will be discarded. + # If the process is not running, pgrep will return a non-zero status, and the output will be discarded as well. + #The if statement checks the exit status, and based on that, it print the appropriate message without showing any output from the pgrep command itself. + return 0 + else + return 1 + fi +} + + +while true; do + echo + echo "Main Menu" + echo + echo "------ Monitoring Metrics Script -------" + echo + echo "Choose below options" + echo " 1. View System Metrics " + echo " 2. Monitor a Specific Service " + echo " 3. Exit" + echo + + read -p "Enter your option: " userOption + + case $userOption in + 1) + + if [ "$reEnterTheMetrix" == 1 ]; then + echo + echo "Showing metrics again in 5 seconds... please wait! " + echo + sleep 5 #implementing the sleep mechanism if user wants to see metric details from second timewe will show the metrics detaisl with hiafter 5 seonds. + reEnterTheMetrix=0 + + fi + cpu_metric_usage=$( top -bn1 | grep 'Cpu(s)' | awk '{print $2 + $4}' ) #the awk command is used to extract specific columns from the output of the top command. and '{print $2 + $4}': will sum the second %CPU column from the output of the top command and $4: Represents the fourth column of the input (in this case, the %us column, which represents the percentage of CPU used by user processes). + + cpu_metric_usage_percentage=$( printf "%.2f" "$cpu_metric_usage" ) #displaying only 2 decimal values. + + memory_metric_total=$( free | grep 'Mem:' | awk '{print $2}' ) #this free command will give us the memory usage details. and here we are taking 2nd and 3rd argument of free command output and calculating the percentage. + memory_metric_total_used=$( free | grep 'Mem:' | awk '{print $3}' ) + memory_metric_usage_percentage=$(echo "scale=2; $memory_metric_total_used / $memory_metric_total * 100" | bc) + #bc: basic calculator operation and to store only two decimal value as a output we are using scal=2. + + disk_usage_metric=$( df -h / | awk 'NR == 2 {print $5}' ) #here NR===2 means taking the second line from df -h / disk space outpur and extracting 5th argument as a disk usage metric. + + echo "CPU Usage: $cpu_metric_usage_percentage% Mem Usage: $memory_metric_usage_percentage% Disk Usage: $disk_usage_metric%" + + reEnterTheMetrix=1 + + ;; + + + 2) + + read -p "Enter the name of the service to monitor: " serviceNameByUser #taking service nameinput to monitor. + check_if_process_running "$serviceNameByUser" #passing the service name to the function. + + if [ $? == 0 ]; then #comparing the output of above function usign $? with 0 means service is running. + echo + echo "Mentioned process '$serviceNameByUser' is running in the system !!!" + sudo systemctl status "$serviceNameByUser" #displaying the status of process. + + else + echo + echo "Mentioned service '$serviceNameByUser' is not running in the system..." + echo + + read -p "Do you want to start $serviceNameByUser? (Y/N): " userOptionToStart + + if [ "$userOptionToStart" == "Y" ]; then + sudo systemctl start "$serviceNameByUser" #using systemctl command to start the service. + + check_if_process_running $serviceNameByUser + if [ $? == 0 ]; then + echo "'$serviceNameByUser' service started successfully!! " + sudo systemctl status $serviceNameByUser + echo + else + echo "Failed to start the service $serviceNameByUser. Please check the service name and try again!!!" + fi + else + echo "We did not try to start the service, Exiting..." + fi + fi + + ;; + + + + 3) + echo + echo "Exiting .." + echo + break + + ;; + + + *) + echo "Invalid option '$userOption'. please try again wtih the availiable options." + + ;; + esac + +done + + +############################################ practice #################### + + +#practice-1 +#practicing To get CPU, memory, and disk usage in shell scripting, you can use various commands and tools available in Linux +######CPU Usage: +#Use the top command with -n1 to get a one-time report of CPU usage: + +top -n1 + +#use the mpstat command to get CPU statistics: +mpstat + + +### Memory Usage: +#Use the free command to get memory usage: + +free -h + +#use the top command to see memory usage along with other statistics: +top + +#### Disk Usage: + +#Use the df command to get disk usage information: +df -h + +#use the du command to get disk usage of specific directories: +du -h /path/to/directory + +#to capture the output of these commands in a shell script +#use command substitution with backticks or $(): +#!/bin/bash + +cpu_usage=$(top -bn1 | grep 'Cpu(s)' | awk '{print $2 + $4}') +memory_usage=$(free -h | grep 'Mem:' | awk '{print $3}') +disk_usage=$(df -h | grep '/dev/sda1' | awk '{print $5}') + +echo "CPU Usage: $cpu_usage" +echo "Memory Usage: $memory_usage" +echo "Disk Usage: $disk_usage" + + +#practice-2 +#practicing to get CPU, memory, and disk usage in percentages in shell scripting, +#!/bin/bash + +# CPU Usage +cpu_usage=$(top -bn1 | grep 'Cpu(s)' | awk '{print $2 + $4}') +cpu_usage_percentage=$(printf "%.2f" "$cpu_usage") + +# Memory Usage +memory_total=$(free | grep 'Mem:' | awk '{print $2}') +memory_used=$(free | grep 'Mem:' | awk '{print $3}') +memory_usage_percentage=$(echo "scale=2; $memory_used / $memory_total * 100" | bc) + +# Disk Usage +disk_usage=$(df -h | grep '/dev/sda1' | awk '{print $5}' | cut -d'%' -f1) + +echo "CPU Usage: $cpu_usage_percentage%" +echo "Memory Usage: $memory_usage_percentage%" +echo "Disk Usage: $disk_usage%" + + + +#explainig awk '{print $2 + $4}' + +#awk: The command itself, which stands for "Aho, Weinberger, and Kernighan." It is a versatile text processing tool commonly used in shell scripting to manipulate and extract data from text files or command output. +#'{print $2 + $4}': This is the awk script enclosed in single quotes. It consists of a single awk action that instructs awk on what to do with each input line. +#it basically sum the 2nd and 4th arugment + +#explaining the line also disk_usage=$(df -h | grep '/dev/sda1' | awk '{print $5}' | cut -d'%' -f1) +#df -h: This command is used to display disk space usage on Linux systems. The -h option stands for "human-readable," which means the output will be in a human-friendly format, displaying sizes in KB, MB, GB, etc., instead of raw blocks. + +#grep '/dev/sda1': The grep command is used to search for a specific pattern or string in the output of the df command. In this case, we are searching for the line that corresponds to the /dev/sda1 partition, which is usually the main system partition. + +#awk '{print $5}': Just like in the previous explanation, awk is used to extract a specific column from the input. In this case, it extracts the fifth column, which represents the "Use%" column in the output of df. The "Use%" column shows the percentage of disk space used. + +#cut -d'%' -f1: The cut command is used to extract a specific portion of each line of text. In this case, we use it to remove the percentage sign (%) from the extracted "Use%" value obtained from the awk command. The -d'%' option specifies that the delimiter is the percentage sign, and -f1 indicates that we want to keep only the first field (before the percentage sign). + +#The final result of this command chain is the disk usage percentage of the /dev/sda1 partition, which is then assigned to the disk_usage variable in the shell script. + + +#exaple-2 +#To find the disk usage of the main system partition, you can modify the command to search for the root file system using the / mount point: +disk_usage=$(df -h / | awk 'NR == 2 {print $5}' | cut -d'%' -f1) +#we use / as the argument to df to specify the root file system. The awk command is used to extract the disk usage percentage from the second line of the df output (the first line contains headers). The cut command is then used to remove the percentage sign (%) from the extracted value. +#basically cut will remove the '%' symbol from the output +#replace / with the appropriate mount point in the df command. + +#awk command, NR == 2 is a pattern that specifies a condition for selecting a specific line from the input +#NR is a built-in variable in awk that represents the current record (i.e., the line number). +#NR == 2 checks if the current line being processed is the second line of the input. +#cut -d'%' -f1: This cut command removes the percentage sign "%" from the disk usage percentage printed by the awk command, leaving only the numeric value. + + +#%.2f means? +#% is the formatting operator that indicates that a format specification follows. +#.2 is the precision specification, which tells printf to display two decimal places after the decimal point. +#f is the format character that specifies the format as a floating-point number. + + +#explaining the $(echo "scale=2; $memory_used / $memory_total * 100" | bc) + +#The scale=2 sets the decimal precision to two decimal places, indicating that the result should have two digits after the decimal point. +#$memory_used: This is a variable containing the amount of used memory. +#$memory_total: This is a variable containing the total amount of memory available. +#| bc: The | (pipe) symbol is used to redirect the output of the echo command to the bc command. bc stands for "basic calculator" and is a command-line calculator that can perform arithmetic operations. + + + +# + + + + + + + + + diff --git a/Self-solutions/Day_4/practice-1.sh b/Self-solutions/Day_4/practice-1.sh new file mode 100755 index 0000000..86b3a23 --- /dev/null +++ b/Self-solutions/Day_4/practice-1.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# Initialize a counter variable +counter=0 + +# Loop 3 times +for ((i=1; i<=3; i++)) +do + echo "Iteration $i" + + # Increment the counter + ((counter++)) + + # Check if the counter is equal to 3 + if [ $counter -eq 3 ]; then + echo "Reached 3 iterations. Exiting loop." + break # Exit the loop + fi +done + diff --git a/Self-solutions/Day_4/readme.txt b/Self-solutions/Day_4/readme.txt new file mode 100644 index 0000000..610f5fe --- /dev/null +++ b/Self-solutions/Day_4/readme.txt @@ -0,0 +1 @@ +please run 'day4_part1_challenge_solution.sh' and day4_part2_challenge_solution.sh files for challenge solutions. diff --git a/Self-solutions/Day_5/LogArchive/log_report-2023-08-04-18-04-18.txt b/Self-solutions/Day_5/LogArchive/log_report-2023-08-04-18-04-18.txt new file mode 100644 index 0000000..09837ed --- /dev/null +++ b/Self-solutions/Day_5/LogArchive/log_report-2023-08-04-18-04-18.txt @@ -0,0 +1,73 @@ + + Log Analasys report + +Date of analysis: 2023-08-04-18-04-18 +Log file name: /root/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_5/logfile.log +Total lines processed: 300 +Total error count: 61 + +Top 5 Error Messages are as follows: +11 - Failed to connect +10 - Segmentation fault +8 - Disk full +6 - Permission denied +6 - Invalid input + + +printing the 'CRITICAL' log level occurences with their line numbers of logfile. + +Line number -2 : 2023-08-04 14:52:26 [CRITICAL] - 9931 +Line number -12 : 2023-08-04 14:52:26 [CRITICAL] - 18610 +Line number -15 : 2023-08-04 14:52:26 [CRITICAL] - 32604 +Line number -17 : 2023-08-04 14:52:26 [CRITICAL] - 8022 +Line number -28 : 2023-08-04 14:52:26 [CRITICAL] - 6799 +Line number -30 : 2023-08-04 14:52:26 [CRITICAL] - 18552 +Line number -32 : 2023-08-04 14:52:26 [CRITICAL] - 11113 +Line number -37 : 2023-08-04 14:52:26 [CRITICAL] - 19571 +Line number -39 : 2023-08-04 14:52:26 [CRITICAL] - 2854 +Line number -40 : 2023-08-04 14:52:26 [CRITICAL] - 15066 +Line number -42 : 2023-08-04 14:52:26 [CRITICAL] - 28344 +Line number -46 : 2023-08-04 14:52:26 [CRITICAL] - 13775 +Line number -47 : 2023-08-04 14:52:26 [CRITICAL] - 31720 +Line number -52 : 2023-08-04 14:52:26 [CRITICAL] - 8107 +Line number -58 : 2023-08-04 14:52:26 [CRITICAL] - 4078 +Line number -61 : 2023-08-04 14:52:26 [CRITICAL] - 9364 +Line number -66 : 2023-08-04 14:52:26 [CRITICAL] - 22911 +Line number -71 : 2023-08-04 14:52:26 [CRITICAL] - 8673 +Line number -74 : 2023-08-04 14:52:26 [CRITICAL] - 23188 +Line number -83 : 2023-08-04 14:52:26 [CRITICAL] - 29553 +Line number -86 : 2023-08-04 14:52:26 [CRITICAL] - 29900 +Line number -98 : 2023-08-04 14:52:26 [CRITICAL] - 14104 +Line number -99 : 2023-08-04 14:52:26 [CRITICAL] - 31900 +Line number -105 : 2023-08-04 14:52:26 [CRITICAL] - 17537 +Line number -106 : 2023-08-04 14:52:26 [CRITICAL] - 32729 +Line number -110 : 2023-08-04 14:52:26 [CRITICAL] - 22285 +Line number -111 : 2023-08-04 14:52:26 [CRITICAL] - 17009 +Line number -120 : 2023-08-04 14:52:26 [CRITICAL] - 18616 +Line number -121 : 2023-08-04 14:52:26 [CRITICAL] - 31053 +Line number -160 : 2023-08-04 14:52:26 [CRITICAL] - 12532 +Line number -161 : 2023-08-04 14:52:26 [CRITICAL] - 28216 +Line number -162 : 2023-08-04 14:52:26 [CRITICAL] - 31835 +Line number -163 : 2023-08-04 14:52:26 [CRITICAL] - 5721 +Line number -174 : 2023-08-04 14:52:26 [CRITICAL] - 11648 +Line number -178 : 2023-08-04 14:52:26 [CRITICAL] - 8364 +Line number -180 : 2023-08-04 14:52:26 [CRITICAL] - 24481 +Line number -186 : 2023-08-04 14:52:26 [CRITICAL] - 5536 +Line number -194 : 2023-08-04 14:52:26 [CRITICAL] - 6033 +Line number -196 : 2023-08-04 14:52:26 [CRITICAL] - 12167 +Line number -206 : 2023-08-04 14:52:26 [CRITICAL] - 14222 +Line number -212 : 2023-08-04 14:52:26 [CRITICAL] - 10208 +Line number -214 : 2023-08-04 14:52:26 [CRITICAL] - 32682 +Line number -220 : 2023-08-04 14:52:26 [CRITICAL] - 5664 +Line number -224 : 2023-08-04 14:52:26 [CRITICAL] - 2668 +Line number -228 : 2023-08-04 14:52:26 [CRITICAL] - 5712 +Line number -238 : 2023-08-04 14:52:26 [CRITICAL] - 14774 +Line number -241 : 2023-08-04 14:52:26 [CRITICAL] - 5768 +Line number -257 : 2023-08-04 14:52:26 [CRITICAL] - 23214 +Line number -264 : 2023-08-04 14:52:27 [CRITICAL] - 11714 +Line number -274 : 2023-08-04 14:52:27 [CRITICAL] - 5122 +Line number -286 : 2023-08-04 14:52:27 [CRITICAL] - 19055 +Line number -287 : 2023-08-04 14:52:27 [CRITICAL] - 5441 +Line number -291 : 2023-08-04 14:52:27 [CRITICAL] - 9692 +Line number -294 : 2023-08-04 14:52:27 [CRITICAL] - 17933 + diff --git a/Self-solutions/Day_5/README.md b/Self-solutions/Day_5/README.md new file mode 100644 index 0000000..df8a653 --- /dev/null +++ b/Self-solutions/Day_5/README.md @@ -0,0 +1,459 @@ + + +Usage and sample output of script day5_challenge_solution.sh + +Generated the sample log file(logfile.log) with 300 lines. +This script will handle multiple scenarios and error messages. + +log_generator.sh - this will generate the logfile by providing the logfile path and number of lines you want in log file. +this will have 9 error messages and 5 log levels to generate the logfile. + +Please read Sample_Log_Data.md for more details on how we are generating the log file. + +This script is fully enhanced with a feature to automatically archive or move processed log files to a LogArchive/ directory after analysis. + +``` +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_5# ./day5_challenge_solution.sh /root/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_5/logfile1.log + +Provided log file path is: /root/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_5/logfile1.log +Path does not exist. So please provide the correct path. !!! + + +#Before Running the script directory have these files +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_5# ls -ltr +total 48 +-rw-r--r-- 1 root root 0 Aug 4 10:00 day5_solution_practice.sh +-rwxr-xr-x 1 root root 1274 Aug 4 14:51 log_generator.sh +-rw-r--r-- 1 root root 12068 Aug 4 14:52 logfile.log +-rw-r--r-- 1 root root 56 Aug 4 14:55 readme.txt +-rw-r--r-- 1 root root 8780 Aug 4 14:56 README.md +-rw-r--r-- 1 root root 2705 Aug 4 15:58 Sample_Log_Data.md +-rwxr-xr-x 1 root root 8442 Aug 4 17:59 day5_challenge_solution.sh + +#after a first run + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_5# ./day5_challenge_solution.sh /root/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_5/logfile.log + +Provided log file path is: /root/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_5/logfile.log + +#################### + +INFO log_level count is: 72 + +#################### + +DEBUG log_level count is: 60 + +#################### + +ERROR log_level count is: 61 + +#################### + +WARNING log_level count is: 53 + +#################### + +CRITICAL log_level count is: 54 + + +printing the 'CRITICAL' log level occurences with their line numbers of logfile. + +Line number -2 : 2023-08-04 14:52:26 [CRITICAL] - 9931 +Line number -12 : 2023-08-04 14:52:26 [CRITICAL] - 18610 +Line number -15 : 2023-08-04 14:52:26 [CRITICAL] - 32604 +Line number -17 : 2023-08-04 14:52:26 [CRITICAL] - 8022 +Line number -28 : 2023-08-04 14:52:26 [CRITICAL] - 6799 +Line number -30 : 2023-08-04 14:52:26 [CRITICAL] - 18552 +Line number -32 : 2023-08-04 14:52:26 [CRITICAL] - 11113 +Line number -37 : 2023-08-04 14:52:26 [CRITICAL] - 19571 +Line number -39 : 2023-08-04 14:52:26 [CRITICAL] - 2854 +Line number -40 : 2023-08-04 14:52:26 [CRITICAL] - 15066 +Line number -42 : 2023-08-04 14:52:26 [CRITICAL] - 28344 +Line number -46 : 2023-08-04 14:52:26 [CRITICAL] - 13775 +Line number -47 : 2023-08-04 14:52:26 [CRITICAL] - 31720 +Line number -52 : 2023-08-04 14:52:26 [CRITICAL] - 8107 +Line number -58 : 2023-08-04 14:52:26 [CRITICAL] - 4078 +Line number -61 : 2023-08-04 14:52:26 [CRITICAL] - 9364 +Line number -66 : 2023-08-04 14:52:26 [CRITICAL] - 22911 +Line number -71 : 2023-08-04 14:52:26 [CRITICAL] - 8673 +Line number -74 : 2023-08-04 14:52:26 [CRITICAL] - 23188 +Line number -83 : 2023-08-04 14:52:26 [CRITICAL] - 29553 +Line number -86 : 2023-08-04 14:52:26 [CRITICAL] - 29900 +Line number -98 : 2023-08-04 14:52:26 [CRITICAL] - 14104 +Line number -99 : 2023-08-04 14:52:26 [CRITICAL] - 31900 +Line number -105 : 2023-08-04 14:52:26 [CRITICAL] - 17537 +Line number -106 : 2023-08-04 14:52:26 [CRITICAL] - 32729 +Line number -110 : 2023-08-04 14:52:26 [CRITICAL] - 22285 +Line number -111 : 2023-08-04 14:52:26 [CRITICAL] - 17009 +Line number -120 : 2023-08-04 14:52:26 [CRITICAL] - 18616 +Line number -121 : 2023-08-04 14:52:26 [CRITICAL] - 31053 +Line number -160 : 2023-08-04 14:52:26 [CRITICAL] - 12532 +Line number -161 : 2023-08-04 14:52:26 [CRITICAL] - 28216 +Line number -162 : 2023-08-04 14:52:26 [CRITICAL] - 31835 +Line number -163 : 2023-08-04 14:52:26 [CRITICAL] - 5721 +Line number -174 : 2023-08-04 14:52:26 [CRITICAL] - 11648 +Line number -178 : 2023-08-04 14:52:26 [CRITICAL] - 8364 +Line number -180 : 2023-08-04 14:52:26 [CRITICAL] - 24481 +Line number -186 : 2023-08-04 14:52:26 [CRITICAL] - 5536 +Line number -194 : 2023-08-04 14:52:26 [CRITICAL] - 6033 +Line number -196 : 2023-08-04 14:52:26 [CRITICAL] - 12167 +Line number -206 : 2023-08-04 14:52:26 [CRITICAL] - 14222 +Line number -212 : 2023-08-04 14:52:26 [CRITICAL] - 10208 +Line number -214 : 2023-08-04 14:52:26 [CRITICAL] - 32682 +Line number -220 : 2023-08-04 14:52:26 [CRITICAL] - 5664 +Line number -224 : 2023-08-04 14:52:26 [CRITICAL] - 2668 +Line number -228 : 2023-08-04 14:52:26 [CRITICAL] - 5712 +Line number -238 : 2023-08-04 14:52:26 [CRITICAL] - 14774 +Line number -241 : 2023-08-04 14:52:26 [CRITICAL] - 5768 +Line number -257 : 2023-08-04 14:52:26 [CRITICAL] - 23214 +Line number -264 : 2023-08-04 14:52:27 [CRITICAL] - 11714 +Line number -274 : 2023-08-04 14:52:27 [CRITICAL] - 5122 +Line number -286 : 2023-08-04 14:52:27 [CRITICAL] - 19055 +Line number -287 : 2023-08-04 14:52:27 [CRITICAL] - 5441 +Line number -291 : 2023-08-04 14:52:27 [CRITICAL] - 9692 +Line number -294 : 2023-08-04 14:52:27 [CRITICAL] - 17933 + + +Printing all the error messages with it's count. + +Failed to connect: 11 +Disk full: 8 +Segmentation fault: 10 +Invalid input: 6 +Out of memory: 5 +File not found: 6 +Permission denied: 6 +Connection refused: 4 +Timeout: 5 + + +Top 5 Error Messages are as follows: +11 - Failed to connect +10 - Segmentation fault +8 - Disk full +6 - Permission denied +6 - Invalid input + + +New log file has been created ( log_report-2023-08-04-18-04-18.txt ) + + + +Generating the report.... + +Report file log_report-2023-08-04-18-04-18.txt has been generated !!! + +Showing the Analasys... + + + Log Analasys report + +Date of analysis: 2023-08-04-18-04-18 +Log file name: /root/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_5/logfile.log +Total lines processed: 300 +Total error count: 61 + +Top 5 Error Messages are as follows: +11 - Failed to connect +10 - Segmentation fault +8 - Disk full +6 - Permission denied +6 - Invalid input + + +printing the 'CRITICAL' log level occurences with their line numbers of logfile. + +Line number -2 : 2023-08-04 14:52:26 [CRITICAL] - 9931 +Line number -12 : 2023-08-04 14:52:26 [CRITICAL] - 18610 +Line number -15 : 2023-08-04 14:52:26 [CRITICAL] - 32604 +Line number -17 : 2023-08-04 14:52:26 [CRITICAL] - 8022 +Line number -28 : 2023-08-04 14:52:26 [CRITICAL] - 6799 +Line number -30 : 2023-08-04 14:52:26 [CRITICAL] - 18552 +Line number -32 : 2023-08-04 14:52:26 [CRITICAL] - 11113 +Line number -37 : 2023-08-04 14:52:26 [CRITICAL] - 19571 +Line number -39 : 2023-08-04 14:52:26 [CRITICAL] - 2854 +Line number -40 : 2023-08-04 14:52:26 [CRITICAL] - 15066 +Line number -42 : 2023-08-04 14:52:26 [CRITICAL] - 28344 +Line number -46 : 2023-08-04 14:52:26 [CRITICAL] - 13775 +Line number -47 : 2023-08-04 14:52:26 [CRITICAL] - 31720 +Line number -52 : 2023-08-04 14:52:26 [CRITICAL] - 8107 +Line number -58 : 2023-08-04 14:52:26 [CRITICAL] - 4078 +Line number -61 : 2023-08-04 14:52:26 [CRITICAL] - 9364 +Line number -66 : 2023-08-04 14:52:26 [CRITICAL] - 22911 +Line number -71 : 2023-08-04 14:52:26 [CRITICAL] - 8673 +Line number -74 : 2023-08-04 14:52:26 [CRITICAL] - 23188 +Line number -83 : 2023-08-04 14:52:26 [CRITICAL] - 29553 +Line number -86 : 2023-08-04 14:52:26 [CRITICAL] - 29900 +Line number -98 : 2023-08-04 14:52:26 [CRITICAL] - 14104 +Line number -99 : 2023-08-04 14:52:26 [CRITICAL] - 31900 +Line number -105 : 2023-08-04 14:52:26 [CRITICAL] - 17537 +Line number -106 : 2023-08-04 14:52:26 [CRITICAL] - 32729 +Line number -110 : 2023-08-04 14:52:26 [CRITICAL] - 22285 +Line number -111 : 2023-08-04 14:52:26 [CRITICAL] - 17009 +Line number -120 : 2023-08-04 14:52:26 [CRITICAL] - 18616 +Line number -121 : 2023-08-04 14:52:26 [CRITICAL] - 31053 +Line number -160 : 2023-08-04 14:52:26 [CRITICAL] - 12532 +Line number -161 : 2023-08-04 14:52:26 [CRITICAL] - 28216 +Line number -162 : 2023-08-04 14:52:26 [CRITICAL] - 31835 +Line number -163 : 2023-08-04 14:52:26 [CRITICAL] - 5721 +Line number -174 : 2023-08-04 14:52:26 [CRITICAL] - 11648 +Line number -178 : 2023-08-04 14:52:26 [CRITICAL] - 8364 +Line number -180 : 2023-08-04 14:52:26 [CRITICAL] - 24481 +Line number -186 : 2023-08-04 14:52:26 [CRITICAL] - 5536 +Line number -194 : 2023-08-04 14:52:26 [CRITICAL] - 6033 +Line number -196 : 2023-08-04 14:52:26 [CRITICAL] - 12167 +Line number -206 : 2023-08-04 14:52:26 [CRITICAL] - 14222 +Line number -212 : 2023-08-04 14:52:26 [CRITICAL] - 10208 +Line number -214 : 2023-08-04 14:52:26 [CRITICAL] - 32682 +Line number -220 : 2023-08-04 14:52:26 [CRITICAL] - 5664 +Line number -224 : 2023-08-04 14:52:26 [CRITICAL] - 2668 +Line number -228 : 2023-08-04 14:52:26 [CRITICAL] - 5712 +Line number -238 : 2023-08-04 14:52:26 [CRITICAL] - 14774 +Line number -241 : 2023-08-04 14:52:26 [CRITICAL] - 5768 +Line number -257 : 2023-08-04 14:52:26 [CRITICAL] - 23214 +Line number -264 : 2023-08-04 14:52:27 [CRITICAL] - 11714 +Line number -274 : 2023-08-04 14:52:27 [CRITICAL] - 5122 +Line number -286 : 2023-08-04 14:52:27 [CRITICAL] - 19055 +Line number -287 : 2023-08-04 14:52:27 [CRITICAL] - 5441 +Line number -291 : 2023-08-04 14:52:27 [CRITICAL] - 9692 +Line number -294 : 2023-08-04 14:52:27 [CRITICAL] - 17933 + +#Now the directory files as follows +#if you observe archive directory(LogArchive/ ) and log file has been generated. + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_5# ls -ltr +total 44 +-rw-r--r-- 1 root root 0 Aug 4 10:00 day5_solution_practice.sh +-rwxr-xr-x 1 root root 1274 Aug 4 14:51 log_generator.sh +-rw-r--r-- 1 root root 12068 Aug 4 14:52 logfile.log +-rw-r--r-- 1 root root 56 Aug 4 14:55 readme.txt +-rw-r--r-- 1 root root 2705 Aug 4 15:58 Sample_Log_Data.md +-rwxr-xr-x 1 root root 8442 Aug 4 17:59 day5_challenge_solution.sh +drwxr-xr-x 2 root root 4096 Aug 4 18:04 LogArchive +-rw-r--r-- 1 root root 3635 Aug 4 18:04 log_report-2023-08-04-18-04-18.txt + +#lets run again + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_5# ./day5_challenge_solution.sh /root/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_5/logfile.log + +Provided log file path is: /root/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_5/logfile.log + +#################### + +INFO log_level count is: 72 + +#################### + +DEBUG log_level count is: 60 + +#################### + +ERROR log_level count is: 61 + +#################### + +WARNING log_level count is: 53 + +#################### + +CRITICAL log_level count is: 54 + + +printing the 'CRITICAL' log level occurences with their line numbers of logfile. + +Line number -2 : 2023-08-04 14:52:26 [CRITICAL] - 9931 +Line number -12 : 2023-08-04 14:52:26 [CRITICAL] - 18610 +Line number -15 : 2023-08-04 14:52:26 [CRITICAL] - 32604 +Line number -17 : 2023-08-04 14:52:26 [CRITICAL] - 8022 +Line number -28 : 2023-08-04 14:52:26 [CRITICAL] - 6799 +Line number -30 : 2023-08-04 14:52:26 [CRITICAL] - 18552 +Line number -32 : 2023-08-04 14:52:26 [CRITICAL] - 11113 +Line number -37 : 2023-08-04 14:52:26 [CRITICAL] - 19571 +Line number -39 : 2023-08-04 14:52:26 [CRITICAL] - 2854 +Line number -40 : 2023-08-04 14:52:26 [CRITICAL] - 15066 +Line number -42 : 2023-08-04 14:52:26 [CRITICAL] - 28344 +Line number -46 : 2023-08-04 14:52:26 [CRITICAL] - 13775 +Line number -47 : 2023-08-04 14:52:26 [CRITICAL] - 31720 +Line number -52 : 2023-08-04 14:52:26 [CRITICAL] - 8107 +Line number -58 : 2023-08-04 14:52:26 [CRITICAL] - 4078 +Line number -61 : 2023-08-04 14:52:26 [CRITICAL] - 9364 +Line number -66 : 2023-08-04 14:52:26 [CRITICAL] - 22911 +Line number -71 : 2023-08-04 14:52:26 [CRITICAL] - 8673 +Line number -74 : 2023-08-04 14:52:26 [CRITICAL] - 23188 +Line number -83 : 2023-08-04 14:52:26 [CRITICAL] - 29553 +Line number -86 : 2023-08-04 14:52:26 [CRITICAL] - 29900 +Line number -98 : 2023-08-04 14:52:26 [CRITICAL] - 14104 +Line number -99 : 2023-08-04 14:52:26 [CRITICAL] - 31900 +Line number -105 : 2023-08-04 14:52:26 [CRITICAL] - 17537 +Line number -106 : 2023-08-04 14:52:26 [CRITICAL] - 32729 +Line number -110 : 2023-08-04 14:52:26 [CRITICAL] - 22285 +Line number -111 : 2023-08-04 14:52:26 [CRITICAL] - 17009 +Line number -120 : 2023-08-04 14:52:26 [CRITICAL] - 18616 +Line number -121 : 2023-08-04 14:52:26 [CRITICAL] - 31053 +Line number -160 : 2023-08-04 14:52:26 [CRITICAL] - 12532 +Line number -161 : 2023-08-04 14:52:26 [CRITICAL] - 28216 +Line number -162 : 2023-08-04 14:52:26 [CRITICAL] - 31835 +Line number -163 : 2023-08-04 14:52:26 [CRITICAL] - 5721 +Line number -174 : 2023-08-04 14:52:26 [CRITICAL] - 11648 +Line number -178 : 2023-08-04 14:52:26 [CRITICAL] - 8364 +Line number -180 : 2023-08-04 14:52:26 [CRITICAL] - 24481 +Line number -186 : 2023-08-04 14:52:26 [CRITICAL] - 5536 +Line number -194 : 2023-08-04 14:52:26 [CRITICAL] - 6033 +Line number -196 : 2023-08-04 14:52:26 [CRITICAL] - 12167 +Line number -206 : 2023-08-04 14:52:26 [CRITICAL] - 14222 +Line number -212 : 2023-08-04 14:52:26 [CRITICAL] - 10208 +Line number -214 : 2023-08-04 14:52:26 [CRITICAL] - 32682 +Line number -220 : 2023-08-04 14:52:26 [CRITICAL] - 5664 +Line number -224 : 2023-08-04 14:52:26 [CRITICAL] - 2668 +Line number -228 : 2023-08-04 14:52:26 [CRITICAL] - 5712 +Line number -238 : 2023-08-04 14:52:26 [CRITICAL] - 14774 +Line number -241 : 2023-08-04 14:52:26 [CRITICAL] - 5768 +Line number -257 : 2023-08-04 14:52:26 [CRITICAL] - 23214 +Line number -264 : 2023-08-04 14:52:27 [CRITICAL] - 11714 +Line number -274 : 2023-08-04 14:52:27 [CRITICAL] - 5122 +Line number -286 : 2023-08-04 14:52:27 [CRITICAL] - 19055 +Line number -287 : 2023-08-04 14:52:27 [CRITICAL] - 5441 +Line number -291 : 2023-08-04 14:52:27 [CRITICAL] - 9692 +Line number -294 : 2023-08-04 14:52:27 [CRITICAL] - 17933 + + +Printing all the error messages with it's count. + +Failed to connect: 11 +Disk full: 8 +Segmentation fault: 10 +Invalid input: 6 +Out of memory: 5 +File not found: 6 +Permission denied: 6 +Connection refused: 4 +Timeout: 5 + + +Top 5 Error Messages are as follows: +11 - Failed to connect +10 - Segmentation fault +8 - Disk full +6 - Permission denied +6 - Invalid input + + +Old log file log_report-2023-08-04-18-04-18.txt presents! Moving it to archive directory. ! + +New log file has been created ( log_report-2023-08-04-18-06-44.txt ) + + +Generating the report.... + +Report file log_report-2023-08-04-18-06-44.txt has been generated !!! + +Showing the Analasys... + + + Log Analasys report + +Date of analysis: 2023-08-04-18-06-44 +Log file name: /root/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_5/logfile.log +Total lines processed: 300 +Total error count: 61 + +Top 5 Error Messages are as follows: +11 - Failed to connect +10 - Segmentation fault +8 - Disk full +6 - Permission denied +6 - Invalid input + + +printing the 'CRITICAL' log level occurences with their line numbers of logfile. + +Line number -2 : 2023-08-04 14:52:26 [CRITICAL] - 9931 +Line number -12 : 2023-08-04 14:52:26 [CRITICAL] - 18610 +Line number -15 : 2023-08-04 14:52:26 [CRITICAL] - 32604 +Line number -17 : 2023-08-04 14:52:26 [CRITICAL] - 8022 +Line number -28 : 2023-08-04 14:52:26 [CRITICAL] - 6799 +Line number -30 : 2023-08-04 14:52:26 [CRITICAL] - 18552 +Line number -32 : 2023-08-04 14:52:26 [CRITICAL] - 11113 +Line number -37 : 2023-08-04 14:52:26 [CRITICAL] - 19571 +Line number -39 : 2023-08-04 14:52:26 [CRITICAL] - 2854 +Line number -40 : 2023-08-04 14:52:26 [CRITICAL] - 15066 +Line number -42 : 2023-08-04 14:52:26 [CRITICAL] - 28344 +Line number -46 : 2023-08-04 14:52:26 [CRITICAL] - 13775 +Line number -47 : 2023-08-04 14:52:26 [CRITICAL] - 31720 +Line number -52 : 2023-08-04 14:52:26 [CRITICAL] - 8107 +Line number -58 : 2023-08-04 14:52:26 [CRITICAL] - 4078 +Line number -61 : 2023-08-04 14:52:26 [CRITICAL] - 9364 +Line number -66 : 2023-08-04 14:52:26 [CRITICAL] - 22911 +Line number -71 : 2023-08-04 14:52:26 [CRITICAL] - 8673 +Line number -74 : 2023-08-04 14:52:26 [CRITICAL] - 23188 +Line number -83 : 2023-08-04 14:52:26 [CRITICAL] - 29553 +Line number -86 : 2023-08-04 14:52:26 [CRITICAL] - 29900 +Line number -98 : 2023-08-04 14:52:26 [CRITICAL] - 14104 +Line number -99 : 2023-08-04 14:52:26 [CRITICAL] - 31900 +Line number -105 : 2023-08-04 14:52:26 [CRITICAL] - 17537 +Line number -106 : 2023-08-04 14:52:26 [CRITICAL] - 32729 +Line number -110 : 2023-08-04 14:52:26 [CRITICAL] - 22285 +Line number -111 : 2023-08-04 14:52:26 [CRITICAL] - 17009 +Line number -120 : 2023-08-04 14:52:26 [CRITICAL] - 18616 +Line number -121 : 2023-08-04 14:52:26 [CRITICAL] - 31053 +Line number -160 : 2023-08-04 14:52:26 [CRITICAL] - 12532 +Line number -161 : 2023-08-04 14:52:26 [CRITICAL] - 28216 +Line number -162 : 2023-08-04 14:52:26 [CRITICAL] - 31835 +Line number -163 : 2023-08-04 14:52:26 [CRITICAL] - 5721 +Line number -174 : 2023-08-04 14:52:26 [CRITICAL] - 11648 +Line number -178 : 2023-08-04 14:52:26 [CRITICAL] - 8364 +Line number -180 : 2023-08-04 14:52:26 [CRITICAL] - 24481 +Line number -186 : 2023-08-04 14:52:26 [CRITICAL] - 5536 +Line number -194 : 2023-08-04 14:52:26 [CRITICAL] - 6033 +Line number -196 : 2023-08-04 14:52:26 [CRITICAL] - 12167 +Line number -206 : 2023-08-04 14:52:26 [CRITICAL] - 14222 +Line number -212 : 2023-08-04 14:52:26 [CRITICAL] - 10208 +Line number -214 : 2023-08-04 14:52:26 [CRITICAL] - 32682 +Line number -220 : 2023-08-04 14:52:26 [CRITICAL] - 5664 +Line number -224 : 2023-08-04 14:52:26 [CRITICAL] - 2668 +Line number -228 : 2023-08-04 14:52:26 [CRITICAL] - 5712 +Line number -238 : 2023-08-04 14:52:26 [CRITICAL] - 14774 +Line number -241 : 2023-08-04 14:52:26 [CRITICAL] - 5768 +Line number -257 : 2023-08-04 14:52:26 [CRITICAL] - 23214 +Line number -264 : 2023-08-04 14:52:27 [CRITICAL] - 11714 +Line number -274 : 2023-08-04 14:52:27 [CRITICAL] - 5122 +Line number -286 : 2023-08-04 14:52:27 [CRITICAL] - 19055 +Line number -287 : 2023-08-04 14:52:27 [CRITICAL] - 5441 +Line number -291 : 2023-08-04 14:52:27 [CRITICAL] - 9692 +Line number -294 : 2023-08-04 14:52:27 [CRITICAL] - 17933 + +#now if you see below new log generated and old file has moved to archive directory + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_5# ls -ltr +total 44 +-rw-r--r-- 1 root root 0 Aug 4 10:00 day5_solution_practice.sh +-rwxr-xr-x 1 root root 1274 Aug 4 14:51 log_generator.sh +-rw-r--r-- 1 root root 12068 Aug 4 14:52 logfile.log +-rw-r--r-- 1 root root 56 Aug 4 14:55 readme.txt +-rw-r--r-- 1 root root 2705 Aug 4 15:58 Sample_Log_Data.md +-rwxr-xr-x 1 root root 8442 Aug 4 17:59 day5_challenge_solution.sh +drwxr-xr-x 2 root root 4096 Aug 4 18:06 LogArchive +-rw-r--r-- 1 root root 3635 Aug 4 18:06 log_report-2023-08-04-18-06-44.txt + + +#validate in archive directory + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_5# ls -ltr +total 44 +-rw-r--r-- 1 root root 0 Aug 4 10:00 day5_solution_practice.sh +-rwxr-xr-x 1 root root 1274 Aug 4 14:51 log_generator.sh +-rw-r--r-- 1 root root 12068 Aug 4 14:52 logfile.log +-rw-r--r-- 1 root root 56 Aug 4 14:55 readme.txt +-rw-r--r-- 1 root root 2705 Aug 4 15:58 Sample_Log_Data.md +-rwxr-xr-x 1 root root 8442 Aug 4 17:59 day5_challenge_solution.sh +drwxr-xr-x 2 root root 4096 Aug 4 18:06 LogArchive +-rw-r--r-- 1 root root 3635 Aug 4 18:06 log_report-2023-08-04-18-06-44.txt +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_5# cd LogArchive/ +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_5/LogArchive# ls -ltr +total 4 +-rw-r--r-- 1 root root 3635 Aug 4 18:04 log_report-2023-08-04-18-04-18.txt + +``` + + diff --git a/Self-solutions/Day_5/Sample_Log_Data.md b/Self-solutions/Day_5/Sample_Log_Data.md new file mode 100644 index 0000000..3ddc8a6 --- /dev/null +++ b/Self-solutions/Day_5/Sample_Log_Data.md @@ -0,0 +1,77 @@ +# Welcome, Challenger! + +## Sample Log Data for Testing + +Congratulations on reaching Day 5 of the 7-day Bash scripting challenge! To assist you in testing your log analyzer and report generator script, we have something below. + +## Create Your Own Data + +Feeling adventurous? If you want to go beyond the provided sample data(which you won't find because i haven't uploaded it ), you can generate your own log data using the `log_generator.sh` script. This script allows you to create log files with custom log levels, error messages, and line counts. + +**How to Generate Your Own Log Data:** + +1. Execute the `log_generator.sh` script with the desired log file path and the number of lines you want to generate. +2. Customize the `log_levels` and `error_messages` arrays in the script to tailor the log data to your needs. + +Remember, the more diverse log data you test with, the better you can fine-tune your script! + +Wishing you the best of luck in this challenge. Happy scripting! + +--- + +```Bash +#!/bin/bash + +# Usage: ./log_generator.sh + +if [ "$#" -ne 2 ]; then + echo "Usage: $0 " + exit 1 +fi + +log_file_path="$1" +num_lines="$2" + +if [ -e "$log_file_path" ]; then + echo "Error: File already exists at $log_file_path." + exit 1 +fi + +# List of possible log message levels +log_levels=("INFO" "DEBUG" "ERROR" "WARNING" "CRITICAL") + +# List of possible error messages +error_messages=("Failed to connect" "Disk full" "Segmentation fault" "Invalid input" "Out of memory") + +# Function to generate a random log line +generate_log_line() { + local log_level="${log_levels[$((RANDOM % ${#log_levels[@]}))]}" + local error_msg="" + if [ "$log_level" == "ERROR" ]; then + error_msg="${error_messages[$((RANDOM % ${#error_messages[@]}))]}" + fi + echo "$(date '+%Y-%m-%d %H:%M:%S') [$log_level] $error_msg - $RANDOM" +} + +# Create the log file with random log lines +touch "$log_file_path" +for ((i=0; i> "$log_file_path" +done + +echo "Log file created at: $log_file_path with $num_lines lines." + +``` + +--- + +Usage: +To use the log generator script, participants can execute the following command: + +``` +./log_generator.sh /path/to/logfile.log 100 +``` + +> This will create a log file named "logfile.log" in the specified path with 100 random log lines. Participants can adjust the number of lines as needed for testing their log analyzer and report generator scripts. + +The log lines generated will have timestamps, log levels (INFO, DEBUG, ERROR, WARNING, CRITICAL), and randomly chosen error messages for lines with "ERROR" log level. diff --git a/Self-solutions/Day_5/day5_challenge_solution.sh b/Self-solutions/Day_5/day5_challenge_solution.sh new file mode 100755 index 0000000..ca0f666 --- /dev/null +++ b/Self-solutions/Day_5/day5_challenge_solution.sh @@ -0,0 +1,229 @@ +#!/bin/bash + +#set -x + + +##################################################################### +# Script Name: day5_challange_solution.sh +# Author: Salwad Basha Shaik +# Date: August 4, 2023 +# Description: This script contains solution for Day 5-Log Analyzer and Report Generator as part of BashBlaze: 7 Days of Bash Scripting Challenge. +# Usage: ./day5_challange_solution.sh +# Email: salvathshaik786143@gmail.com +# LinkedIn: https://www.linkedin.com/in/salwad-basha-shaik/ +# Github: https://github.com/salvathshaik/ +##################################################################### + + +##################################### Day 5: Bash Scripting Challenge - Log Analyzer and Report Generator #################### + +###### Challenge Title: Log Analyzer and Report Generator ############### + +#Scenario +#You are a system administrator responsible for managing a network of servers. Every day, a log file is generated on each server containing important system events and error messages. As part of your daily tasks, you need to analyze these log files, identify specific events, and generate a summary report. + +#Task +#Write a Bash script that automates the process of analyzing log files and generating a daily summary report. The script should perform the following steps: + +#Input: The script should take the path to the log file as a command-line argument. + +#Error Count: Analyze the log file and count the number of error messages. An error message can be identified by a specific keyword (e.g., "ERROR" or "Failed"). Print the total error count. + +#Critical Events: Search for lines containing the keyword "CRITICAL" and print those lines along with the line number. + +#Top Error Messages: Identify the top 5 most common error messages and display them along with their occurrence count. + +#Summary Report: Generate a summary report in a separate text file. The report should include: + +#Date of analysis +#Log file name +#Total lines processed +#Total error count +#Top 5 error messages with their occurrence count +#List of critical events with line numbers + +#Optional Enhancement: Add a feature to automatically archive or move processed log files to a designated directory after analysis. + +#Tips +#Use grep, awk, and other command-line tools to process the log file. +##Utilize arrays or associative arrays to keep track of error messages and their counts. +#Use appropriate error handling to handle cases where the log file doesn't exist or other issues arise. + +#Sample Log File +#A sample log file named Sample_Log_Data.md has been provided in the same directory as this challenge file. You can use this file to test your script. + +#i have used the above log_generator.sh from above and created the log file as logfile.log with 300 lines with multiple log levels. + + +#checking if user provided command line arguments or not if not displaying the below message. + +logFilePath=$1 + +if [ "$#" == 0 ]; then + echo + echo "No arguments provide to the script so please follow below usage format !!!!" + echo "Usage: $0 " + echo + exit 1 +fi + +if [ -e "$logFilePath" ]; then + #ignoring if path presents!! + echo + echo "Provided log file path is: $logFilePath" + echo +else + echo + echo "Provided log file path is: $logFilePath" + echo "Path does not exist. So please provide the correct path. !!!" + echo + exit 1 +fi + +# Function to count of loglevels of with their corresponding lines and print them + +count_log_level() { + + local log_level="$1" + local log_level_count=$(grep -c "$log_level" "$logFilePath") + echo "####################" + echo + echo "$log_level log_level count is: $log_level_count" + echo +} + +# Calling the function for each log level to check the count. +count_log_level "INFO" +count_log_level "DEBUG" +count_log_level "ERROR" +count_log_level "WARNING" +count_log_level "CRITICAL" + + +#searching for lines containing the keyword "CRITICAL" and printing those lines along with the line number. + +list_critical_events() { + + echo + echo "printing the 'CRITICAL' log level occurences with their line numbers of logfile." + echo + grep -n "CRITICAL" "$logFilePath" | sed 's/^\([0-9]\+\):/Line number -\1 : /' + echo + +} + +list_critical_events #calling this fucntion to print the critical events with their line numbers of logfile. + +#Identifying the top 5 most common error messages and displaying them along with their occurrence count. + +# Declaring an array to store the 9 error messages +error_messages=( "Failed to connect" "Disk full" "Segmentation fault" "Invalid input" "Out of memory" "File not found" "Permission denied" "Connection refused" "Timeout" ) + +# Declaring an associative array to store error counts . associative arrays are similar to dictionaries in other programming languages. +declare -A error_messages_count_array + +all_loglevels_error_count=0 + +#for loop to count each error message in the log file +echo +echo "Printing all the error messages with it's count." +echo +for error_message in "${error_messages[@]}"; do + log_level_count=$(grep -c "$error_message" "$logFilePath") #here using grep -c to count the error message in logfile. + error_messages_count_array["$error_message"]=$log_level_count #here using storing the count in error_messages_count_array associative array with error_message key. + all_loglevels_error_count=$(( all_loglevels_error_count + log_level_count )) + echo "$error_message: $log_level_count" +done +echo + +#displaying top 5 error messages and their counts + +top_5_error_messages() { + + echo + echo "Top 5 Error Messages are as follows: " + sort -nr <<< "$(for error in "${!error_messages_count_array[@]}"; do echo "${error_messages_count_array[$error]} - $error"; done)" | head -n 5 + echo +#above command explanation +#<<< : this command will pass the for loop output to sort command +#sort command with -nr (numberically reverse ) will sort descendent the output with based on first filed that is error message count ). we can sort the second field using -k2 option with sort like (sort -nr -k2) but it's not working so sorting based on first field. +#and finally using head -n 5 top list out the top 5 error messages. + +} + +top_5_error_messages #calling the function to print the top 5 error messages. + + + +#Generating a summary report in a separate text file +date=$(date +"%Y-%m-%d-%H-%M-%S") #storing date with this format looks like YYYY-MM-DD HH:MM:SS +#creating a log_report.txt file and checking if it exists or not before creating +log_filename="log_report-$date.txt" +archive_directory="LogArchive" + + +log_report_pattern="log_report-*" + +#checking if all the files in current directory is starts with log_report-* text to moved it to archive directory. +for file in *; do + # Check if the file is a regular file + if [[ -f "$file" ]]; then + #comparing two files if matches means old log file present hence,moving to archive + if [[ "$file" == $log_report_pattern ]]; then + echo + echo "Old log file $file presents! Moving it to archive directory. !" + mv "$file" "$archive_directory" #moving the log file to archive directory.. + + fi + fi +done + +touch "$log_filename" +echo +echo "New log file has been created ( $log_filename )" +echo + +# Check if the directory exists +if [ -d "$archive_directory" ]; then + echo +else #if directory not present then create directory. + echo + mkdir "$archive_directory" + echo +fi + + + +echo "Generating the report...." +echo +echo >> "$log_filename" + +echo " Log Analasys report " >> "$log_filename" +echo >> "$log_filename" +echo "Date of analysis: $date" >> "$log_filename" #date has been stored in report + +echo "Log file name: $logFilePath" >> "$log_filename" + +#checking how many number of lines present in the logfile. +line_count=$(grep -c "" "$logFilePath") #grep is for searching text + #-c option is for counting the occurences of pattern + #"" is an empty pattern, which will match all lines in the file. + +echo "Total lines processed: $line_count" >> "$log_filename" + +echo "Total error count: $all_loglevels_error_count" >> "$log_filename" #i have calculaed this while counting the log levels above + + +top_5_error_messages >> "$log_filename" #calling function and passing the output to report file + +list_critical_events >> "$log_filename" #calling fuction and passing the output to report file. + +echo "Report file $log_filename has been generated !!! " +echo +echo "Showing the Analasys..." +echo +cat "$log_filename" +echo + + + diff --git a/Self-solutions/Day_5/day5_solution_practice.sh b/Self-solutions/Day_5/day5_solution_practice.sh new file mode 100644 index 0000000..c322be6 --- /dev/null +++ b/Self-solutions/Day_5/day5_solution_practice.sh @@ -0,0 +1,582 @@ +#!/bin/bash + +#set -x + + +##################################################################### +# Script Name: day5_challange_solution.sh +# Author: Salwad Basha Shaik +# Date: August 4, 2023 +# Description: This script contains solution for Day 5-Log Analyzer and Report Generator as part of BashBlaze: 7 Days of Bash Scripting Challenge. +# Usage: ./day5_challange_solution.sh +# Email: salvathshaik786143@gmail.com +# LinkedIn: https://www.linkedin.com/in/salwad-basha-shaik/ +# Github: https://github.com/salvathshaik/ +##################################################################### + + +##################################### Day 5: Bash Scripting Challenge - Log Analyzer and Report Generator #################### + +###### Challenge Title: Log Analyzer and Report Generator ############### + +#Scenario +#You are a system administrator responsible for managing a network of servers. Every day, a log file is generated on each server containing important system events and error messages. As part of your daily tasks, you need to analyze these log files, identify specific events, and generate a summary report. + +#Task +#Write a Bash script that automates the process of analyzing log files and generating a daily summary report. The script should perform the following steps: + +#Input: The script should take the path to the log file as a command-line argument. + +#Error Count: Analyze the log file and count the number of error messages. An error message can be identified by a specific keyword (e.g., "ERROR" or "Failed"). Print the total error count. + +#Critical Events: Search for lines containing the keyword "CRITICAL" and print those lines along with the line number. + +#Top Error Messages: Identify the top 5 most common error messages and display them along with their occurrence count. + +#Summary Report: Generate a summary report in a separate text file. The report should include: + +#Date of analysis +#Log file name +#Total lines processed +#Total error count +#Top 5 error messages with their occurrence count +#List of critical events with line numbers + +#Optional Enhancement: Add a feature to automatically archive or move processed log files to a designated directory after analysis. + +#Tips +#Use grep, awk, and other command-line tools to process the log file. +##Utilize arrays or associative arrays to keep track of error messages and their counts. +#Use appropriate error handling to handle cases where the log file doesn't exist or other issues arise. + +#Sample Log File +#A sample log file named Sample_Log_Data.md has been provided in the same directory as this challenge file. You can use this file to test your script. + +#i have used the above log_generator.sh from above and created the log file as logfile.log with 300 lines with multiple log levels. + + +#checking if user provided command line arguments or not if not displaying the below message. + +logFilePath=$1 + +if [ "$#" == 0 ]; then + echo + echo "No arguments provide to the script so please follow below usage format !!!!" + echo "Usage: $0 " + echo + exit 1 +fi + +if [ -e "$logFilePath" ]; then + #ignoring if path presents!! + echo + echo "Provided log file path is: $logFilePath" + echo +else + echo + echo "Provided log file path is: $logFilePath" + echo "Path does not exist. So please provide the correct path. !!!" + echo + exit 1 +fi + +# Function to count of loglevels of with their corresponding lines and print them + +count_log_level() { + + local log_level="$1" + local log_level_count=$(grep -c "$log_level" "$logFilePath") + echo "####################" + echo + echo "$log_level log_level count is: $log_level_count" + echo +} + +# Calling the function for each log level to check the count. +count_log_level "INFO" +count_log_level "DEBUG" +count_log_level "ERROR" +count_log_level "WARNING" +count_log_level "CRITICAL" + + +#searching for lines containing the keyword "CRITICAL" and printing those lines along with the line number. + +list_critical_events() { + + echo + echo "printing the 'CRITICAL' log level occurences with their line numbers of logfile." + echo + grep -n "CRITICAL" "$logFilePath" | sed 's/^\([0-9]\+\):/Line number -\1 : /' + echo + +} + +list_critical_events #calling this fucntion to print the critical events with their line numbers of logfile. + +#Identifying the top 5 most common error messages and displaying them along with their occurrence count. + +# Declaring an array to store the 9 error messages +error_messages=( "Failed to connect" "Disk full" "Segmentation fault" "Invalid input" "Out of memory" "File not found" "Permission denied" "Connection refused" "Timeout" ) + +# Declaring an associative array to store error counts . associative arrays are similar to dictionaries in other programming languages. +declare -A error_messages_count_array + +all_loglevels_error_count=0 + +#for loop to count each error message in the log file +echo +echo "Printing all the error messages with it's count." +echo +for error_message in "${error_messages[@]}"; do + log_level_count=$(grep -c "$error_message" "$logFilePath") #here using grep -c to count the error message in logfile. + error_messages_count_array["$error_message"]=$log_level_count #here using storing the count in error_messages_count_array associative array with error_message key. + all_loglevels_error_count=$(( all_loglevels_error_count + log_level_count )) + echo "$error_message: $log_level_count" +done +echo + +#displaying top 5 error messages and their counts + +top_5_error_messages() { + + echo + echo "Top 5 Error Messages are as follows: " + sort -nr <<< "$(for error in "${!error_messages_count_array[@]}"; do echo "${error_messages_count_array[$error]} - $error"; done)" | head -n 5 + echo +#above command explanation +#<<< : this command will pass the for loop output to sort command +#sort command with -nr (numberically reverse ) will sort descendent the output with based on first filed that is error message count ). we can sort the second field using -k2 option with sort like (sort -nr -k2) but it's not working so sorting based on first field. +#and finally using head -n 5 top list out the top 5 error messages. + +} + +top_5_error_messages #calling the function to print the top 5 error messages. + + + +#Generating a summary report in a separate text file +date=$(date +"%Y-%m-%d-%H-%M-%S") #storing date with this format looks like YYYY-MM-DD HH:MM:SS +#creating a log_report.txt file and checking if it exists or not before creating +log_filename="log_report-$date.txt" +archive_directory="LogArchive" + + +log_report_pattern="log_report-*" + +#checking if all the files in current directory is starts with log_report-* text to moved it to archive directory. +for file in *; do + # Check if the file is a regular file + if [[ -f "$file" ]]; then + #comparing two files if matches means old log file present hence,moving to archive + if [[ "$file" == $log_report_pattern ]]; then + echo + echo "Old log file $file presents! Moving it to archive directory. !" + mv "$file" "$archive_directory" #moving the log file to archive directory.. + + fi + fi +done + +touch "$log_filename" +echo +echo "New log file has been created ( $log_filename )" +echo + +# Check if the directory exists +if [ -d "$archive_directory" ]; then + echo +else #if directory not present then create directory. + echo + mkdir "$archive_directory" + echo +fi + + + +echo "Generating the report...." +echo +echo >> "$log_filename" + +echo " Log Analasys report " >> "$log_filename" +echo >> "$log_filename" +echo "Date of analysis: $date" >> "$log_filename" #date has been stored in report + +echo "Log file name: $logFilePath" >> "$log_filename" + +#checking how many number of lines present in the logfile. +line_count=$(grep -c "" "$logFilePath") #grep is for searching text + #-c option is for counting the occurences of pattern + #"" is an empty pattern, which will match all lines in the file. + +echo "Total lines processed: $line_count" >> "$log_filename" + +echo "Total error count: $all_loglevels_error_count" >> "$log_filename" #i have calculaed this while counting the log levels above + + +top_5_error_messages >> "$log_filename" #calling function and passing the output to report file + +list_critical_events >> "$log_filename" #calling fuction and passing the output to report file. + +echo "Report file $log_filename has been generated !!! " +echo +echo "Showing the Analasys..." +echo +cat "$log_filename" +echo + + +################################# practice #################### + +#practice-1 +#practicing to count the occurrences of each log level ("INFO," "DEBUG," "ERROR," "WARNING," "CRITICAL") in a given log file using shell scripting +#use the grep and wc commands. +#!/bin/bash + +log_file="path/to/your/log_file.log" + +# Count occurrences of each log level and store them in variables +info_count=$(grep -c "INFO" "$log_file") +debug_count=$(grep -c "DEBUG" "$log_file") +error_count=$(grep -c "ERROR" "$log_file") +warning_count=$(grep -c "WARNING" "$log_file") +critical_count=$(grep -c "CRITICAL" "$log_file") + +# Print the counts +echo "INFO count: $info_count" +echo "DEBUG count: $debug_count" +echo "ERROR count: $error_count" +echo "WARNING count: $warning_count" +echo "CRITICAL count: $critical_count" + + + +#practice-2 +#practicing to print the occurrence lines along with their counts +#!/bin/bash + +log_file="path/to/your/log_file.log" + +# Function to count occurrences of each log level and print them +count_logs() { + local level="$1" + local count=$(grep -c "$level" "$log_file") + echo "$level count: $count" + if [ "$count" -gt 0 ]; then + grep "$level" "$log_file" | awk '{print NR, $0}' + fi + echo "-------------------" +} + +# Call the function for each log level +count_logs "INFO" +count_logs "DEBUG" +count_logs "ERROR" +count_logs "WARNING" +count_logs "CRITICAL" + +#explaining the below line +grep "$level" "$log_file" | awk '{print NR, $0}' + +#grep "$level" "$log_file": This part uses the grep command to search for lines containing the log level specified by the variable $level in the log file specified by the variable $log_file. +#|: The vertical bar, also known as the pipe symbol |, is used to connect the output of one command as the input to another command. In this case, it takes the output of the grep command and passes it as input to the awk command. +#awk '{print NR, $0}': This part uses the awk command to manipulate and format the output from grep. awk is a powerful text processing tool that can operate on individual fields of each line. +#NR: It is a built-in awk variable that stores the current line number. awk '{print NR, $0}' prints the line number NR followed by the entire line $0. +#$0: It is a built-in awk variable that represents the entire current line. +#o, when you combine grep "$level" "$log_file" and awk '{print NR, $0}' using the pipe symbol |, it will search for lines containing the log level specified by $level in the log file specified by $log_file + + +#practice-3 +#practicing to To find the count of lines with "CRITICAL" log level and display their line numbers in the log file +grep -n "CRITICAL" "$log_file" + + +#practice-4 +#practicing to check if a path exists or not in shell scripting using the -e flag with the test command or the equivalent [ -e ... ] construct. +#Using the test command: + +if test -e "/path/to/directory_or_file"; then + echo "Path exists." +else + echo "Path does not exist." +fi + +#Using the [ ] construct (note that there should be spaces inside the brackets): +if [ -e "/path/to/directory_or_file" ]; then + echo "Path exists." +else + echo "Path does not exist." +fi + + +#practice-5 +#practicing to add some text with each line number while using the grep -n command to search for "CRITICAL" in the log file +#can achieve this using the sed command to replace the line numbers with your desired text. +grep -n "CRITICAL" "$log_file" | sed 's/^\([0-9]\+\):/Line \1:/' + +#we can add space after the original line number by modifying the sed command. +grep -n "CRITICAL" "$log_file" | sed 's/^\([0-9]\+\):/Line \1: /' +#The only change here is the addition of a space after the replacement text "Line \1:". This will insert a space after the original line number, giving you the desired output with the space after each line number. + +#practice-6 +#practicing to identify the top 5 most common error messages and display them along with their occurrence count +##we can use a combination of grep, sort, and uniq commands in shell scripting. +#Assuming the error messages are logged in a file named error.log, +grep -o "ERROR .*" error.log | sort | uniq -c | sort -nr | head -5 +#Explanation of each part of the command: +#grep -o "ERROR .*" error.log: This command extracts all lines that start with "ERROR" from the error.log file. +#sort: This sorts the extracted error messages alphabetically. +#uniq -c: This counts the occurrences of each unique error message and adds the count in front of each message. +#sort -nr: This sorts the error messages based on the occurrence count in descending order, so the most common errors appear at the top. +##head -5: This displays only the top 5 most common error messages along with their occurrence count. + + +#practice-7 +#practicing To count and list the top 5 occurrences of each log level (INFO, DEBUG, ERROR, WARNING, CRITICAL) from the logfile, +#!/bin/bash + +logfile="your_log_file.log" + +# Function to count and list the top 5 occurrences of a log level +count_and_list_log_level() { + log_level="$1" + echo "Top 5 occurrences of $log_level:" + grep -o "$log_level .*" "$logfile" | sort | uniq -c | sort -nr | head -5 + echo +} + +# Call the function for each log level +count_and_list_log_level "INFO" +count_and_list_log_level "DEBUG" +count_and_list_log_level "ERROR" +count_and_list_log_level "WARNING" +count_and_list_log_level "CRITICAL" + + +#practice-8 +#practicing arrays in shell scripting +#Arrays in shell scripting allow you to store multiple values under a single variable name. Shell scripts support one-dimensional arrays. You can access individual elements, loop through the array, and perform various operations on it. + +#Declaring an array: +# Declare an array +my_array=("value1" "value2" "value3") +#Accessing array elements: +# Access an element using its index (starts from 0) +echo "${my_array[0]}" # Output: value1 +echo "${my_array[1]}" # Output: value2 +#Assigning values to array elements: +# Assign values to individual elements +my_array[2]="new_value" +#Getting the length of the array: +# Get the length of the array +length=${#my_array[@]} +echo "Array length: $length" # Output: Array length: 3 +#Looping through an array: +# Loop through the array using a for loop +for item in "${my_array[@]}"; do + echo "$item" +done +#Appending elements to the array: +# Append elements to the end of the array +my_array+=(value4 value5) +#Removing elements from the array: +# Remove a specific element from the array +unset my_array[2] + +# Remove all elements from the array +unset my_array +#Using array in command substitution: +# Command substitution with an array +result=$(ls -l) # Stores the output of "ls -l" command in the "result" variable +echo "$result" + + +#practice-8 +#practicing to store 6 error messages in array and count each error message in logfile and store each error message with its count and in the end display the top 5 error messages based on with its count in shell scripting. +#!/bin/bash + +# Declare an array to store error messages +error_messages=("Error: File not found" "Error: Permission denied" "Error: Connection refused" "Error: Invalid input" "Error: Timeout" "Error: Out of memory") + +# Declare an associative array to store error counts +declare -A error_counts + +# Log file path +log_file="path/to/your/logfile.log" + +# Count each error message in the log file +for error in "${error_messages[@]}"; do + count=$(grep -c "$error" "$log_file") + error_counts["$error"]=$count +done + +# Display error messages with their counts +echo "Error Messages and their Counts:" +for error in "${!error_counts[@]}"; do + echo "$error: ${error_counts[$error]}" +done + +# Display the top 5 error messages based on their counts +echo "Top 5 Error Messages:" +sort -nr -k2 <<< "$(for error in "${!error_counts[@]}"; do echo "$error ${error_counts[$error]}"; done)" | head -n 5 + +#-k2 option not working so use below command +sort -nr <<< "$(for error in "${!error_counts[@]}"; do echo "${error_counts[$error]} $error"; done)" | head -n 5 +#for error in "${!error_counts[@]}"; do echo "${error_counts[$error]} $error"; done: This loop iterates through the associative array error_counts and echoes each error message with its count in the format "count error_message". +#<<<: This is a Here String in Bash, which feeds the output of the preceding loop as input to the next command. +#|: The pipe symbol (|) is used to pass the sorted output to the next command. +#head -n 5: This command selects the top 5 lines from the sorted output, displaying the error messages with the highest counts. +#sort -nr will sort based on first firled of the out of for loop by defualt + + +#practice-9 +#practing associative arraysin shell scripting +#in shell scripting, associative arrays are similar to dictionaries in other programming languages. They allow you to store key-value pairs, where each key is unique and maps to a specific value. The key-value pairs in an associative array can be accessed, added, modified, or deleted using the key. +#we can create an associative array using +declare -A my_array +#The -A option indicates that the array is associative +#assign values to the array using the keys: +my_array["key1"]="value1" +my_array["key2"]="value2" +#To access the values, +echo ${my_array["key1"]} # This will print "value1" +#we can iterate through the associative array using a for loop: +for key in "${!my_array[@]}"; do + echo "Key: $key, Value: ${my_array[$key]}" +done +#Keep in mind that associative arrays are available in Bash version 4 and above. If you are using an older version of Bash, you won't be able to use associative arrays. + +#practice-10 but not worked out +#practicing other way of sort based on occurrence count in the shell script. +#One common approach is to use the awk command to rearrange the fields in the desired order before sorting. +for error in "${!error_counts[@]}"; do + echo "${error_counts[$error]} $error" +done | awk '{print $2, $1}' | sort -nr | head -n 5 + + +#practice-10 +#practicing to use the date command to print the current date and time in a formatted manner. To pass the formatted date to a text file, +# Get the current date in a specific format (e.g., YYYY-MM-DD HH:MM:SS) +formatted_date=$(date +"%Y-%m-%d %H:%M:%S") + +# Print the formatted date to the terminal +echo "Current date: $formatted_date" + +# Append the formatted date to a text file +echo "Current date: $formatted_date" >> output.txt +#The echo command is used to print the formatted date to the terminal, and the >> redirection appends the output to the output.txt file +##to create a new file or overwrite an existing one, you can use > instead of >>. + +#to ass more text into the same file in the next line using the >> redirection operator +# Append the second line to the file +echo "This is the second line." >> output.txt +##This will append the text to the end of the file on a new line. + + +#practice-11 +#practicing to create a text file and check if it already exists in shell scripting +#!/bin/bash + +filename="example.txt" + +# Check if the file already exists +if [ -e "$filename" ]; then + echo "File already exists." +else + # Create the file + touch "$filename" + echo "File created: $filename" +fi + + +#practice-12 +#practicing to check the number of lines in a file using various methods in shell scripting. +#Using wc command: +#!/bin/bash + +filename="example.txt" + +# Check the number of lines in the file +line_count=$(wc -l < "$filename") + +echo "Number of lines in $filename: $line_count" +#Using grep and wc: +#!/bin/bash + +filename="example.txt" + +# Check the number of lines in the file +line_count=$(grep -c "" "$filename") + +echo "Number of lines in $filename: $line_count" +#Using a loop: +#!/bin/bash + +filename="example.txt" +line_count=0 + +# Count lines using a loop +while IFS= read -r _; do + ((line_count++)) +done < "$filename" + +echo "Number of lines in $filename: $line_count" + +#explaining this line +line_count=$(grep -c "" "$filename") + +#grep is a command-line utility in Linux used for searching text patterns in files. +#-c is the option for counting the number of occurrences of the pattern. +#"" is an empty pattern, which will match all lines in the file. +#"$filename" is the variable that holds the name of the file you want to search. + + +#practice-13: +#practicing To pass the output of a function to a file in shell scripting, +#use command substitution and output redirection +my_function > output.txt +my_function >> output.txt +# use the >> redirection operator for append + + +#practice-14 +#practicing to use a for loop to iterate through the files in the current directory and check if the filename starts with 'log_report-'. +#!/bin/bash + +log_report="log_report-*" # The prefix you want to check + +# Loop through all files in the current directory +for file in *; do + if -e $file[ ] + # Check if the file starts with the specified prefix + if [[ "$file" == "$log_report" ]]; then #use vairiable only dont use direct text here + echo "$file starts with '$log_report'" + # You can add more actions here if needed + fi + fi +done +#the [[ ... ]] construct is used for the string comparison + +#practice-15 +#practicing to use the -d flag with the test or [ command to check if a directory is present in the current directory. +#!/bin/bash + +directory_name="my_directory" # The name of the directory you want to check + +# Check if the directory exists +if [ -d "$directory_name" ]; then + echo "Directory '$directory_name' exists in the current directory." + # You can add more actions here if needed +else + echo "Directory '$directory_name' does not exist in the current directory." +fi + + + + + + + + + + diff --git a/Self-solutions/Day_5/log_generator.sh b/Self-solutions/Day_5/log_generator.sh new file mode 100755 index 0000000..8bf47a1 --- /dev/null +++ b/Self-solutions/Day_5/log_generator.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# Usage: ./log_generator.sh + +if [ "$#" -ne 2 ]; then + echo "Usage: $0 " + exit 1 +fi + +log_file_path="$1" +num_lines="$2" + +if [ -e "$log_file_path" ]; then + echo "Error: File already exists at $log_file_path." + exit 1 +fi + +# List of possible log message levels +log_levels=("INFO" "DEBUG" "ERROR" "WARNING" "CRITICAL") + +# List of possible error messages +#error_messages=("Failed to connect" "Disk full" "Segmentation fault" "Invalid input" "Out of memory") +error_messages=( "Failed to connect" "Disk full" "Segmentation fault" "Invalid input" "Out of memory" "File not found" "Permission denied" "Connection refused" "Timeout" ) +# Function to generate a random log line +generate_log_line() { + local log_level="${log_levels[$((RANDOM % ${#log_levels[@]}))]}" + local error_msg="" + if [ "$log_level" == "ERROR" ]; then + error_msg="${error_messages[$((RANDOM % ${#error_messages[@]}))]}" + fi + echo "$(date '+%Y-%m-%d %H:%M:%S') [$log_level] $error_msg - $RANDOM" +} + +# Create the log file with random log lines +touch "$log_file_path" +for ((i=0; i> "$log_file_path" +done + +echo "Log file created at: $log_file_path with $num_lines lines." + diff --git a/Self-solutions/Day_5/log_report-2023-08-04-18-06-44.txt b/Self-solutions/Day_5/log_report-2023-08-04-18-06-44.txt new file mode 100644 index 0000000..d09e1ff --- /dev/null +++ b/Self-solutions/Day_5/log_report-2023-08-04-18-06-44.txt @@ -0,0 +1,73 @@ + + Log Analasys report + +Date of analysis: 2023-08-04-18-06-44 +Log file name: /root/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_5/logfile.log +Total lines processed: 300 +Total error count: 61 + +Top 5 Error Messages are as follows: +11 - Failed to connect +10 - Segmentation fault +8 - Disk full +6 - Permission denied +6 - Invalid input + + +printing the 'CRITICAL' log level occurences with their line numbers of logfile. + +Line number -2 : 2023-08-04 14:52:26 [CRITICAL] - 9931 +Line number -12 : 2023-08-04 14:52:26 [CRITICAL] - 18610 +Line number -15 : 2023-08-04 14:52:26 [CRITICAL] - 32604 +Line number -17 : 2023-08-04 14:52:26 [CRITICAL] - 8022 +Line number -28 : 2023-08-04 14:52:26 [CRITICAL] - 6799 +Line number -30 : 2023-08-04 14:52:26 [CRITICAL] - 18552 +Line number -32 : 2023-08-04 14:52:26 [CRITICAL] - 11113 +Line number -37 : 2023-08-04 14:52:26 [CRITICAL] - 19571 +Line number -39 : 2023-08-04 14:52:26 [CRITICAL] - 2854 +Line number -40 : 2023-08-04 14:52:26 [CRITICAL] - 15066 +Line number -42 : 2023-08-04 14:52:26 [CRITICAL] - 28344 +Line number -46 : 2023-08-04 14:52:26 [CRITICAL] - 13775 +Line number -47 : 2023-08-04 14:52:26 [CRITICAL] - 31720 +Line number -52 : 2023-08-04 14:52:26 [CRITICAL] - 8107 +Line number -58 : 2023-08-04 14:52:26 [CRITICAL] - 4078 +Line number -61 : 2023-08-04 14:52:26 [CRITICAL] - 9364 +Line number -66 : 2023-08-04 14:52:26 [CRITICAL] - 22911 +Line number -71 : 2023-08-04 14:52:26 [CRITICAL] - 8673 +Line number -74 : 2023-08-04 14:52:26 [CRITICAL] - 23188 +Line number -83 : 2023-08-04 14:52:26 [CRITICAL] - 29553 +Line number -86 : 2023-08-04 14:52:26 [CRITICAL] - 29900 +Line number -98 : 2023-08-04 14:52:26 [CRITICAL] - 14104 +Line number -99 : 2023-08-04 14:52:26 [CRITICAL] - 31900 +Line number -105 : 2023-08-04 14:52:26 [CRITICAL] - 17537 +Line number -106 : 2023-08-04 14:52:26 [CRITICAL] - 32729 +Line number -110 : 2023-08-04 14:52:26 [CRITICAL] - 22285 +Line number -111 : 2023-08-04 14:52:26 [CRITICAL] - 17009 +Line number -120 : 2023-08-04 14:52:26 [CRITICAL] - 18616 +Line number -121 : 2023-08-04 14:52:26 [CRITICAL] - 31053 +Line number -160 : 2023-08-04 14:52:26 [CRITICAL] - 12532 +Line number -161 : 2023-08-04 14:52:26 [CRITICAL] - 28216 +Line number -162 : 2023-08-04 14:52:26 [CRITICAL] - 31835 +Line number -163 : 2023-08-04 14:52:26 [CRITICAL] - 5721 +Line number -174 : 2023-08-04 14:52:26 [CRITICAL] - 11648 +Line number -178 : 2023-08-04 14:52:26 [CRITICAL] - 8364 +Line number -180 : 2023-08-04 14:52:26 [CRITICAL] - 24481 +Line number -186 : 2023-08-04 14:52:26 [CRITICAL] - 5536 +Line number -194 : 2023-08-04 14:52:26 [CRITICAL] - 6033 +Line number -196 : 2023-08-04 14:52:26 [CRITICAL] - 12167 +Line number -206 : 2023-08-04 14:52:26 [CRITICAL] - 14222 +Line number -212 : 2023-08-04 14:52:26 [CRITICAL] - 10208 +Line number -214 : 2023-08-04 14:52:26 [CRITICAL] - 32682 +Line number -220 : 2023-08-04 14:52:26 [CRITICAL] - 5664 +Line number -224 : 2023-08-04 14:52:26 [CRITICAL] - 2668 +Line number -228 : 2023-08-04 14:52:26 [CRITICAL] - 5712 +Line number -238 : 2023-08-04 14:52:26 [CRITICAL] - 14774 +Line number -241 : 2023-08-04 14:52:26 [CRITICAL] - 5768 +Line number -257 : 2023-08-04 14:52:26 [CRITICAL] - 23214 +Line number -264 : 2023-08-04 14:52:27 [CRITICAL] - 11714 +Line number -274 : 2023-08-04 14:52:27 [CRITICAL] - 5122 +Line number -286 : 2023-08-04 14:52:27 [CRITICAL] - 19055 +Line number -287 : 2023-08-04 14:52:27 [CRITICAL] - 5441 +Line number -291 : 2023-08-04 14:52:27 [CRITICAL] - 9692 +Line number -294 : 2023-08-04 14:52:27 [CRITICAL] - 17933 + diff --git a/Self-solutions/Day_5/logfile.log b/Self-solutions/Day_5/logfile.log new file mode 100644 index 0000000..f7419bd --- /dev/null +++ b/Self-solutions/Day_5/logfile.log @@ -0,0 +1,300 @@ +2023-08-04 14:52:26 [DEBUG] - 15492 +2023-08-04 14:52:26 [CRITICAL] - 9931 +2023-08-04 14:52:26 [ERROR] Disk full - 21455 +2023-08-04 14:52:26 [INFO] - 322 +2023-08-04 14:52:26 [ERROR] Segmentation fault - 29780 +2023-08-04 14:52:26 [INFO] - 2319 +2023-08-04 14:52:26 [INFO] - 22462 +2023-08-04 14:52:26 [INFO] - 31309 +2023-08-04 14:52:26 [DEBUG] - 3171 +2023-08-04 14:52:26 [ERROR] Invalid input - 13361 +2023-08-04 14:52:26 [WARNING] - 31418 +2023-08-04 14:52:26 [CRITICAL] - 18610 +2023-08-04 14:52:26 [INFO] - 8735 +2023-08-04 14:52:26 [INFO] - 12807 +2023-08-04 14:52:26 [CRITICAL] - 32604 +2023-08-04 14:52:26 [WARNING] - 18603 +2023-08-04 14:52:26 [CRITICAL] - 8022 +2023-08-04 14:52:26 [DEBUG] - 12975 +2023-08-04 14:52:26 [DEBUG] - 17772 +2023-08-04 14:52:26 [ERROR] Invalid input - 13938 +2023-08-04 14:52:26 [WARNING] - 26583 +2023-08-04 14:52:26 [INFO] - 28002 +2023-08-04 14:52:26 [WARNING] - 25186 +2023-08-04 14:52:26 [DEBUG] - 21316 +2023-08-04 14:52:26 [DEBUG] - 2581 +2023-08-04 14:52:26 [ERROR] Segmentation fault - 18976 +2023-08-04 14:52:26 [INFO] - 29202 +2023-08-04 14:52:26 [CRITICAL] - 6799 +2023-08-04 14:52:26 [DEBUG] - 7081 +2023-08-04 14:52:26 [CRITICAL] - 18552 +2023-08-04 14:52:26 [WARNING] - 27791 +2023-08-04 14:52:26 [CRITICAL] - 11113 +2023-08-04 14:52:26 [INFO] - 3678 +2023-08-04 14:52:26 [WARNING] - 6663 +2023-08-04 14:52:26 [WARNING] - 3371 +2023-08-04 14:52:26 [INFO] - 31051 +2023-08-04 14:52:26 [CRITICAL] - 19571 +2023-08-04 14:52:26 [INFO] - 23629 +2023-08-04 14:52:26 [CRITICAL] - 2854 +2023-08-04 14:52:26 [CRITICAL] - 15066 +2023-08-04 14:52:26 [INFO] - 22487 +2023-08-04 14:52:26 [CRITICAL] - 28344 +2023-08-04 14:52:26 [DEBUG] - 29461 +2023-08-04 14:52:26 [ERROR] File not found - 28975 +2023-08-04 14:52:26 [INFO] - 17986 +2023-08-04 14:52:26 [CRITICAL] - 13775 +2023-08-04 14:52:26 [CRITICAL] - 31720 +2023-08-04 14:52:26 [ERROR] Segmentation fault - 13663 +2023-08-04 14:52:26 [INFO] - 6336 +2023-08-04 14:52:26 [WARNING] - 4070 +2023-08-04 14:52:26 [WARNING] - 8466 +2023-08-04 14:52:26 [CRITICAL] - 8107 +2023-08-04 14:52:26 [WARNING] - 8412 +2023-08-04 14:52:26 [DEBUG] - 936 +2023-08-04 14:52:26 [INFO] - 25418 +2023-08-04 14:52:26 [ERROR] Out of memory - 29480 +2023-08-04 14:52:26 [WARNING] - 13259 +2023-08-04 14:52:26 [CRITICAL] - 4078 +2023-08-04 14:52:26 [DEBUG] - 27501 +2023-08-04 14:52:26 [DEBUG] - 9474 +2023-08-04 14:52:26 [CRITICAL] - 9364 +2023-08-04 14:52:26 [ERROR] Timeout - 6862 +2023-08-04 14:52:26 [ERROR] Disk full - 13157 +2023-08-04 14:52:26 [INFO] - 25403 +2023-08-04 14:52:26 [INFO] - 22249 +2023-08-04 14:52:26 [CRITICAL] - 22911 +2023-08-04 14:52:26 [WARNING] - 21172 +2023-08-04 14:52:26 [DEBUG] - 14914 +2023-08-04 14:52:26 [INFO] - 30312 +2023-08-04 14:52:26 [DEBUG] - 9407 +2023-08-04 14:52:26 [CRITICAL] - 8673 +2023-08-04 14:52:26 [DEBUG] - 7370 +2023-08-04 14:52:26 [DEBUG] - 23656 +2023-08-04 14:52:26 [CRITICAL] - 23188 +2023-08-04 14:52:26 [ERROR] Segmentation fault - 25406 +2023-08-04 14:52:26 [DEBUG] - 3739 +2023-08-04 14:52:26 [WARNING] - 5977 +2023-08-04 14:52:26 [WARNING] - 8577 +2023-08-04 14:52:26 [WARNING] - 13503 +2023-08-04 14:52:26 [INFO] - 14712 +2023-08-04 14:52:26 [DEBUG] - 4121 +2023-08-04 14:52:26 [WARNING] - 29042 +2023-08-04 14:52:26 [CRITICAL] - 29553 +2023-08-04 14:52:26 [DEBUG] - 15388 +2023-08-04 14:52:26 [INFO] - 9655 +2023-08-04 14:52:26 [CRITICAL] - 29900 +2023-08-04 14:52:26 [WARNING] - 13147 +2023-08-04 14:52:26 [INFO] - 4910 +2023-08-04 14:52:26 [ERROR] Disk full - 22296 +2023-08-04 14:52:26 [WARNING] - 28700 +2023-08-04 14:52:26 [INFO] - 25714 +2023-08-04 14:52:26 [INFO] - 17862 +2023-08-04 14:52:26 [ERROR] Permission denied - 23501 +2023-08-04 14:52:26 [WARNING] - 13528 +2023-08-04 14:52:26 [INFO] - 1044 +2023-08-04 14:52:26 [INFO] - 17782 +2023-08-04 14:52:26 [ERROR] Permission denied - 8410 +2023-08-04 14:52:26 [CRITICAL] - 14104 +2023-08-04 14:52:26 [CRITICAL] - 31900 +2023-08-04 14:52:26 [INFO] - 4163 +2023-08-04 14:52:26 [DEBUG] - 22960 +2023-08-04 14:52:26 [WARNING] - 9648 +2023-08-04 14:52:26 [ERROR] Segmentation fault - 24115 +2023-08-04 14:52:26 [DEBUG] - 16618 +2023-08-04 14:52:26 [CRITICAL] - 17537 +2023-08-04 14:52:26 [CRITICAL] - 32729 +2023-08-04 14:52:26 [DEBUG] - 5486 +2023-08-04 14:52:26 [INFO] - 10877 +2023-08-04 14:52:26 [INFO] - 17370 +2023-08-04 14:52:26 [CRITICAL] - 22285 +2023-08-04 14:52:26 [CRITICAL] - 17009 +2023-08-04 14:52:26 [INFO] - 3002 +2023-08-04 14:52:26 [INFO] - 23500 +2023-08-04 14:52:26 [ERROR] Connection refused - 20277 +2023-08-04 14:52:26 [INFO] - 26016 +2023-08-04 14:52:26 [WARNING] - 20966 +2023-08-04 14:52:26 [INFO] - 6801 +2023-08-04 14:52:26 [WARNING] - 28761 +2023-08-04 14:52:26 [WARNING] - 1792 +2023-08-04 14:52:26 [CRITICAL] - 18616 +2023-08-04 14:52:26 [CRITICAL] - 31053 +2023-08-04 14:52:26 [INFO] - 15792 +2023-08-04 14:52:26 [DEBUG] - 10602 +2023-08-04 14:52:26 [DEBUG] - 6598 +2023-08-04 14:52:26 [INFO] - 10789 +2023-08-04 14:52:26 [INFO] - 29776 +2023-08-04 14:52:26 [INFO] - 27373 +2023-08-04 14:52:26 [ERROR] File not found - 23665 +2023-08-04 14:52:26 [DEBUG] - 24196 +2023-08-04 14:52:26 [ERROR] Out of memory - 5354 +2023-08-04 14:52:26 [WARNING] - 1049 +2023-08-04 14:52:26 [WARNING] - 22487 +2023-08-04 14:52:26 [ERROR] Disk full - 10440 +2023-08-04 14:52:26 [ERROR] Segmentation fault - 7079 +2023-08-04 14:52:26 [INFO] - 17352 +2023-08-04 14:52:26 [WARNING] - 5385 +2023-08-04 14:52:26 [WARNING] - 30154 +2023-08-04 14:52:26 [DEBUG] - 30501 +2023-08-04 14:52:26 [ERROR] Permission denied - 19414 +2023-08-04 14:52:26 [ERROR] File not found - 3013 +2023-08-04 14:52:26 [WARNING] - 11558 +2023-08-04 14:52:26 [INFO] - 21963 +2023-08-04 14:52:26 [INFO] - 4617 +2023-08-04 14:52:26 [WARNING] - 17018 +2023-08-04 14:52:26 [ERROR] Invalid input - 12028 +2023-08-04 14:52:26 [DEBUG] - 3582 +2023-08-04 14:52:26 [INFO] - 18181 +2023-08-04 14:52:26 [INFO] - 9138 +2023-08-04 14:52:26 [INFO] - 11748 +2023-08-04 14:52:26 [WARNING] - 22248 +2023-08-04 14:52:26 [ERROR] Timeout - 15694 +2023-08-04 14:52:26 [INFO] - 13460 +2023-08-04 14:52:26 [DEBUG] - 16467 +2023-08-04 14:52:26 [WARNING] - 22282 +2023-08-04 14:52:26 [ERROR] Connection refused - 8296 +2023-08-04 14:52:26 [WARNING] - 32485 +2023-08-04 14:52:26 [WARNING] - 30208 +2023-08-04 14:52:26 [ERROR] Failed to connect - 7828 +2023-08-04 14:52:26 [WARNING] - 26089 +2023-08-04 14:52:26 [CRITICAL] - 12532 +2023-08-04 14:52:26 [CRITICAL] - 28216 +2023-08-04 14:52:26 [CRITICAL] - 31835 +2023-08-04 14:52:26 [CRITICAL] - 5721 +2023-08-04 14:52:26 [ERROR] Invalid input - 1841 +2023-08-04 14:52:26 [INFO] - 16739 +2023-08-04 14:52:26 [INFO] - 18902 +2023-08-04 14:52:26 [ERROR] Out of memory - 30781 +2023-08-04 14:52:26 [INFO] - 23672 +2023-08-04 14:52:26 [WARNING] - 4280 +2023-08-04 14:52:26 [WARNING] - 559 +2023-08-04 14:52:26 [INFO] - 12348 +2023-08-04 14:52:26 [INFO] - 10787 +2023-08-04 14:52:26 [INFO] - 28531 +2023-08-04 14:52:26 [CRITICAL] - 11648 +2023-08-04 14:52:26 [INFO] - 3373 +2023-08-04 14:52:26 [DEBUG] - 23950 +2023-08-04 14:52:26 [INFO] - 8698 +2023-08-04 14:52:26 [CRITICAL] - 8364 +2023-08-04 14:52:26 [INFO] - 22653 +2023-08-04 14:52:26 [CRITICAL] - 24481 +2023-08-04 14:52:26 [ERROR] Failed to connect - 30723 +2023-08-04 14:52:26 [ERROR] Permission denied - 9708 +2023-08-04 14:52:26 [DEBUG] - 7780 +2023-08-04 14:52:26 [INFO] - 32052 +2023-08-04 14:52:26 [INFO] - 6071 +2023-08-04 14:52:26 [CRITICAL] - 5536 +2023-08-04 14:52:26 [INFO] - 9213 +2023-08-04 14:52:26 [ERROR] Failed to connect - 13655 +2023-08-04 14:52:26 [ERROR] Segmentation fault - 24765 +2023-08-04 14:52:26 [ERROR] Disk full - 22656 +2023-08-04 14:52:26 [INFO] - 12725 +2023-08-04 14:52:26 [ERROR] Failed to connect - 30138 +2023-08-04 14:52:26 [WARNING] - 13200 +2023-08-04 14:52:26 [CRITICAL] - 6033 +2023-08-04 14:52:26 [ERROR] Out of memory - 21286 +2023-08-04 14:52:26 [CRITICAL] - 12167 +2023-08-04 14:52:26 [WARNING] - 11477 +2023-08-04 14:52:26 [DEBUG] - 1772 +2023-08-04 14:52:26 [ERROR] Failed to connect - 29799 +2023-08-04 14:52:26 [DEBUG] - 27700 +2023-08-04 14:52:26 [DEBUG] - 31273 +2023-08-04 14:52:26 [INFO] - 22357 +2023-08-04 14:52:26 [INFO] - 28049 +2023-08-04 14:52:26 [ERROR] Failed to connect - 673 +2023-08-04 14:52:26 [ERROR] Failed to connect - 18574 +2023-08-04 14:52:26 [CRITICAL] - 14222 +2023-08-04 14:52:26 [DEBUG] - 6903 +2023-08-04 14:52:26 [ERROR] Failed to connect - 22902 +2023-08-04 14:52:26 [WARNING] - 27662 +2023-08-04 14:52:26 [INFO] - 25500 +2023-08-04 14:52:26 [DEBUG] - 12913 +2023-08-04 14:52:26 [CRITICAL] - 10208 +2023-08-04 14:52:26 [ERROR] Connection refused - 22778 +2023-08-04 14:52:26 [CRITICAL] - 32682 +2023-08-04 14:52:26 [INFO] - 5396 +2023-08-04 14:52:26 [WARNING] - 31589 +2023-08-04 14:52:26 [ERROR] Segmentation fault - 8068 +2023-08-04 14:52:26 [ERROR] Permission denied - 22422 +2023-08-04 14:52:26 [ERROR] Connection refused - 28923 +2023-08-04 14:52:26 [CRITICAL] - 5664 +2023-08-04 14:52:26 [WARNING] - 19833 +2023-08-04 14:52:26 [ERROR] Timeout - 23972 +2023-08-04 14:52:26 [DEBUG] - 3304 +2023-08-04 14:52:26 [CRITICAL] - 2668 +2023-08-04 14:52:26 [DEBUG] - 29447 +2023-08-04 14:52:26 [ERROR] Segmentation fault - 11938 +2023-08-04 14:52:26 [ERROR] Segmentation fault - 2920 +2023-08-04 14:52:26 [CRITICAL] - 5712 +2023-08-04 14:52:26 [DEBUG] - 6661 +2023-08-04 14:52:26 [ERROR] File not found - 27703 +2023-08-04 14:52:26 [INFO] - 7797 +2023-08-04 14:52:26 [DEBUG] - 32110 +2023-08-04 14:52:26 [DEBUG] - 29872 +2023-08-04 14:52:26 [DEBUG] - 18823 +2023-08-04 14:52:26 [DEBUG] - 8759 +2023-08-04 14:52:26 [ERROR] Out of memory - 12972 +2023-08-04 14:52:26 [INFO] - 2809 +2023-08-04 14:52:26 [CRITICAL] - 14774 +2023-08-04 14:52:26 [WARNING] - 16261 +2023-08-04 14:52:26 [INFO] - 4840 +2023-08-04 14:52:26 [CRITICAL] - 5768 +2023-08-04 14:52:26 [ERROR] Disk full - 28425 +2023-08-04 14:52:26 [DEBUG] - 23030 +2023-08-04 14:52:26 [WARNING] - 25725 +2023-08-04 14:52:26 [ERROR] Invalid input - 21859 +2023-08-04 14:52:26 [INFO] - 28266 +2023-08-04 14:52:26 [ERROR] Timeout - 16689 +2023-08-04 14:52:26 [INFO] - 23673 +2023-08-04 14:52:26 [WARNING] - 10699 +2023-08-04 14:52:26 [DEBUG] - 26415 +2023-08-04 14:52:26 [WARNING] - 2063 +2023-08-04 14:52:26 [INFO] - 16976 +2023-08-04 14:52:26 [INFO] - 14631 +2023-08-04 14:52:26 [WARNING] - 21362 +2023-08-04 14:52:26 [ERROR] File not found - 27946 +2023-08-04 14:52:26 [WARNING] - 2026 +2023-08-04 14:52:26 [CRITICAL] - 23214 +2023-08-04 14:52:26 [WARNING] - 3761 +2023-08-04 14:52:26 [WARNING] - 21427 +2023-08-04 14:52:26 [DEBUG] - 574 +2023-08-04 14:52:26 [INFO] - 11668 +2023-08-04 14:52:26 [DEBUG] - 9878 +2023-08-04 14:52:26 [WARNING] - 19535 +2023-08-04 14:52:27 [CRITICAL] - 11714 +2023-08-04 14:52:27 [ERROR] Disk full - 4261 +2023-08-04 14:52:27 [DEBUG] - 3893 +2023-08-04 14:52:27 [ERROR] File not found - 23236 +2023-08-04 14:52:27 [DEBUG] - 6910 +2023-08-04 14:52:27 [WARNING] - 11290 +2023-08-04 14:52:27 [DEBUG] - 26394 +2023-08-04 14:52:27 [DEBUG] - 30664 +2023-08-04 14:52:27 [ERROR] Disk full - 5324 +2023-08-04 14:52:27 [DEBUG] - 28515 +2023-08-04 14:52:27 [CRITICAL] - 5122 +2023-08-04 14:52:27 [WARNING] - 23106 +2023-08-04 14:52:27 [INFO] - 3684 +2023-08-04 14:52:27 [WARNING] - 22112 +2023-08-04 14:52:27 [INFO] - 31316 +2023-08-04 14:52:27 [DEBUG] - 9765 +2023-08-04 14:52:27 [ERROR] Timeout - 18510 +2023-08-04 14:52:27 [DEBUG] - 14232 +2023-08-04 14:52:27 [ERROR] Failed to connect - 8488 +2023-08-04 14:52:27 [ERROR] Failed to connect - 7400 +2023-08-04 14:52:27 [ERROR] Invalid input - 13443 +2023-08-04 14:52:27 [DEBUG] - 6485 +2023-08-04 14:52:27 [CRITICAL] - 19055 +2023-08-04 14:52:27 [CRITICAL] - 5441 +2023-08-04 14:52:27 [INFO] - 27663 +2023-08-04 14:52:27 [DEBUG] - 15634 +2023-08-04 14:52:27 [DEBUG] - 25359 +2023-08-04 14:52:27 [CRITICAL] - 9692 +2023-08-04 14:52:27 [ERROR] Failed to connect - 26895 +2023-08-04 14:52:27 [DEBUG] - 3409 +2023-08-04 14:52:27 [CRITICAL] - 17933 +2023-08-04 14:52:27 [DEBUG] - 19153 +2023-08-04 14:52:27 [DEBUG] - 10522 +2023-08-04 14:52:27 [ERROR] Permission denied - 25136 +2023-08-04 14:52:27 [DEBUG] - 12072 +2023-08-04 14:52:27 [INFO] - 11080 +2023-08-04 14:52:27 [DEBUG] - 20022 diff --git a/Self-solutions/Day_5/readme.txt b/Self-solutions/Day_5/readme.txt new file mode 100644 index 0000000..de56c85 --- /dev/null +++ b/Self-solutions/Day_5/readme.txt @@ -0,0 +1 @@ +Please run "day5_challenge_solution.sh " diff --git a/Self-solutions/Day_6/broken_myst/README.md b/Self-solutions/Day_6/broken_myst/README.md new file mode 100644 index 0000000..12b68e9 --- /dev/null +++ b/Self-solutions/Day_6/broken_myst/README.md @@ -0,0 +1,66 @@ +Please run "day6_mystery_challange_solution.sh " for solution. + +The challenge script mystery.sh has multiple culprits to confuse to understand what this script is doing but when you know the commmands and some important lines then it will be easy to crack the purpose of the file. it took for while for me to understand new commands like rev, and cipher encrypt technique and how it works and all but at the end i cracked it and modified with fully with lot of enhancemens with performance improvement. + +The output of the script as follows + +``` +#checking the content of output file before running the script + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_6/broken_myst# cat output-file.txt +Hello World! + +#running the script with input and output files + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_6/broken_myst# ./day6_mystery_challange_solution.sh input-file.txt output-file.txt + +After 10 times encryption with ROT13 encryption technique on the input file input-file.txt. The output file looks like + +Uryyb Jbeyq! + +The data looks to be in encrypted format. Do you want to decrypt it (Y/N)? Y + +Now the data has been decrypted successfully !! +Showing the content of file below!! + +Hello World! + +The mysterious process is complete. Check the 'output-file.txt' for the result! + +#verifying the output file content + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_6/broken_myst# cat output-file.txt +Hello World! + +#running again and now see the difference if the random number is ODD + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_6/broken_myst# ./day6_mystery_challange_solution.sh input-file.txt output-file.txt + +After 7 times encryption with ROT13 encryption technique on the input file input-file.txt. The output file looks like + +Hello World! + +Exiting .. +The mysterious process is complete. Check the 'output-file.txt' for the result! + + +#Now running again but this time random number will be even number and choose NO to decrypt + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_6/broken_myst# ./day6_mystery_challange_solution.sh input-file.txt output-file.txt + +After 4 times encryption with ROT13 encryption technique on the input file input-file.txt. The output file looks like + +Uryyb Jbeyq! + +The data looks to be in encrypted format. Do you want to decrypt it (Y/N)? N + +Data is not decrypted !!! + +The mysterious process is complete. Check the 'output-file.txt' for the result! + +#verifying the output file content now + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_6/broken_myst# cat output-file.txt +Uryyb Jbeyq! + +``` diff --git a/Self-solutions/Day_6/broken_myst/day6_mystery_challange_solution.sh b/Self-solutions/Day_6/broken_myst/day6_mystery_challange_solution.sh new file mode 100755 index 0000000..8db376c --- /dev/null +++ b/Self-solutions/Day_6/broken_myst/day6_mystery_challange_solution.sh @@ -0,0 +1,163 @@ +#!/bin/bash + +# Welcome to the Mysterious Script Challenge! +# Your task is to unravel the mystery behind this script and understand what it does. +# Once you've deciphered its objective, your mission is to improve the script by adding comments and explanations for clarity. + +# DISCLAIMER: This script is purely fictional and does not perform any harmful actions. +# It's designed to challenge your scripting skills and creativity. + + + + +##################################################################### +# Script Name: day6_mystery_challange_solution.sh +# Author: Salwad Basha Shaik +# Date: August 5, 2023 +# Description: This script contains solution for Day 6-The Mysterious Script as part of BashBlaze: 7 Days of Bash Scripting Challenge. +# Usage: ./day5_mystery_challange_solution.sh +# Email: salvathshaik786143@gmail.com +# LinkedIn: https://www.linkedin.com/in/salwad-basha-shaik/ +# Github: https://github.com/salvathshaik/ +##################################################################### + + + +################################################# +#Day 6 Bash Scripting Challenge: The Mysterious Script + +#Introduction +#Welcome to Day 6 of the 7-day Bash scripting challenge! In this challenge, you will encounter a mysterious Bash script named mystery.sh. The script lacks documentation and comments, leaving its purpose and functionality shrouded in mystery. Your mission is to unravel the secrets of this script, understand its objective, and improve it by adding comments and explanations. + +#Challenge Steps +#Explore the Script +#Begin by examining the contents of mystery.sh. The script contains various Bash commands, functions, or variables without any comments or explanations. Make note of any patterns or interesting code segments that might give you hints about the script's purpose. + +#Run the Script +#Execute mystery.sh using the command bash mystery.sh and observe its behavior. Pay attention to any output or changes in the system that might occur during the script's execution. + +#Debugging and Decoding +#Identify and fix any potential errors or bugs in the script that may prevent it from running correctly. Analyze the logic of the script to understand how it processes data or performs operations. + +#Identify the Objective +#Based on your observations and analysis, determine the main objective of the script. What is it trying to accomplish? Try to reverse-engineer the script's logic to understand its intended purpose. + +#Add Comments and Explanation +#Now that you have a good understanding of the script's purpose, modify mystery.sh to add clear and concise comments at crucial points in the code. Explain the logic behind each major operation and any critical decisions made during the script's execution. + +#Optimize (Optional) +#If you think there are opportunities to optimize the script's performance or make it more efficient, you can implement those changes. However, this step is entirely optional. + + +#################################### + + + +# The Mysterious Function + +mysterious_function() { + + local input_file="$1" + local output_file="$2" + + # + #encrypting the data there in the input file using ROT13 encryption technique and pass it to output file by overridiing. + #ROT13 is a simple encryption technique that rotates each letter in the alphabet by 13 positions. + #It is also known as the Caesar Cipher with a shift of 13. ROT13 operates only on letters and leaves other characters unchanged. + #If it is a lowercase letter from 'a' to 'm', add 13 to its ASCII code. + #If it is a lowercase letter from 'n' to 'z', subtract 13 from its ASCII code. + #If it is an uppercase letter from 'A' to 'M', add 13 to its ASCII code. + #If it is an uppercase letter from 'N' to 'Z', subtract 13 from its ASCII code. + #Keep all other characters (non-letters) unchanged. + tr 'A-Za-z' 'N-ZA-Mn-za-m' < "$input_file" > "$output_file" + + # trying to reverse the text each line of text file in output file But as per analysys it is the culprit to confuse. LOL !! + #Hence, i am commenting the both rev commands + #reason: below we are reversing the each line but again while going to loop we are again re-reversing the lines means again using the same text without reversing like we have data in input-file at the initial time. so commenting these two commands. + + #rev "$output_file" > "reversed_temp.txt" + + # + random_number=$(( ( RANDOM % 10 ) + 1 )) + #set -x + touch temp_enc.txt ##creating the temp file to do the ROT13 technique. + + # Mystery loop: + + #so this loop will not needed but what is assume is , this may used to encrypt the data with random number of times to just to play with the data + #so just using this loop to perform encryption for random number of times and showing the data to the user. + #if random number is ODD then the output file will have the normal text(decrypted text) because we if we perform ROT13 technique on same file for ODD number of times then it will be in decrypted format and including initial encrypt the output file will have decrypted format of the data. for EVEN it will be vise-versa. + for (( i=0; i<$random_number; i++ )); do + # Commenting the below rev command also because no use of above and this command as mentioned above. + #rev "reversed_temp.txt" > "temp_rev.txt" + + # + tr 'A-Za-z' 'N-ZA-Mn-za-m' < "$output_file" > "temp_enc.txt" + + #here one more culprit LOL! but changed as per my requirement to enhance. + mv "temp_enc.txt" "$output_file" #after moving the data from temp file this file will be removed automatically by mv command. + done + + echo + echo "After $random_number times encryption with ROT13 encryption technique on the input file $input_file. The output file looks like " + echo + cat $output_file + echo + + # Clean up temporary files is not required as i did not used this variable so just commenting. + #rm "temp_rev.txt" + + # The mystery continues... + # The script will continue with more operations that you need to figure out! + + #i think the above line also should be culprit to confuse as we don't have any operations to do now. + #encrypting and descrypting is already done. + + #But as a end goal of the script i wanted to show the option to user to descrypt the data in the file by providing the options to chooose. + + if ((random_number % 2 == 0)); then + #if the random_number is even then that means the data is still in encrypted as we already encrypting above the loop one time. + read -p "The data looks to be in encrypted format. Do you want to decrypt it (Y/N)? " userOption + if [ $userOption == "Y" ]; then + touch temp_enc.txt #creating the temp file again to do the decrypting. + tr 'A-Za-z' 'N-ZA-Mn-za-m' < "$output_file" > "temp_enc.txt" + mv "temp_enc.txt" "$output_file" + echo + echo "Now the data has been decrypted successfully !!" + echo "Showing the content of file below!!" + echo + cat $output_file + echo + else + echo + echo "Data is not decrypted !!!" + echo + fi + else + echo "Exiting .." + fi +} + +# Main Script Execution + +# Check if two arguments are provided +if [ $# -ne 2 ]; then + echo "Usage: $0 " + exit 1 +fi + +input_file="$1" +output_file="$2" + +# Check if the input file exists +if [ ! -f "$input_file" ]; then + echo "Error: Input file not found!" + exit 1 +fi + +# Call the mysterious function to begin the process +mysterious_function "$input_file" "$output_file" + +# Display the mysterious output +echo "The mysterious process is complete. Check the '$output_file' for the result!" +echo diff --git a/Self-solutions/Day_6/broken_myst/day6_mystery_solution_practice.sh b/Self-solutions/Day_6/broken_myst/day6_mystery_solution_practice.sh new file mode 100755 index 0000000..de4c06e --- /dev/null +++ b/Self-solutions/Day_6/broken_myst/day6_mystery_solution_practice.sh @@ -0,0 +1,163 @@ +#!/bin/bash + +# Welcome to the Mysterious Script Challenge! +# Your task is to unravel the mystery behind this script and understand what it does. +# Once you've deciphered its objective, your mission is to improve the script by adding comments and explanations for clarity. + +# DISCLAIMER: This script is purely fictional and does not perform any harmful actions. +# It's designed to challenge your scripting skills and creativity. + + + + +##################################################################### +# Script Name: day6_mystery_challange_solution.sh +# Author: Salwad Basha Shaik +# Date: August 5, 2023 +# Description: This script contains solution for Day 6-The Mysterious Script as part of BashBlaze: 7 Days of Bash Scripting Challenge. +# Usage: ./day5_mystery_challange_solution.sh +# Email: salvathshaik786143@gmail.com +# LinkedIn: https://www.linkedin.com/in/salwad-basha-shaik/ +# Github: https://github.com/salvathshaik/ +##################################################################### + + + +################################################# +#Day 6 Bash Scripting Challenge: The Mysterious Script + +#Introduction +#Welcome to Day 6 of the 7-day Bash scripting challenge! In this challenge, you will encounter a mysterious Bash script named mystery.sh. The script lacks documentation and comments, leaving its purpose and functionality shrouded in mystery. Your mission is to unravel the secrets of this script, understand its objective, and improve it by adding comments and explanations. + +#Challenge Steps +#Explore the Script +#Begin by examining the contents of mystery.sh. The script contains various Bash commands, functions, or variables without any comments or explanations. Make note of any patterns or interesting code segments that might give you hints about the script's purpose. + +#Run the Script +#Execute mystery.sh using the command bash mystery.sh and observe its behavior. Pay attention to any output or changes in the system that might occur during the script's execution. + +#Debugging and Decoding +#Identify and fix any potential errors or bugs in the script that may prevent it from running correctly. Analyze the logic of the script to understand how it processes data or performs operations. + +#Identify the Objective +#Based on your observations and analysis, determine the main objective of the script. What is it trying to accomplish? Try to reverse-engineer the script's logic to understand its intended purpose. + +#Add Comments and Explanation +#Now that you have a good understanding of the script's purpose, modify mystery.sh to add clear and concise comments at crucial points in the code. Explain the logic behind each major operation and any critical decisions made during the script's execution. + +#Optimize (Optional) +#If you think there are opportunities to optimize the script's performance or make it more efficient, you can implement those changes. However, this step is entirely optional. + + +#################################### + + + +# The Mysterious Function + +mysterious_function() { + + local input_file="$1" + local output_file="$2" + + # + #encrypting the data there in the input file using ROT13 encryption technique and pass it to output file by overridiing. + #ROT13 is a simple encryption technique that rotates each letter in the alphabet by 13 positions. + #It is also known as the Caesar Cipher with a shift of 13. ROT13 operates only on letters and leaves other characters unchanged. + #If it is a lowercase letter from 'a' to 'm', add 13 to its ASCII code. + #If it is a lowercase letter from 'n' to 'z', subtract 13 from its ASCII code. + #If it is an uppercase letter from 'A' to 'M', add 13 to its ASCII code. + #If it is an uppercase letter from 'N' to 'Z', subtract 13 from its ASCII code. + #Keep all other characters (non-letters) unchanged. + tr 'A-Za-z' 'N-ZA-Mn-za-m' < "$input_file" > "$output_file" + + # trying to reverse the text each line of text file in output file But as per analysys it is the culprit to confuse. LOL !! + #Hence, i am commenting the both rev commands + #reason: below we are reversing the each line but again while going to loop we are again re-reversing the lines means again using the same text without reversing like we have data in input-file at the initial time. so commenting these two commands. + + #rev "$output_file" > "reversed_temp.txt" + + # + random_number=$(( ( RANDOM % 10 ) + 1 )) + set -x + touch temp_enc.txt ##creating the temp file to do the ROT13 technique. + + # Mystery loop: + + #so this loop will not needed but what is assume is , this may used to encrypt the data with random number of times to just to play with the data + #so just using this loop to perform encryption for random number of times and showing the data to the user. + #if random number is ODD then the output file will have the normal text(decrypted text) because we if we perform ROT13 technique on same file for ODD number of times then it will be in decrypted format and including initial encrypt the output file will have decrypted format of the data. for EVEN it will be vise-versa. + for (( i=0; i<$random_number; i++ )); do + # Commenting the below rev command also because no use of above and this command as mentioned above. + #rev "reversed_temp.txt" > "temp_rev.txt" + + # + tr 'A-Za-z' 'N-ZA-Mn-za-m' < "$output_file" > "temp_enc.txt" + + #here one more culprit LOL! but changed as per my requirement to enhance. + mv "temp_enc.txt" "$output_file" #after moving the data from temp file this file will be removed automatically by mv command. + done + + echo + echo "After $random_number times encryption with ROT13 encryption technique. The output file looks like " + echo + cat $output_file + echo + + # Clean up temporary files is not required as i did not used this variable so just commenting. + #rm "temp_rev.txt" + + # The mystery continues... + # The script will continue with more operations that you need to figure out! + + #i think the above line also should be culprit to confuse as we don't have any operations to do now. + #encrypting and descrypting is already done. + + #But as a end goal of the script i wanted to show the option to user to descrypt the data in the file by providing the options to chooose. + + if ((random_number % 2 == 0)); then + #if the random_number is even then that means the data is still in encrypted as we already encrypting above the loop one time. + read -p "The data looks to be in encrypted format. Do you want to decrypt it (Y/N)? " userOption + if [ $userOption == "Y" ]; then + touch temp_enc.txt #creating the temp file again to do the decrypting. + tr 'A-Za-z' 'N-ZA-Mn-za-m' < "$output_file" > "temp_enc.txt" + mv "temp_enc.txt" "$output_file" + echo + echo "Now the data has been decrypted successfully !!" + echo "Showing the content of file below!!" + echo + cat $output_file + echo + else + echo + echo "Data is not decrypted !!!" + echo + fi + else + echo "Exiting .." + fi +} + +# Main Script Execution + +# Check if two arguments are provided +if [ $# -ne 2 ]; then + echo "Usage: $0 " + exit 1 +fi + +input_file="$1" +output_file="$2" + +# Check if the input file exists +if [ ! -f "$input_file" ]; then + echo "Error: Input file not found!" + exit 1 +fi + +# Call the mysterious function to begin the process +mysterious_function "$input_file" "$output_file" + +# Display the mysterious output +echo "The mysterious process is complete. Check the '$output_file' for the result!" +echo diff --git a/Self-solutions/Day_6/broken_myst/input-file.txt b/Self-solutions/Day_6/broken_myst/input-file.txt new file mode 100644 index 0000000..980a0d5 --- /dev/null +++ b/Self-solutions/Day_6/broken_myst/input-file.txt @@ -0,0 +1 @@ +Hello World! diff --git a/Self-solutions/Day_6/broken_myst/mystery.sh b/Self-solutions/Day_6/broken_myst/mystery.sh new file mode 100644 index 0000000..dba59f3 --- /dev/null +++ b/Self-solutions/Day_6/broken_myst/mystery.sh @@ -0,0 +1,64 @@ +#!/bin/bash + +# Welcome to the Mysterious Script Challenge! +# Your task is to unravel the mystery behind this script and understand what it does. +# Once you've deciphered its objective, your mission is to improve the script by adding comments and explanations for clarity. + +# DISCLAIMER: This script is purely fictional and does not perform any harmful actions. +# It's designed to challenge your scripting skills and creativity. + +# The Mysterious Function +mysterious_function() { + local input_file="$1" + local output_file="$2" + + # + tr 'A-Za-z' 'N-ZA-Mn-za-m' < "$input_file" > "$output_file" + + # + rev "$output_file" > "reversed_temp.txt" + + # + random_number=$(( ( RANDOM % 10 ) + 1 )) + + # Mystery loop: + for (( i=0; i<$random_number; i++ )); do + # + rev "reversed_temp.txt" > "temp_rev.txt" + + # + tr 'A-Za-z' 'N-ZA-Mn-za-m' < "temp_rev.txt" > "temp_enc.txt" + + # + mv "temp_enc.txt" "reversed_temp.txt" + done + + # Clean up temporary files + rm "temp_rev.txt" + + # The mystery continues... + # The script will continue with more operations that you need to figure out! +} + +# Main Script Execution + +# Check if two arguments are provided +if [ $# -ne 2 ]; then + echo "Usage: $0 " + exit 1 +fi + +input_file="$1" +output_file="$2" + +# Check if the input file exists +if [ ! -f "$input_file" ]; then + echo "Error: Input file not found!" + exit 1 +fi + +# Call the mysterious function to begin the process +mysterious_function "$input_file" "$output_file" + +# Display the mysterious output +echo "The mysterious process is complete. Check the '$output_file' for the result!" diff --git a/Self-solutions/Day_6/broken_myst/output-file.txt b/Self-solutions/Day_6/broken_myst/output-file.txt new file mode 100644 index 0000000..20bfe77 --- /dev/null +++ b/Self-solutions/Day_6/broken_myst/output-file.txt @@ -0,0 +1 @@ +Uryyb Jbeyq! diff --git a/Self-solutions/Day_6/broken_myst/readme.txt b/Self-solutions/Day_6/broken_myst/readme.txt new file mode 100644 index 0000000..6d7b56b --- /dev/null +++ b/Self-solutions/Day_6/broken_myst/readme.txt @@ -0,0 +1 @@ +Please run './day6_mystery_challange_solution.sh ' for solution diff --git a/Self-solutions/Day_6/broken_resto/README.md b/Self-solutions/Day_6/broken_resto/README.md new file mode 100644 index 0000000..0ce66b0 --- /dev/null +++ b/Self-solutions/Day_6/broken_resto/README.md @@ -0,0 +1,198 @@ + +Please Run the script "day6_resto_challange_solution.sh" and choose the options to process the order. + +This script will take inputs + - customer name + - item number and item quantity + +And perform the total amount based on each item price and the quantity. + +Used menu.txt file read the menu items and this file can change means you can add as many items with prices at the end like existed ones. our script wil take dynamically and display the user with the menu and calculate the total. + +Script is desinged to handle multiple errors as well validated the user inputs before process the order. + +Sample output of the script as follows... + + +``` + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_6/broken_resto# ./day6_resto_challange_solution.sh + +Welcome to the Restaurant! +Menu: +1. Burger - 120 +2. Pizza - 250 +3. Salad - 180 +4. Soda - 40 +5. Pasta - 180 +6. Sandwich - 150 +7. Coke - 50 +8. Fries - 100 +9. IceCream - 120 +10. EggPuff - 20 +Please enter your name to continue with the order: salwad basha shaik +Please enter the item number and quantity (e.g., 1 2 for two Burgers): +3 4 + +Thank you, salwad basha shaik! Your total bill is 720. + +Do you want to order more items (Y/N)? Y + +Welcome to the Restaurant! +Menu: +1. Burger - 120 +2. Pizza - 250 +3. Salad - 180 +4. Soda - 40 +5. Pasta - 180 +6. Sandwich - 150 +7. Coke - 50 +8. Fries - 100 +9. IceCream - 120 +10. EggPuff - 20 +Please enter your name to continue with the order: salwad basha shaik +Please enter the item number and quantity (e.g., 1 2 for two Burgers): +10 20 + +Thank you, salwad basha shaik! Your total bill is 400. + +Do you want to order more items (Y/N)? N + +Exiting... + +#handline invalid inputs + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_6/broken_resto# ./day6_resto_challange_solution.sh + +Welcome to the Restaurant! +Menu: +1. Burger - 120 +2. Pizza - 250 +3. Salad - 180 +4. Soda - 40 +5. Pasta - 180 +6. Sandwich - 150 +7. Coke - 50 +8. Fries - 100 +9. IceCream - 120 +10. EggPuff - 20 +Please enter your name to continue with the order: salwad +Please enter the item number and quantity (e.g., 1 2 for two Burgers): +-1 20 + +Invalid item number! Please enter a valid item number between 1 to 9. + +#one more invalid input + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_6/broken_resto# ./day6_resto_challange_solution.sh + +Welcome to the Restaurant! +Menu: +1. Burger - 120 +2. Pizza - 250 +3. Salad - 180 +4. Soda - 40 +5. Pasta - 180 +6. Sandwich - 150 +7. Coke - 50 +8. Fries - 100 +9. IceCream - 120 +10. EggPuff - 20 +Please enter your name to continue with the order: salwad +Please enter the item number and quantity (e.g., 1 2 for two Burgers): +12 20 + +Invalid item number! Please enter a valid item number between 1 to 9. + + +#one more + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_6/broken_resto# ./day6_resto_challange_solution.sh + +Welcome to the Restaurant! +Menu: +1. Burger - 120 +2. Pizza - 250 +3. Salad - 180 +4. Soda - 40 +5. Pasta - 180 +6. Sandwich - 150 +7. Coke - 50 +8. Fries - 100 +9. IceCream - 120 +10. EggPuff - 20 +Please enter your name to continue with the order: salwad basha +Please enter the item number and quantity (e.g., 1 2 for two Burgers): +7 -12 + +Invalid quantity entered! Please enter a valid quantity in numbers. + + +#more scenarios + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_6/broken_resto# ./day6_resto_challange_solution.sh + +Welcome to the Restaurant! +Menu: +1. Burger - 120 +2. Pizza - 250 +3. Salad - 180 +4. Soda - 40 +5. Pasta - 180 +6. Sandwich - 150 +7. Coke - 50 +8. Fries - 100 +9. IceCream - 120 +10. EggPuff - 20 +Please enter your name to continue with the order: basha +Please enter the item number and quantity (e.g., 1 2 for two Burgers): + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_6/broken_resto# ./day6_resto_challange_solution.sh + +Welcome to the Restaurant! +Menu: +1. Burger - 120 +2. Pizza - 250 +3. Salad - 180 +4. Soda - 40 +5. Pasta - 180 +6. Sandwich - 150 +7. Coke - 50 +8. Fries - 100 +9. IceCream - 120 +10. EggPuff - 20 +Please enter your name to continue with the order: salwad +Please enter the item number and quantity (e.g., 1 2 for two Burgers): +1 5 + +Thank you, salwad! Your total bill is 600. + +Do you want to order more items (Y/N)? Y + +Welcome to the Restaurant! +Menu: +1. Burger - 120 +2. Pizza - 250 +3. Salad - 180 +4. Soda - 40 +5. Pasta - 180 +6. Sandwich - 150 +7. Coke - 50 +8. Fries - 100 +9. IceCream - 120 +10. EggPuff - 20 +Please enter your name to continue with the order: salwad +Please enter the item number and quantity (e.g., 1 2 for two Burgers): +3 4 + +Thank you, salwad! Your total bill is 720. + +Do you want to order more items (Y/N)? N + +Exiting... + + +``` + + + diff --git a/Self-solutions/Day_6/broken_resto/day6_resto_challange_solution.sh b/Self-solutions/Day_6/broken_resto/day6_resto_challange_solution.sh new file mode 100755 index 0000000..8c3a2ec --- /dev/null +++ b/Self-solutions/Day_6/broken_resto/day6_resto_challange_solution.sh @@ -0,0 +1,203 @@ +#!/bin/bash + + + +##################################################################### +# Script Name: day6_resto_challange_solution.sh +# Author: Salwad Basha Shaik +# Date: August 3, 2023 +# Description: This script contains solution for Day 6 Restaurant Order System Challenge as part of BashBlaze: 7 Days of Bash Scripting Challenge. +# Usage: ./day6_resto_challange_solution.sh +# Email: salvathshaik786143@gmail.com +# LinkedIn: https://www.linkedin.com/in/salwad-basha-shaik/ +# Github: https://github.com/salvathshaik/ +##################################################################### + + +#Challenge Description + + +#In this challenge, you will be working on a Bash-based restaurant order system. The provided script, restaurant_order.sh, is partially broken and missing some crucial parts. Your task is to fix and complete the script to create a fully functional restaurant order system. + +#The Broken Script +#The restaurant_order.sh script is provided to you, but some essential parts are missing or not functioning correctly. Here are the broken parts: + +#Missing Menu Display: The script is missing the code to read and display the menu from the menu.txt file. You need to implement the function to read the menu and display it to the customers. + +#Invalid User Input Handling: The script is not handling invalid user input, such as entering a non-existent item number or negative quantities. You need to implement error handling to prompt users for valid inputs when necessary. + +#Total Bill Calculation: The script is not calculating the correct total bill based on the customer's order. You need to implement the function to calculate the total bill accurately. + +#Your Task +#Your mission is to complete the restaurant_order.sh script and make it fully functional. Once you fix all the broken parts, the script should provide a smooth dining experience for our customers. + + +############################### + + + +# Function to read and display the menu from menu.txt file +function display_menu() { + echo + echo "Welcome to the Restaurant!" + echo "Menu: " + + + file_name="menu.txt" + # Check if the file exists + if [ ! -f "$file_name" ]; then + echo "File not found: $file_name. please check!!!" + exit 1 + fi + + + # Loop through each line in the file + while IFS= read -r line; do + # Process the item name and item price variables here + cleaned_line=$(echo "$line" | tr -d '[:space:]') + + # Split the cleaned line into string and integer variables + IFS=',' read -r item_name item_price <<< "$cleaned_line" + declare -i int_variable="$item_price" + echo "$line_number. $item_name - $item_price" + + main_menu_index=$(( line_number - 1 )) + line_number=$(( line_number + 1 )) + main_menu[$main_menu_index]="$int_variable" + + done < "$file_name" + + #explanation: + #The IFS= read -r line command reads a line from the file and stores it in the variable line. + #To remove spaces and newlines from the line used the tr command. The tr -d '[:space:]' command removes all whitespace characters from the line + #used IFS=',' read -r string_val integer_val <<< "$cleaned_line" to split the cleaned_line into two variables: string_val and integer_val. + #The <<< notation is called a here-string, which is used to pass the value of cleaned_line as input to the read command. + #declare -i int_variable="$integer_val" declares a new integer variable called int_variable and assigns the value of integer_val to it. + #otherwise we will not gonna use it for our calculation as this will be treat as string at initial time +} + + +# Function to calculate the total bill +function calculate_total_bill() { + local total=0 + + #looping through all the order items and calculate the total + for item_number in "${!order[@]}"; do #${!order[@]}: this is to repeat till total order items. here in for loop we will get key value item_number + item_count="${order[$item_number]}" #extracting item count from order associative array with itemnumber + + item_index_number_in_main_menu=$((item_number - 1)) #we are decreasing value by one as i have store menu items from 0 in main_menu assoc array. + + price="${main_menu[$item_index_number_in_main_menu]}" #getting price based on main menu index from main menu array + total=$((price * item_count)) #total is price *no of items. + done + + echo "$total" +} + +# Function to handle invalid user input +function handle_invalid_input() { + + item_number="${input_order[0]}" + quantity="${input_order[1]}" + #validating if user entered any negative or other tahn the total count of items for both the inputs item number and item count. + if [ ! $item_number -le $line_number ] || [ $item_number -le 0 ]; then + echo + echo "Invalid item number! Please enter a valid item number between 1 to 9." + echo + exit 1 + fi + + if [ $quantity -le 0 ]; then + echo + echo "Invalid quantity entered! Please enter a valid quantity in numbers." + echo + exit 1 + fi + +} + + +#function is created to use it for multiple times based on user option after the first order run. +starting_the_restaurant_system() { + +#declaring these two associative array as well as line_number variable as we will be gonna use this whenever possible in script. +declare -A main_menu +line_number=1 +# Main script +display_menu + +#storing menu +#declare -A main_menu +#main_menu[0]=120 +#main_menu[1]=250 +#main_menu[2]=180 +#main_menu[3]=40 +#main_menu[4]=180 +#main_menu[5]=150 +#main_menu[6]=50 +#main_menu[7]=100 +#main_menu[8]=120 + +#declare -A main_menu + +read -p "Please enter your name to continue with the order: " customer_name + +echo "Please enter the item number and quantity (e.g., 1 2 for two Burgers):" +read -a input_order + + +#calling this function to valiadate the user inputs. +handle_invalid_input + +# Process the customer's order +declare -A order + +#storing the order items using assocaitive array item as a key and quantity as a value. +for (( i=0; i<${#input_order[@]}; i+=2 )); do + item_number="${input_order[i]}" + quantity="${input_order[i+1]}" + + + order["$item_number"]=$quantity #storiing the value with key here + + + +done + +# Calculate the total bill +total_bill=$(calculate_total_bill) +echo +echo "Thank you, $customer_name! Your total bill is $total_bill." +echo + +} + + +#this will run first and started the system. +starting_the_restaurant_system + + +#after above function runs means if user done with first order then provide option to choose to order multiple times and calling the above function again to process the order. if user chooses No then it infinite loop will end. + +while true; do + + read -p "Do you want to order more items (Y/N)? " more_item_option + if [ $more_item_option == "Y" ] || [ $more_item_option == "N" ]; then + + if [ $more_item_option == "Y" ]; then + starting_the_restaurant_system + else + echo + echo "Exiting..." + echo + break + fi + else + echo + echo "Invalid Option please try again !!" + echo + fi + +done + + diff --git a/Self-solutions/Day_6/broken_resto/day6_resto_solution_practice.sh b/Self-solutions/Day_6/broken_resto/day6_resto_solution_practice.sh new file mode 100644 index 0000000..e69de29 diff --git a/Self-solutions/Day_6/broken_resto/menu.txt b/Self-solutions/Day_6/broken_resto/menu.txt new file mode 100644 index 0000000..523ce00 --- /dev/null +++ b/Self-solutions/Day_6/broken_resto/menu.txt @@ -0,0 +1,10 @@ +Burger, 120 +Pizza, 250 +Salad, 180 +Soda, 40 +Pasta, 180 +Sandwich, 150 +Coke, 50 +Fries, 100 +Ice Cream, 120 +Egg Puff, 20 diff --git a/Self-solutions/Day_6/broken_resto/readme.txt b/Self-solutions/Day_6/broken_resto/readme.txt new file mode 100644 index 0000000..2b61792 --- /dev/null +++ b/Self-solutions/Day_6/broken_resto/readme.txt @@ -0,0 +1 @@ +Please run "day6_resto_challange_solution.sh" for the solution diff --git a/Self-solutions/Day_6/broken_resto/restaurant_order.sh b/Self-solutions/Day_6/broken_resto/restaurant_order.sh new file mode 100644 index 0000000..2f64c3e --- /dev/null +++ b/Self-solutions/Day_6/broken_resto/restaurant_order.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +# Function to read and display the menu from menu.txt file +function display_menu() { + echo "Welcome to the Restaurant!" + echo "Menu:" + # TODO: Read the menu from menu.txt and display item numbers and prices + # Format: 1. Burger - ₹120 + # 2. Pizza - ₹250 + # 3. Salad - ₹180 + # ... +} + +# Function to calculate the total bill +function calculate_total_bill() { + local total=0 + # TODO: Calculate the total bill based on the customer's order + # The order information will be stored in an array "order" + # The array format: order[] = + # Prices are available in the same format as the menu display + # Example: If the customer ordered 2 Burgers and 1 Salad, the array will be: + # order[1]=2, order[3]=1 + # The total bill should be the sum of (price * quantity) for each item in the order. + # Store the calculated total in the "total" variable. + echo "$total" +} + +# Function to handle invalid user input +function handle_invalid_input() { + echo "Invalid input! Please enter a valid item number and quantity." +} + +# Main script +display_menu + +# Ask for the customer's name +# TODO: Ask the customer for their name and store it in a variable "customer_name" + +# Ask for the order +echo "Please enter the item number and quantity (e.g., 1 2 for two Burgers):" +read -a input_order + +# Process the customer's order +declare -A order +for (( i=0; i<${#input_order[@]}; i+=2 )); do + item_number="${input_order[i]}" + quantity="${input_order[i+1]}" + # TODO: Add the item number and quantity to the "order" array +done + +# Calculate the total bill +total_bill=$(calculate_total_bill) + +# Display the total bill with a personalized thank-you message +# TODO: Display a thank-you message to the customer along with the total bill +# The message format: "Thank you, ! Your total bill is ₹." + diff --git a/Self-solutions/Day_6/broken_search/README.md b/Self-solutions/Day_6/broken_search/README.md new file mode 100644 index 0000000..bed9c82 --- /dev/null +++ b/Self-solutions/Day_6/broken_search/README.md @@ -0,0 +1,47 @@ +Please run the script "day6_search_challange_solution.sh " for the solution. + +This script will return the path of the file that you wanted to search in current directory or in all its subdirectories. + +This script will handle the file and directory presence before processing. + +Output of the file will look like as below + + + + +``` +#Below is the file directory structure that is created for demo purpose with all the directories. + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_6/broken_search# tree testDirectory/ +testDirectory/ +├── test1 +│   └── test1sub +│   ├── test1sub-file.txt +│   └── test1sub.txt +├── test2 +│   └── test2-file.txt +│   └── test2-file.txt +└── test3 + +5 directories, 3 files + +#running the script with wrong directory + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_6/broken_search# ./day6_search_challange_solution.sh testDirectory-dummy/ test1sub-file.txt + +Error: Directory 'testDirectory-dummy/' is not found. Please provide the correct directory !!! + +#running now with file that is not present + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_6/broken_search# ./day6_search_challange_solution.sh testDirectory/ test1sub-file-2.txt +File not found: test1sub-file-2.txt + + +#running the script to search test1sub-file.txt file + +root@ip-172-31-91-38:~/BashBlaze-7-Days-of-Bash-Scripting-Challenge/Self-solutions/Day_6/broken_search# ./day6_search_challange_solution.sh testDirectory/ test1sub-file.txt +File has been found in the path: testDirectory//test1/test1sub/test1sub-file.txt + + +``` + diff --git a/Self-solutions/Day_6/broken_search/day6_search_challange_solution.sh b/Self-solutions/Day_6/broken_search/day6_search_challange_solution.sh new file mode 100755 index 0000000..7bca500 --- /dev/null +++ b/Self-solutions/Day_6/broken_search/day6_search_challange_solution.sh @@ -0,0 +1,97 @@ +#!/bin/bash + + +##################################################################### +# Script Name: day6_search_challange_solution.sh +# Author: Salwad Basha Shaik +# Date: August 4, 2023 +# Description: This script contains solution for Day 5-Log Analyzer and Report Generator as part of BashBlaze: 7 Days of Bash Scripting Challenge. +# Usage: ./day6_search_challange_solution.sh +# Email: salvathshaik786143@gmail.com +# LinkedIn: https://www.linkedin.com/in/salwad-basha-shaik/ +# Github: https://github.com/salvathshaik/ +##################################################################### + + + +###################### + +##Recursive Directory Search Challenge +# +#Description +#The "Recursive Directory Search" challenge is part of the day-6. In this challenge, participants are tasked with creating a Bash script that performs a recursive search for a specific file within a given directory and its subdirectories. The script provided for this challenge is not functioning correctly, and participants must fix and improve it to achieve the desired behavior. + + +#Challenge Details +#Objective: Your goal is to fix the provided Bash script, recursive_search.sh, and ensure it performs the recursive search as described below: + +#The script should take two command-line arguments: the directory to start the search and the target file name to find. +#The search should be recursive, meaning it should look for the target file not only in the specified directory but also in all its subdirectories and their subdirectories, and so on. +#When the target file is found, the script should print the absolute path of the file and then exit. +#Proper error handling should be in place to handle cases where the directory does not exist or the target file is not found. + +#If the target file target.txt exists within any of the subdirectories of test_files, the script should print the absolute path of the file. Otherwise, it should print "File not found: target.txt". + + + + +##################### + + +#checking if user provided two arguments or not +if [ $# -ne 2 ]; then + echo "Usage: ./recursive_search.sh " + exit 1 +fi + + +search_directory=$1 +target_file=$2 + + + +# Checking if the specified directory exists or not +if [ ! -d "$search_directory" ]; then + echo + echo "Error: Directory '$search_directory' is not found. Please provide the correct directory !!!" + echo + exit 1 +fi + + +#Implementing the recursive search logic here + +#this function will search in all sub directories and return the path of the file. +search_the_file() { + + local dir_to_search="$1" + + # Loop through each file in the directory + for file in "$dir_to_search"/*; do #this will search all the directories + # Checking if the current file is the one we are looking for or not + if [ -f "$file" ] && [ "$(basename "$file")" = "$target_file" ]; then + echo "File has been found in the path: $file" + exit 1 #existing after i found the file otherwise it will keep on looing for the file. + + + # Check if the current file is a directory, then recursively search in it to go to subdirectories + elif [ -d "$file" ]; then + search_the_file "$file" "$target_file" + fi + done + + #explanation + #"$file": This is the variable that contains the current file or directory path. It is taken from the loop, + #basename "$file": The basename command is used to extract the base name of the file or directory from the full path. + #"$(basename "$file")": The $(...) syntax is used for command substitution. It executes the command within the parentheses and replaces it with the command's output. + #So, $(basename "$file") gives us the base name of the current file. + #" = ": This is a comparison operator. It checks if the base name of the current file is equal to the target filename. + +} + +search_the_file $1 $2 + +echo "File not found: $target_file" +exit 1 + + diff --git a/Self-solutions/Day_6/broken_search/day6_search_solution_practice.sh b/Self-solutions/Day_6/broken_search/day6_search_solution_practice.sh new file mode 100644 index 0000000..e69de29 diff --git a/Self-solutions/Day_6/broken_search/readme.txt b/Self-solutions/Day_6/broken_search/readme.txt new file mode 100644 index 0000000..325cd9a --- /dev/null +++ b/Self-solutions/Day_6/broken_search/readme.txt @@ -0,0 +1 @@ +Please run "day6_search_challange_solution.sh " for the solution. diff --git a/Self-solutions/Day_6/broken_search/recursive_search.sh b/Self-solutions/Day_6/broken_search/recursive_search.sh new file mode 100644 index 0000000..501af36 --- /dev/null +++ b/Self-solutions/Day_6/broken_search/recursive_search.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +if [ $# -ne 2 ]; then + echo "Usage: ./recursive_search.sh " + exit 1 +fi + +search_directory=$1 +target_file=$2 + +# TODO: Implement the recursive search logic here + +echo "File not found: $target_file" +exit 1 diff --git a/Self-solutions/Day_6/broken_search/testDirectory/test1/test1sub/test1sub-file.txt b/Self-solutions/Day_6/broken_search/testDirectory/test1/test1sub/test1sub-file.txt new file mode 100644 index 0000000..e69de29 diff --git a/Self-solutions/Day_6/broken_search/testDirectory/test1/test1sub/test1sub.txt b/Self-solutions/Day_6/broken_search/testDirectory/test1/test1sub/test1sub.txt new file mode 100644 index 0000000..e69de29 diff --git a/Self-solutions/Day_6/broken_search/testDirectory/test2/test2-file.txt/test2-file.txt b/Self-solutions/Day_6/broken_search/testDirectory/test2/test2-file.txt/test2-file.txt new file mode 100644 index 0000000..e69de29 diff --git a/Self-solutions/Day_7/README.md b/Self-solutions/Day_7/README.md new file mode 100644 index 0000000..6752efc --- /dev/null +++ b/Self-solutions/Day_7/README.md @@ -0,0 +1,255 @@ +Please run "day7_challange_solution.sh" for the solution. + +This project is full meals with the shell scripting including devops concepts. + +This script will deploy the sample web application to the nginx as well as docker using shell scripting. + +I have depoloyed a sample flask web application in both nginx and docker environments. + +This script will handle major issues like if application is running already and again if someone try to deploy then it will kill the previous session and re-deploy the updated version. + +Also handles the symlink creation(which is a major part of nginx reverse proxy) if symlink created earlier then it will unlink and re-create again to make sure ngin awareness. + +Below are the snapshots of the project + + + +Created 3 VMs(server, client1 and client2) with the below details. + +![image (1)](https://github.com/salvathshaik/BashBlaze-7-Days-of-Bash-Scripting-Challenge/assets/39498166/a970a49c-d719-4498-b192-cf2010584116) + + +![image (2)](https://github.com/salvathshaik/BashBlaze-7-Days-of-Bash-Scripting-Challenge/assets/39498166/6cb80e5f-0cc3-47ed-a259-656dc61a362c) + + +![image (3)](https://github.com/salvathshaik/BashBlaze-7-Days-of-Bash-Scripting-Challenge/assets/39498166/536c2780-d877-4a0a-842e-e9754a8c218d) + + +And this is the network adapter(bridge adapter) that i have used to communicate with each other VMs. + +![image (4)](https://github.com/salvathshaik/BashBlaze-7-Days-of-Bash-Scripting-Challenge/assets/39498166/00bb9164-2b90-4653-b02b-2b610cc67cdf) + + +Copied the SSH files to both the clients. + +![image (5)](https://github.com/salvathshaik/BashBlaze-7-Days-of-Bash-Scripting-Challenge/assets/39498166/23c5bf85-84c8-4967-98c1-fafa6682f253) + + +Below is the snap while building the docker image. + +![image (6)](https://github.com/salvathshaik/BashBlaze-7-Days-of-Bash-Scripting-Challenge/assets/39498166/b34eed5e-fe03-409d-9562-7bd429f9c1d2) + +![image (7)](https://github.com/salvathshaik/BashBlaze-7-Days-of-Bash-Scripting-Challenge/assets/39498166/b14f8a22-c26d-4a92-97f0-9b8a59c3c783) + + + +Below are the successful remote command execution. + +``` +=1.6.2 in /usr/local/lib/python3.8/dist-packages (from flask) (1.6.2) +Requirement already satisfied: click>=8.1.3 in /usr/local/lib/python3.8/dist-packages (from flask) (8.1.6) +Requirement already satisfied: importlib-metadata>=3.6.0; python_version < "3.10" in /usr/local/lib/python3.8/dist-packages (from flask) (6.8.0) +Requirement already satisfied: Jinja2>=3.1.2 in /usr/local/lib/python3.8/dist-packages (from flask) (3.1.2) +Requirement already satisfied: Werkzeug>=2.3.3 in /usr/local/lib/python3.8/dist-packages (from flask) (2.3.6) +Requirement already satisfied: itsdangerous>=2.1.2 in /usr/local/lib/python3.8/dist-packages (from flask) (2.1.2) +Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.8/dist-packages (from importlib-metadata>=3.6.0; python_version < "3.10"->flask) (3.16.2) +Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.8/dist-packages (from Jinja2>=3.1.2->flask) (2.1.3) + +Completed for Client-1 + +Started for client-2 + +[sudo] password for client2: +WARNING: apt does not have a stable CLI interface. Use with caution in scripts. + +Hit:1 http://in.archive.ubuntu.com/ubuntu focal InRelease +Hit:2 http://in.archive.ubuntu.com/ubuntu focal-updates InRelease +Hit:3 http://security.ubuntu.com/ubuntu focal-security InRelease +Hit:4 http://in.archive.ubuntu.com/ubuntu focal-backports InRelease +Reading package lists... +Building dependency tree... +Reading state information... +53 packages can be upgraded. Run 'apt list --upgradable' to see them. + +WARNING: apt does not have a stable CLI interface. Use with caution in scripts. + +Reading package lists... +Building dependency tree... +Reading state information... +nginx is already the newest version (1.18.0-0ubuntu1.4). +0 upgraded, 0 newly installed, 0 to remove and 53 not upgraded. +[sudo] password for client2: Reading package lists... +Building dependency tree... +Reading state information... +python3-pip is already the newest version (20.0.2-5ubuntu1.9). +0 upgraded, 0 newly installed, 0 to remove and 53 not upgraded. +[sudo] password for client2: Requirement already satisfied: flask in /usr/local/lib/python3.8/dist-packages (2.3.2) +Requirement already satisfied: Werkzeug>=2.3.3 in /usr/local/lib/python3.8/dist-packages (from flask) (2.3.6) +Requirement already satisfied: click>=8.1.3 in /usr/local/lib/python3.8/dist-packages (from flask) (8.1.6) +Requirement already satisfied: importlib-metadata>=3.6.0; python_version < "3.10" in /usr/local/lib/python3.8/dist-packages (from flask) (6.8.0) +Requirement already satisfied: itsdangerous>=2.1.2 in /usr/local/lib/python3.8/dist-packages (from flask) (2.1.2) +Requirement already satisfied: Jinja2>=3.1.2 in /usr/local/lib/python3.8/dist-packages (from flask) (3.1.2) +Requirement already satisfied: blinker>=1.6.2 in /usr/local/lib/python3.8/dist-packages (from flask) (1.6.2) +Requirement already satisfied: MarkupSafe>=2.1.1 in /usr/local/lib/python3.8/dist-packages (from Werkzeug>=2.3.3->flask) (2.1.3) +Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.8/dist-packages (from importlib-metadata>=3.6.0; python_version < "3.10"->flask) (3.16.2) + +Completed for Client-2 + + +Started copying the nginx configurations + +Started for client-1 + +client1-nginx.conf 100% 283 143.2KB/s 00:00 + +Completed for Client-1 + +Started for client-2 + +client2-nginx.conf 100% 283 125.2KB/s 00:00 + +Completed for Client-2 + + +Started Checking if symlink already created for my_app nginx configuration file. + +Started for client-1 + +./day7_challenge_solution.sh: line 73: check_and_unlink_symlink.sh: No such file or directory + +Completed for Client-1 + +Started for client-2 + +./day7_challenge_solution.sh: line 81: check_and_unlink_symlink.sh: No such file or directory + +Completed for Client-2 + + +Started Moving the nginx configurations + +Started for client-1 + +[sudo] password for client1: + +[sudo] password for client1: ln: failed to create symbolic link '/etc/nginx/sites-enabled/my_app': File exists + +Completed for Client-1 + +Started for client-1 + +[sudo] password for client2: + +[sudo] password for client2: ln: failed to create symbolic link '/etc/nginx/sites-enabled/my_app': File exists + +Completed for Client-1 + + +Started copying the flask application code to nginx. + +Started for client-1 + +requirements.txt 100% 19 5.0KB/s 00:00 +app.py 100% 514 140.9KB/s 00:00 +index.html 100% 144 38.6KB/s 00:00 +README.md 100% 1603 338.4KB/s 00:00 +Dockerfile 100% 149 34.4KB/s 00:00 + + +[sudo] password for client1: +Completed for Client-1 + +Started for client-2 + +requirements.txt 100% 19 6.4KB/s 00:00 +app.py 100% 514 192.3KB/s 00:00 +index.html 100% 144 59.8KB/s 00:00 +README.md 100% 1603 581.2KB/s 00:00 +Dockerfile 100% 149 66.8KB/s 00:00 + + +[sudo] password for client2: +Completed for Client-2 + + +Started checking if app.py is running on the BOTH remote hosts . + +app.py is not running on client1@192.168.0.12. +app.py is not running on client2@192.168.0.14. + +Completed the checking.. + + +Running the app in both clients in the background and moving the terminal out to dummy file. + + +Completed Running.. + + +Reloaing the nginx configurations to ensure nginx knows about the changes. + +[sudo] password for client1: [sudo] password for client2: +Completed All tasks.. validate in browser now + +``` + + + +After running the script validating whether application is running in background or not + +![image (11)](https://github.com/salvathshaik/BashBlaze-7-Days-of-Bash-Scripting-Challenge/assets/39498166/827ed759-a7f5-493b-aac6-779e3b0c1d78) + +Validating whether we can accessible the application using our vm ip(basically here we are accessing with only ip means it runs with 80 port this happens due to i have used nginx reverse proxy here). + +validating in client-1 + +![image (8)](https://github.com/salvathshaik/BashBlaze-7-Days-of-Bash-Scripting-Challenge/assets/39498166/20df1d66-e465-4f25-aa38-1c4c1d00001d) + +validating in client-2 + +![image (12)](https://github.com/salvathshaik/BashBlaze-7-Days-of-Bash-Scripting-Challenge/assets/39498166/14cfe635-2695-4de2-a5ad-39864ec2f898) + + +Deploying application on docker manually as VMs are capable to handle as of now. + +Running the docker image with 1234 port + +![image (13)](https://github.com/salvathshaik/BashBlaze-7-Days-of-Bash-Scripting-Challenge/assets/39498166/9d2ed8b8-0ee8-41cf-98f0-c14cb1580278) + +Validating the application with 1234 port in browser. + +![image (14)](https://github.com/salvathshaik/BashBlaze-7-Days-of-Bash-Scripting-Challenge/assets/39498166/d0bd94a0-1ec1-42a3-8daf-474e455a122d) + +Thank you diff --git a/Self-solutions/Day_7/check_and_unlink_symlink.sh b/Self-solutions/Day_7/check_and_unlink_symlink.sh new file mode 100644 index 0000000..8112fad --- /dev/null +++ b/Self-solutions/Day_7/check_and_unlink_symlink.sh @@ -0,0 +1,11 @@ +if [ -h /etc/nginx/sites-enabled/my_app ]; then + echo "A symbolic link with the name 'my_app' already exists in /etc/nginx/sites-enabled/." + + echo "Removing it before creating a new symlink." + echo "admin1234" | sudo -S unlink /etc/nginx/sites-enabled/my_app + echo "admin1234" | sudo -S ln -s /etc/nginx/sites-available/my_app /etc/nginx/sites-enabled/ + echo "Symlink 'my_app' created in /etc/nginx/sites-enabled/." +else + echo "admin1234" | sudo -S ln -s /etc/nginx/sites-available/my_app /etc/nginx/sites-enabled/ + echo "Symlink 'my_app' created in /etc/nginx/sites-enabled/." +fi diff --git a/Self-solutions/Day_7/client1-nginx.conf b/Self-solutions/Day_7/client1-nginx.conf new file mode 100644 index 0000000..d453665 --- /dev/null +++ b/Self-solutions/Day_7/client1-nginx.conf @@ -0,0 +1,10 @@ +server { + listen 80; + server_name 192.168.0.12; + + location / { + proxy_pass http://127.0.0.1:5000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } +} diff --git a/Self-solutions/Day_7/client2-nginx.conf b/Self-solutions/Day_7/client2-nginx.conf new file mode 100644 index 0000000..3d4fe39 --- /dev/null +++ b/Self-solutions/Day_7/client2-nginx.conf @@ -0,0 +1,10 @@ +server { + listen 80; + server_name 192.168.0.14; + + location / { + proxy_pass http://127.0.0.1:5000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } +} diff --git a/Self-solutions/Day_7/day7_challenge_solution.sh b/Self-solutions/Day_7/day7_challenge_solution.sh new file mode 100755 index 0000000..98ac2b4 --- /dev/null +++ b/Self-solutions/Day_7/day7_challenge_solution.sh @@ -0,0 +1,196 @@ +#!/bin/bash + +##################################################################### +# Script Name: day7_challange_solution.sh +# Author: Salwad Basha Shaik +# Date: August 6, 2023 +# Description: This script contains solution for Day 7-Mastering Remote Server Management and Web App Deployment as part of BashBlaze: 7 Days of Bash Scripting Challenge. +# Usage: ./day7_challange_solution.sh +# Email: salvathshaik786143@gmail.com +# LinkedIn: https://www.linkedin.com/in/salwad-basha-shaik/ +# Github: https://github.com/salvathshaik/ +##################################################################### + + + + + +echo +echo "Started the nginx and Dependancies installations" +echo + +echo "Started for client-1" +echo +ssh client1@192.168.0.12 "echo 'admin1234' | sudo -S apt update && echo 'admin1234' | sudo -S apt install -y nginx" +ssh client1@192.168.0.12 "echo 'admin1234' | sudo -S apt-get install -y python3-pip" +ssh client1@192.168.0.12 "echo 'admin1234' | sudo -S pip3 install flask" + +echo +echo "Completed for Client-1" +echo + +echo "Started for client-2" +echo +ssh client2@192.168.0.14 "echo 'admin1234' | sudo -S apt update && echo 'admin1234' | sudo -S apt install -y nginx" +ssh client2@192.168.0.14 "echo 'admin1234' | sudo -S apt-get install -y python3-pip" +ssh client2@192.168.0.14 "echo 'admin1234' | sudo -S pip3 install flask" + +echo +echo "Completed for Client-2" +echo + + +echo +echo "Started copying the nginx configurations" +echo + +echo "Started for client-1" +echo + +# Copy Nginx configuration to client1 +scp /tmp/client1-nginx.conf client1@192.168.0.12:/tmp/client1-nginx.conf + +echo +echo "Completed for Client-1" +echo + +echo "Started for client-2" +echo +#Copy Nginx configuration to client2 +scp /tmp/client2-nginx.conf client2@192.168.0.14:/tmp/client2-nginx.conf + +echo +echo "Completed for Client-2" +echo + + +echo +echo "Started Checking if symlink already created for my_app nginx configuration file." +echo + +echo "Started for client-1" +echo +ssh client1@192.168.0.12 "bash -s" < check_and_unlink_symlink.sh + +echo +echo "Completed for Client-1" +echo + +echo "Started for client-2" +echo +ssh client2@192.168.0.14 "bash -s" < check_and_unlink_symlink.sh + +echo +echo "Completed for Client-2" +echo + + +echo +echo "Started Moving the nginx configurations" +echo + +echo "Started for client-1" +echo +# Move Nginx configuration file on client1 +ssh client1@192.168.0.12 "echo 'admin1234' | sudo -S mv /tmp/client1-nginx.conf /etc/nginx/sites-available/my_app" + +echo +echo + +ssh client1@192.168.0.12 "echo 'admin1234' | sudo -S ln -s /etc/nginx/sites-available/my_app /etc/nginx/sites-enabled/" + +echo +echo "Completed for Client-1" +echo + +echo "Started for client-1" +echo +# Move Nginx configuration file on client2 +ssh client2@192.168.0.14 "echo 'admin1234' | sudo -S mv /tmp/client2-nginx.conf /etc/nginx/sites-available/my_app" + +echo +echo + +ssh client2@192.168.0.14 "echo 'admin1234' | sudo -S ln -s /etc/nginx/sites-available/my_app /etc/nginx/sites-enabled/" + +echo +echo "Completed for Client-1" +echo + +echo +echo "Started copying the flask application code to nginx." +echo + +echo "Started for client-1" +echo +scp -r /home/server/web-app-deploy-shell-scripting client1@192.168.0.12:/tmp +echo +echo +ssh client1@192.168.0.12 "echo 'admin1234' | sudo -S cp -pr /tmp/web-app-deploy-shell-scripting/* /etc/nginx/sites-available/" + +echo +echo "Completed for Client-1" +echo + +echo "Started for client-2" +echo +scp -r /home/server/web-app-deploy-shell-scripting client2@192.168.0.14:/tmp +echo +echo +ssh client2@192.168.0.14 "echo 'admin1234' | sudo -S cp -pr /tmp/web-app-deploy-shell-scripting/* /etc/nginx/sites-available/" +echo +echo "Completed for Client-2" +echo + + +echo +echo "Started checking if app.py is running on the BOTH remote hosts ." +echo + + +#Check if app.py is running on the remote host +check_and_kill_app() { + remote_host=$1 + if ssh "$remote_host" 'ps aux | grep -q "[a]pp.py"'; then + echo "app.py is running on $remote_host. Killing the process..." + # Get the PID of the app.py process on the remote host + app_pid=$(ssh "$remote_host" 'ps aux | grep "[a]pp.py" | awk "{print \$2}"') + # Kill the process on the remote host + ssh "$remote_host" "kill $app_pid" + echo "app.py process (PID $app_pid) killed successfully on $remote_host." + else + echo "app.py is not running on $remote_host." + fi +} +# Call the function for client1 and client2 VMs +check_and_kill_app "client1@192.168.0.12" +check_and_kill_app "client2@192.168.0.14" + +echo +echo "Completed the checking.." +echo + + +echo +echo "Running the app in both clients in the background and moving the terminal out to dummy file." +echo + +ssh client1@192.168.0.12 "echo 'admin1234' | sudo -S nohup python3 /etc/nginx/sites-available/app.py > /dev/null 2>&1 & " +ssh client2@192.168.0.14 "echo 'admin1234' | sudo -S nohup python3 /etc/nginx/sites-available/app.py > /dev/null 2>&1 & " + +echo +echo "Completed Running.." +echo + +echo +echo "Reloaing the nginx configurations to ensure nginx knows about the changes." +echo +# Reload Nginx on client1 +ssh client1@192.168.0.12 "echo 'admin1234' | sudo -S systemctl reload nginx" +# Reload Nginx on client2 +ssh client2@192.168.0.14 "echo 'admin1234' | sudo -S systemctl reload nginx" + +echo +echo "Completed All tasks.. validate in browser now" +echo + diff --git a/Self-solutions/Day_7/day7_solution_practice.sh b/Self-solutions/Day_7/day7_solution_practice.sh new file mode 100755 index 0000000..e69de29 diff --git a/Self-solutions/Day_7/readme.txt b/Self-solutions/Day_7/readme.txt new file mode 100644 index 0000000..16576e2 --- /dev/null +++ b/Self-solutions/Day_7/readme.txt @@ -0,0 +1 @@ +Please run './day7_challange_solution.sh' for the solution. diff --git a/Self-solutions/Day_7/web-app-deploy-shell-scripting/Dockerfile b/Self-solutions/Day_7/web-app-deploy-shell-scripting/Dockerfile new file mode 100644 index 0000000..edfd252 --- /dev/null +++ b/Self-solutions/Day_7/web-app-deploy-shell-scripting/Dockerfile @@ -0,0 +1,8 @@ +FROM python:alpine3.7 +COPY . /app +WORKDIR /app +RUN pip install -r requirements.txt +ENV PORT 5000 +EXPOSE 5000 +ENTRYPOINT [ "python" ] +CMD [ "app.py" ] \ No newline at end of file diff --git a/Self-solutions/Day_7/web-app-deploy-shell-scripting/README.md b/Self-solutions/Day_7/web-app-deploy-shell-scripting/README.md new file mode 100644 index 0000000..96fb405 --- /dev/null +++ b/Self-solutions/Day_7/web-app-deploy-shell-scripting/README.md @@ -0,0 +1,46 @@ +# Kubernetes Microservice Flask Application + +This is a microservice application built using Flask and deployed on Kubernetes. It is designed to demonstrate how to build and deploy microservices on a Kubernetes cluster. + +## Table of Contents + +- [Installation](#installation) +- [Usage](#usage) +- [Contributing](#contributing) +- [License](#license) + +## Installation + +First prepare the kubernetes master and worker environments with the below reference +https://github.com/lerndevops/educka/blob/master/1-intall/install-kubernetes-v1.24-ubuntu-debian.md + +To install and run the application on your Kubernetes cluster, follow these steps: + +1. Clone this repository to your local machine. +2. Navigate to the project root directory. +3. Create a Kubernetes deployment and service by running the following command: + +`kubectl apply -f kubernetes.yaml` + +4. Verify that the deployment and service have been created successfully by running the following command: + +`kubectl get deployments,services` + +5. If everything is working properly, you should see the name of your deployment and service listed in the output. + +## Usage + +To use the microservice, you can send HTTP requests to the service's endpoint. Here's an example request: + +`curl http://:/tasks` + + +This should return a JSON response with a greeting message. + +## Contributing + +If you'd like to contribute to this project, please fork the repository and create a new branch. Pull requests are welcome! + +## License + +This project is licensed under the MIT License - see the [LICENSE.md] and thanks to Shubham Londe for the references. diff --git a/Self-solutions/Day_7/web-app-deploy-shell-scripting/app.py b/Self-solutions/Day_7/web-app-deploy-shell-scripting/app.py new file mode 100644 index 0000000..35669b1 --- /dev/null +++ b/Self-solutions/Day_7/web-app-deploy-shell-scripting/app.py @@ -0,0 +1,13 @@ +from flask import Flask, render_template +import socket +app = Flask(__name__) +@app.route("/") #health-check-api + +def index(): + hostname = socket.gethostname() + title = 'Welcome to Salwad Basha Task App' + message="Welcome to Tasks app! I am running inside {} pod!".format(hostname) + return render_template('index.html', title=title, body_text=message) + +if __name__ == "__main__": #running this app using port 5000 while we run this file(app.py) it will initialize + app.run(host="0.0.0.0", port=5000) diff --git a/Self-solutions/Day_7/web-app-deploy-shell-scripting/requirements.txt b/Self-solutions/Day_7/web-app-deploy-shell-scripting/requirements.txt new file mode 100644 index 0000000..1657fb5 --- /dev/null +++ b/Self-solutions/Day_7/web-app-deploy-shell-scripting/requirements.txt @@ -0,0 +1,2 @@ +Flask +Flask-PyMongo \ No newline at end of file diff --git a/Self-solutions/Day_7/web-app-deploy-shell-scripting/templates/index.html b/Self-solutions/Day_7/web-app-deploy-shell-scripting/templates/index.html new file mode 100644 index 0000000..f111e47 --- /dev/null +++ b/Self-solutions/Day_7/web-app-deploy-shell-scripting/templates/index.html @@ -0,0 +1,10 @@ + + + + {{ title }} + + +

{{ title }}

+

{{ body_text }}

+ +