Created
June 7, 2025 23:40
-
-
Save carloswm85/221e8e55091b3d0b3d15e3a3f81ec797 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# shellcheck disable=SC2002 | |
# shellcheck disable=SC2020 | |
# shellcheck disable=SC2086 | |
# shellcheck disable=SC2317 | |
# shellcheck disable=SC1073 | |
# shellcheck disable=SC1009 | |
# shellcheck disable=SC1072 | |
## Common BASH shell environment files and the order in which they are typically | |
## executed are as follows: | |
# /etc/profile | |
# /etc/profile.d/* | |
# /etc/bashrc | |
# ~/.bashrc | |
# ~/.bash_profile | |
# ~/.bash_login | |
# ~/.profile | |
## WEEK 07 | |
## ============================================================================= | |
## PROJECT 7-1 | |
## Objective: Perform shell redirection. | |
## Description: In this hands-on project, you use the shell to redirect the | |
## stdout and stderr to a file and take stdin from a file. | |
touch sample1 sample2 # Create two empty files: sample1 and sample2 | |
ls -F # List files in the directory with special characters to indicate type | |
ls -l sample1 sample2 sample3 # List detailed info for sample1, sample2, and non-existent sample3 (stderr expected) | |
ls -l sample1 sample2 sample3 > file # Redirect stdout to 'file'; stderr (if any) still appears on screen | |
cat file # Display contents of 'file' (only stdout from previous command) | |
ls -l sample1 sample2 sample3 2> file # Redirect stderr to 'file'; stdout (if any) appears on screen | |
cat file # Display contents of 'file' (only stderr from previous command) | |
ls -l sample1 sample2 sample3 > file 2>file2 # Redirect stdout to 'file' and stderr to 'file2' | |
cat file # Show stdout from previous ls command | |
cat file2 # Show stderr from previous ls command | |
ls -l sample1 sample2 sample3 > file 2>&1 # Redirect both stdout and stderr to 'file' | |
cat file # Show combined stdout and stderr from previous command | |
ls -l sample1 sample2 sample3 >&2 2>file2 # Redirect both stdout and stderr to stderr, then redirect stderr to 'file2' | |
cat file2 # Show captured stderr from previous command | |
date > file # Overwrite 'file' with current date | |
cat file # Show contents of 'file' (should be the current date) | |
date >> file # Append current date to 'file' | |
cat file # Show both dates; first from overwrite, second from append | |
tr o O /etc/hosts # Incorrect usage: tr doesn't take filenames as arguments (stderr expected) | |
tr o O </etc/hosts # Correct: replaces all 'o' with 'O' from /etc/hosts and outputs result | |
tr o O <<EOF # Start here-doc input redirection to tr (until EOF is entered) | |
oranges | |
Toronto | |
Donkey Kong | |
EOF | |
## ============================================================================= | |
## PROJECT 7-2 | |
## Objective: Perform shell piping. | |
## Description: In this hands-on project, you redirect stdout and stdin using | |
## pipe metacharacters. | |
cat /etc/services # Display the contents of /etc/services | |
cat /etc/services | less # View the contents page-by-page using less via a pipe | |
cat /etc/services | grep NFS # Filter lines containing "NFS"; grep reads from stdin | |
cat /etc/services | grep NFS | tr F f # Replace uppercase 'F' with lowercase 'f' in the grep output | |
cat /etc/services | grep NFS | tr F f | sort -r # Sort the modified lines in reverse order | |
cat /etc/services | grep NFS | tr F f | sort -r | tee file # Save output to 'file' and display on screen | |
cat file # Show contents of 'file'; matches previous output | |
cat /etc/services | grep NFS | tr F f | sort -r | tee file | wc -l # Count number of lines; saves intermediate output to 'file' | |
cat file # Show contents of 'file' to verify tee output | |
cat /etc/services | grep NFS | tr F f | sort -r | sed /udp/d | sed /tcp/s/mount/MOUNT/g # Remove lines with 'udp', replace 'mount' with 'MOUNT' in 'tcp' lines | |
cat /etc/hosts # Display contents of /etc/hosts | |
cat /etc/hosts | awk '/localhost/ {print $1, $3}' # Print first and third fields of lines containing 'localhost' | |
## ============================================================================= | |
## PROJECT 7-3 | |
## Objective: Create and manage variables. | |
## Description: In this hands-on project, you create and use an alias, as well | |
## as view and change existing shell variables. In addition, you export | |
## user-defined variables and load variables automatically upon shell startup. | |
# shellcheck disable=SC2002 | |
set | less # View all shell variables; scroll with arrow keys, quit with 'q' | |
env | less # View exported environment variables; usually fewer than `set` because it only shows exported ones | |
PS1="Hello There:" # Temporarily change the shell prompt to "Hello There:" | |
echo $PS1 # Display current value of the PS1 variable | |
exit # Log out of the shell | |
# After re-login: | |
# The prompt reverts because the PS1 change wasn't persisted | |
vi .bash_profile # Open user's shell profile to persist settings | |
# Add the following to the bottom of .bash_profile: | |
# echo -e "Would you like a hello prompt? (y/n) -->\c" | |
# read ANSWER | |
# if [ $ANSWER = "y" -o $ANSWER = "Y" ] | |
# then | |
# PS1="Hello There: " | |
# fi | |
# This script prompts user at login, and sets the prompt to "Hello There: " if they answer 'y' or 'Y' | |
exit # Log out to test the new .bash_profile behavior | |
# Log back in and enter 'y' at the prompt — prompt changes to "Hello There:" | |
exit # Log out again | |
# Log in again and enter 'n' at the prompt — default prompt appears | |
MYVAR="My sample variable" # Create a shell variable called MYVAR | |
echo $MYVAR # Display value of MYVAR | |
set | grep MYVAR # MYVAR appears because it's set in the shell | |
env | grep MYVAR # MYVAR does not appear — not exported yet | |
export MYVAR # Export MYVAR to make it available to subshells | |
env | grep MYVAR # MYVAR now appears in environment list | |
exit # Log out again | |
# After re-login: | |
echo $MYVAR # MYVAR is not defined — because it wasn't set in .bash_profile | |
vi .bash_profile # Edit profile to make MYVAR persistent | |
# Add this line at the bottom of .bash_profile: | |
# export MYVAR="My sample variable" | |
exit # Log out again | |
# After re-login: | |
echo $MYVAR # MYVAR is now available automatically | |
alias # Show defined aliases | |
alias asample="cd /etc ; cat hosts ; cd ~ ; ls -F" # Define alias: go to /etc, display hosts file, return home, list files with markers | |
asample # Run the alias; output from each command is displayed in sequence | |
# To persist this alias across sessions, add it to ~/.bashrc | |
exit # Logout of the shell | |
## ============================================================================= | |
## PROJECT 7-4 | |
## Objective: Create a basic shell script. | |
## Description: In this hands-on project, you create a basic shell script and | |
## execute it on the system. | |
vi myscript # Open a new file called 'myscript' in the vi editor | |
# Inside vi, enter the following lines: | |
# ------------------------------------ | |
# #!/bin/bash | |
# echo -e "This is a sample shell script. \t It displays mounted filesystems: \a" | |
# df -hT | |
# ------------------------------------ | |
# Save and quit vi with :wq | |
ls -l myscript # List file details and permissions for 'myscript' | |
bash myscript # Run the script using the bash interpreter directly | |
# \t = horizontal tab, \a = alert/bell (may make a sound or flash) | |
./myscript # Try to execute script directly (will likely fail due to missing execute permission) | |
chmod u+x myscript # Add execute permission for the file owner | |
./myscript # Now run the script directly after setting execute permission | |
exit # Log out of the shell | |
## ============================================================================= | |
## PROJECT 7-5 | |
## Objective: Create system administration shell scripts. | |
## Description: In this hands-on project, you create a shell script that uses | |
## decision and loop constructs to analyze user input. | |
vi diskconfig.sh # Open a new shell script file named diskconfig.sh in the vi editor | |
# Inside vi, enter the following script: | |
# -------------------------------------- | |
# #!/bin/bash # Use the Bash shell to interpret the script | |
# # This script creates a report of our disk configuration | |
# FILENAME=$(hostname) # Assign the system's hostname to the variable FILENAME | |
# echo "Disk report saved to $FILENAME.report" # Print message showing the name of the output report file | |
# echo -e "\n LVM Configuration: \n\n" >> $FILENAME.report # Write LVM section header into the report file | |
# lvscan >> $FILENAME.report # Append output of logical volume scan to the report | |
# echo -e "\n\n Partition Configuration: \n\n" >> $FILENAME.report # Write partition section header into the report | |
# fdisk -l | head -17 >> $FILENAME.report # Append first 17 lines of partition info to the report | |
# echo -e "\n\n Mounted Filesystems: \n\n" >> $FILENAME.report # Write mounted filesystems header into the report | |
# df -hT | grep -v tmp >> $FILENAME.report # Append mounted filesystems (excluding tmpfs) to the report | |
# -------------------------------------- | |
# Save and quit vi with :wq | |
chmod u+x diskconfig.sh # Grant execute permission to the script | |
./diskconfig.sh # Run the disk configuration script | |
less "$(hostname).report" # View the generated report with less | |
vi dirbackup.sh # Open a new shell script file named dirbackup.sh | |
# Inside vi, enter the following first version: | |
# -------------------------------------- | |
# #!/bin/bash # Use the Bash shell to interpret the script | |
# # This script backs up a directory of your choice | |
# if [ $# -ne 1 ]; then # Check if exactly one argument (directory) was passed | |
# echo "Usage is $0 <directory to back up>" # Print usage message with script name if not | |
# exit 255 # Exit with status code 255 indicating error | |
# fi | |
# echo "Performing backup....." # Inform user that backup is starting | |
# sleep 3 # Pause for 3 seconds for dramatic effect | |
# tar -zcvf ~/backupfile.tar.gz $1 # Create compressed archive of the directory passed as argument | |
# echo "Backup completed successfully to ~/backupfile.tar.gz" # Inform user that the backup has completed | |
# -------------------------------------- | |
# Save and quit vi with :wq | |
chmod u+x dirbackup.sh # Make script executable | |
./dirbackup.sh # Run without argument to see the error | |
./dirbackup.sh /etc/samba # Run with argument to back up /etc/samba | |
ls -F # List files in current directory to check for backup | |
vi dirbackup.sh # Edit the script for input-based backup | |
# Modify the script to: | |
# -------------------------------------- | |
# #!/bin/bash # Use the Bash shell to interpret the script | |
# # This script backs up a directory of your choice | |
# echo -e "What directory do you want to back up?-->\c" # Prompt user to input a directory path (with no newline) | |
# read ANS # Read the user input into the variable ANS | |
# echo "Performing backup....." # Inform user that backup is starting | |
# sleep 3 # Pause for 3 seconds for user clarity | |
# tar -zcvf ~/backupfile.tar.gz $ANS # Create compressed archive of the specified directory | |
# echo "Backup completed successfully to ~/backupfile.tar.gz" # Inform user that the backup has completed | |
# -------------------------------------- | |
# Save and quit vi with :wq | |
./dirbackup.sh # Run and input e.g. /etc/httpd when prompted | |
vi dirbackup.sh # Modify the script to include directory and date in filename | |
# Modify the script to: | |
# -------------------------------------- | |
# #!/bin/bash # Use the Bash shell to interpret the script | |
# # This script backs up a directory of your choice | |
# echo -e "What directory do you want to back up?-->\c" # Prompt user for directory path (no newline after prompt) | |
# read ANS # Read user input into the variable ANS | |
# echo "Performing backup....." # Notify the user that the backup is starting | |
# sleep 3 # Pause for 3 seconds for visibility | |
# FILE=$(echo $ANS | sed 's#/#-#g') # Replace all forward slashes in directory path with dashes for filename | |
# DATE=$(date +%F) # Store current date in YYYY-MM-DD format | |
# tar -zcvf ~/backup-$FILE-$DATE.tar.gz $ANS # Create a gzipped tarball named with sanitized path and current date | |
# echo "Backup performed to ~/backup-$FILE-$DATE.tar.gz" # Notify the user of successful backup and its location | |
# -------------------------------------- | |
# Save and quit vi with :wq | |
./dirbackup.sh # Run and input e.g. /etc/httpd to create a timestamped backup | |
vi familydatabase.sh # Open a new shell script file named familydatabase.sh | |
# Enter the following: | |
# -------------------------------------- | |
# #!/bin/bash # Use the Bash shell to interpret the script | |
# while true; do # Start an infinite loop | |
# clear # Clear the screen before each iteration | |
# echo -e "What would you like to do? # Display the menu options | |
# Add an entry (a) | |
# Search an entry (s) | |
# Quit (q) | |
# Enter your choice (a/s/q)-->\c" # Prompt the user (no newline after prompt) | |
# read ANSWER # Read user input into variable ANSWER | |
# case $ANSWER in # Begin case block to handle user choice | |
# a|A) # If user selects 'a' or 'A': | |
# echo -e "Name of the family member --> \c" # Prompt for name | |
# read NAME # Read name input | |
# echo -e "Family member's relation to you -->\c" # Prompt for relation | |
# read RELATION # Read relation input | |
# echo -e "Family member's telephone number --> \c" # Prompt for phone number | |
# read PHONE # Read phone number input | |
# echo -e "$NAME\t$RELATION\t$PHONE" >> database # Append entered info to 'database' file, tab-separated | |
# ;; # End of 'a' case block | |
# s|S) # If user selects 's' or 'S': | |
# echo -e "What word would you like to look for? --> \c" # Prompt for search term | |
# read WORD # Read search term input | |
# grep "$WORD" database # Search the 'database' file for the term | |
# sleep 4 # Pause for 4 seconds to view output | |
# ;; # End of 's' case block | |
# q|Q) # If user selects 'q' or 'Q': | |
# exit # Exit the script | |
# ;; # End of 'q' case block | |
# *) # For any other input: | |
# echo "You must enter either the letter a or s." # Display usage error message | |
# sleep 4 # Pause for 4 seconds | |
# ;; # End of default case block | |
# esac # Close the case block | |
# done # Repeat the loop | |
# -------------------------------------- | |
# Save and quit vi with :wq | |
chmod u+x familydatabase.sh # Make the script executable | |
./familydatabase.sh # Run the family database script | |
# Test all options: a (add), s (search), x (invalid), q (quit) | |
exit # Log out of the shell | |
## ============================================================================= | |
## PROJECT 7-6 | |
## Objective: Practice using Git. | |
## Description: In this hands-on project, you create a local Git repository for | |
## the shell scripts that you created in Project 7-5 and explore Git version | |
## control. | |
mkdir /shellscripts # Create a new directory called /shellscripts | |
mv diskconfig.sh dirbackup.sh familydatabase.sh /shellscripts # Move the three scripts to the /shellscripts directory | |
git config --global user.email "[email protected]" # Set the global Git email | |
git config --global user.name "root user" # Set the global Git username | |
git config --global init.defaultBranch main # Set the default Git branch name to main | |
cd /shellscripts # Change to the /shellscripts directory | |
git init # Initialize a new Git repository | |
ls -a # List all files including hidden ones to confirm .git directory | |
git status # Check current Git status (untracked files) | |
git add . # Add all files to the Git staging area | |
git status # Confirm that files are staged | |
git commit -m "First commit" # Create the first commit with a message | |
vi diskconfig.sh # Open diskconfig.sh in vi editor | |
# (Add the following lines at the end of the file in vi) | |
echo -e "\n\n RAID Configuration: \n\n" >>$FILENAME.report # Add RAID section heading to the report | |
mdadm --detail /dev/md0 >>$FILENAME.report # Add RAID details to the report | |
git status # Check Git status to see if the file was modified | |
git add . # Stage the modified file | |
git commit -m "Added RAID to diskconfig.sh" # Commit the changes with a message | |
git log # Show Git commit history | |
git reset --hard <commit> # Reset the repo to the specified previous commit | |
cat diskconfig.sh # Display the contents of diskconfig.sh | |
cd # Return to the home directory | |
git clone /shellscripts # Clone the /shellscripts repository into the current directory | |
cd shellscripts # Change into the cloned repository directory | |
ls -a # List all files including .git to verify the clone | |
git branch # Show current branch (should be main) | |
git checkout -b AddRAID # Create and switch to a new branch named AddRAID | |
git branch # List branches to confirm AddRAID is the current branch | |
vi diskconfig.sh # Open diskconfig.sh in vi editor | |
# (Add the following lines at the end of the file in vi) | |
echo -e "\n\n RAID Configuration: \n\n" >>$FILENAME.report # Add RAID section heading again in branch | |
mdadm --detail /dev/md0 >>$FILENAME.report # Add RAID details again in branch | |
git add . # Stage the modified file for commit in AddRAID branch | |
git commit -m "Added RAID to diskconfig.sh" # Commit the change to the AddRAID branch | |
cat diskconfig.sh # Show contents to confirm RAID lines are present | |
git checkout main # Switch back to the main branch | |
cat diskconfig.sh # Confirm the RAID lines are not present in main | |
git push origin AddRAID # Push AddRAID branch to the origin repository | |
cd /shellscripts # Go to the original repository | |
git branch # Verify that AddRAID exists and main is still the active branch | |
git show AddRAID # Show the changes made in the AddRAID branch | |
git merge AddRAID # Merge AddRAID into the current main branch | |
cat diskconfig.sh # Confirm RAID lines are now in the main branch | |
cd ~/shellscripts # Go back to the cloned repo in the home directory | |
git pull origin main # Pull latest changes from the origin main branch | |
exit # Log out of the terminal | |
## ============================================================================= | |
## PROJECT 7-7 | |
## Objective: Set up and use the Z shell. | |
## Description: In this hands-on project, you install and explore the Z shell. | |
dnf -y install zsh # Install the Z shell non-interactively with auto-confirm | |
exit # Log out of the root shell session | |
zsh # Start the Z shell and enter the interactive configuration menu | |
vi .zshrc # Open Zsh config file in vi for manual editing; edit `setopt autocd` to `setopt autocd correct`, then save with :wq | |
source .zshrc # Reload .zshrc into the current shell session | |
grep NFS /etc/services >file1 >file2 # Only file2 gets the output; second redirection overrides the first | |
cat file1 # View contents of file1 (likely empty) | |
cat file2 # View contents of file2 (contains grep output) | |
grep NFS /etc/services >file1 | grep protocol >file2 # file1 gets output from grep NFS; file2 gets filtered result from the pipe | |
cat file1 # View file1 contents | |
cat file2 # View file2 contents | |
sort <file1 <file2 >file3 # Incorrect: only file2 is used due to conflicting redirections | |
cat file3 # View file3 contents (likely only sorted file2) | |
grp NFS /etc/services # Typo triggers autocorrect; press y to fix to `grep` | |
date - # Press Tab to list valid options | |
date --universal # Show current date/time in UTC | |
pwd # Show current working directory | |
Desktop # Change to Desktop directory using autocd | |
pwd # Show new working directory (should be ~/Desktop) | |
exit # Log out of Z shell session |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment