Introduction
In this lab, you will learn to create and execute Bash scripts for RHEL system administration. You will begin by crafting simple scripts, then enhance them with system commands and make them executable. The lab progresses to using for loops for automating tasks like system information gathering and filtering command output with grep and regular expressions. Finally, you will build a comprehensive RHEL system information script, gaining practical skills in automating administrative tasks and leveraging powerful shell features.
Create and Execute a Simple Bash Script
In this step, you will learn how to create a basic Bash script and execute it. Bash scripts are plain text files containing a series of commands that the Bash shell can execute. They are powerful tools for automating repetitive tasks and combining multiple commands into a single executable unit.
First, you will create a new directory to store your scripts. It's good practice to organize your files, and placing scripts in a dedicated directory helps keep your home directory tidy.
Create a directory for your scripts. Use the
mkdircommand to create a directory namedscriptswithin your~/projectdirectory. This is where you will store your Bash scripts.mkdir ~/project/scriptsThere will be no direct output from this command if successful.
Create your first Bash script file. Navigate into the newly created
scriptsdirectory and use thenanotext editor to create a file namedfirstscript.sh. The.shextension is a common convention for shell scripts, though not strictly required.cd ~/project/scripts nano firstscript.shInside the
nanoeditor, you will see a blank screen.Add content to your script. Every Bash script should start with a "shebang" line,
#!/usr/bin/bash. This line tells the operating system which interpreter to use for executing the script (in this case, Bash). After the shebang, you will add a simpleechocommand to print a message to the terminal.Type the following lines into the
nanoeditor:#!/usr/bin/bash echo "Hello, LabEx! This is my first Bash script."Once you have entered the content, save the file by pressing
Ctrl+O, thenEnterto confirm the filename, andCtrl+Xto exitnano.Your terminal should return to the command prompt.
Execute your script using the
bashinterpreter. You can execute a Bash script by explicitly telling thebashinterpreter to run it. This method does not require the script to have executable permissions.bash firstscript.shYou should see the output of your script:
Hello, LabEx! This is my first Bash script.This confirms that your script was created correctly and executed successfully.
Enhance Bash Script with System Commands and Make Executable
In this step, you will enhance your Bash script by adding more system commands and learn how to make the script directly executable. Making a script executable allows you to run it like any other command, without explicitly calling the bash interpreter.
Navigate to your scripts directory. Ensure you are in the
~/project/scriptsdirectory where you createdfirstscript.shin the previous step.cd ~/project/scriptsEdit
firstscript.shto include more system commands. You will now add commands to your script that display system information, such as block devices and filesystem free space. This demonstrates how scripts can automate the collection of system data.Open
firstscript.shusingnano:nano firstscript.shModify the content of the file to match the following. This script will now:
- Print a header for block device information.
- Execute
lsblkto list block devices. - Print a header for filesystem free space.
- Execute
df -hto display disk space usage in a human-readable format.
#!/usr/bin/bash echo "Hello, LabEx! This is my first Bash script." echo "#####################################################" echo "LIST BLOCK DEVICES" echo "#####################################################" lsblk echo "#####################################################" echo "FILESYSTEM FREE SPACE STATUS" echo "#####################################################" df -hSave the file by pressing
Ctrl+O, thenEnter, andCtrl+Xto exitnano.Make the script executable. To run a script directly (e.g.,
./firstscript.sh), you need to grant it executable permissions. Thechmodcommand is used to change file permissions.+xadds execute permission for all users.chmod +x firstscript.shThere will be no direct output from this command if successful.
Execute the script directly. Now that the script is executable, you can run it by specifying its path. Since it's in your current directory, you use
./followed by the script name../firstscript.shYou should see output similar to this, combining your initial message with the output of
lsblkanddf -h:Hello, LabEx! This is my first Bash script. ##################################################### LIST BLOCK DEVICES ##################################################### NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS loop0 7:0 0 10.2G 1 loop / loop1 7:1 0 200M 1 loop /usr/local/bin loop2 7:2 0 200M 1 loop /usr/local/go loop3 7:3 0 200M 1 loop /usr/local/java loop4 7:4 0 200M 1 loop /usr/local/node loop5 7:5 0 200M 1 loop /usr/local/python ##################################################### FILESYSTEM FREE SPACE STATUS ##################################################### Filesystem Size Used Avail Use% Mounted on overlay 10G 4.0G 6.1G 40% / tmpfs 64M 0 64M 0% /dev tmpfs 7.8G 0 7.8G 0% /sys/fs/cgroup shm 64M 0 64M 0% /dev/shm /dev/loop0 10G 4.0G 6.1G 40% / tmpfs 7.8G 0 7.8G 0% /proc/asound tmpfs 7.8G 0 7.8G 0% /proc/acpi tmpfs 7.8G 0 7.8G 0% /proc/scsi tmpfs 7.8G 0 7.8G 0% /sys/firmwareThe exact output for
lsblkanddf -hmay vary slightly depending on the specific environment, but the structure and presence of the commands' output should be similar.
Use For Loops to Automate Hostname Retrieval on RHEL Servers
In this step, you will learn about for loops in Bash and how to use them to automate tasks across multiple servers. for loops are fundamental control flow statements that allow you to execute a block of code repeatedly for each item in a list. This is particularly useful for managing multiple systems efficiently.
For this exercise, we will demonstrate the concept using localhost with different approaches to simulate working with multiple servers.
Retrieve hostname using local commands. Before using a loop, let's see how you would typically get the hostname from the local system. We'll use different methods to demonstrate the concept.
hostname hostname -fYou should see output similar to this:
684791f71c0e35fea6cc1243 684791f71c0e35fea6cc1243This demonstrates that you can successfully retrieve hostname information using different options. Note that in this container environment, all hostname options return the same container ID.
Create a
forloop to automate hostname retrieval with different options. Now, let's use aforloop to perform different hostname commands more efficiently. Theforloop will iterate over a list of hostname options, executing thehostnamecommand with each option.for OPTION in "" "-f" "-s"; do echo "hostname ${OPTION}:" hostname ${OPTION} echo "" doneLet's break down this command:
for OPTION in "" "-f" "-s";: This part initializes the loop.OPTIONis a variable that will take on the value of each item in the list (empty string,-f,-s) during each iteration.do: Marks the beginning of the commands to be executed in the loop.echo "hostname ${OPTION}:";: This displays which option is being used.hostname ${OPTION};: This is the command executed in each iteration.${OPTION}expands to the current value of theOPTIONvariable.echo "";: Adds a blank line for better readability.done: Marks the end of the loop.
You should see output similar to this:
hostname : 684791f71c0e35fea6cc1243 hostname -f: 684791f71c0e35fea6cc1243 hostname -s: 684791f71c0e35fea6cc1243This demonstrates the power of
forloops in automating repetitive tasks with different parameters.
Create and Execute a Bash Script with For Loop for RHEL Servers
In this step, you will encapsulate the for loop you learned in the previous step into a Bash script. This allows you to save the automation logic and reuse it easily. You will also learn about the PATH environment variable and how to make your scripts accessible from any directory.
Navigate to your scripts directory. Ensure you are in the
~/project/scriptsdirectory.cd ~/project/scriptsCreate a new script for hostname retrieval. You will create a script named
get_hostnames.shthat contains theforloop to retrieve hostname information using different options.Open
get_hostnames.shusingnano:nano get_hostnames.shAdd the following content to the file:
#!/usr/bin/bash ## This script retrieves hostname information using different options. for OPTION in "" "-f" "-s"; do echo "Getting hostname with option: ${OPTION}" hostname ${OPTION} echo "------------------------" done exit 0Save the file by pressing
Ctrl+O, thenEnter, andCtrl+Xto exitnano.Let's break down the new elements:
## This script...: Lines starting with#are comments. They are ignored by the shell but are useful for documenting your script.echo "Getting hostname with option: ${OPTION}": This line provides feedback during script execution, indicating which option is currently being used.exit 0: This command explicitly exits the script with a status code of0, which conventionally indicates success.
Make the script executable. Just like in the previous step, you need to give your new script executable permissions.
chmod +x get_hostnames.shThere will be no direct output from this command if successful.
Execute the script from its current directory. Run the script to verify its functionality.
./get_hostnames.shYou should see output similar to this:Getting hostname with option: 684791f71c0e35fea6cc1243 ------------------------ Getting hostname with option: -f 684791f71c0e35fea6cc1243 ------------------------ Getting hostname with option: -s 684791f71c0e35fea6cc1243 ------------------------Understand the
PATHenvironment variable. ThePATHenvironment variable is a list of directories that the shell searches for executable commands. When you type a command likelsorgrep, the shell looks in the directories listed inPATHto find the corresponding executable file.Display your current
PATHvariable:echo $PATHYou will see a colon-separated list of directories. For example:
/home/labex/.local/bin:/home/labex/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbinNotice that
~/project/scripts(or/home/labex/project/scripts) is not typically included in the defaultPATH. This is why you had to use./get_hostnames.shto execute your script.Add your scripts directory to the
PATH(Optional, for future reference). While not strictly required for this lab step, it's common practice to add a personalbinorscriptsdirectory to yourPATHso you can run your custom scripts from any location. You can do this by adding a line likeexport PATH=$PATH:~/project/scriptsto your~/.bashrcor~/.zshrcfile. For this lab, we will continue to execute scripts by specifying their path.
Filter Command Output with Grep and Regular Expressions on RHEL
In this step, you will learn how to use the grep command with regular expressions to efficiently filter and extract specific information from command output and files. grep is a powerful utility for searching plain-text data sets for lines that match a regular expression. Regular expressions (regex) are sequences of characters that define a search pattern.
Search for specific user and group information in system files. You will use
grepto find information about thelabexuser and group from the/etc/passwdand/etc/groupfiles. These files store user and group account information, respectively.First, let's look for the
labexuser entry in/etc/passwd:grep "labex" /etc/passwdExpected output:
labex:x:1000:1000::/home/labex:/bin/bashNext, find the
labexgroup entry in/etc/group:grep "labex" /etc/groupExpected output:
labex:x:1000:These commands demonstrate basic
grepusage to find exact string matches.Filter
lscpuoutput usinggrepand regular expressions. Thelscpucommand displays CPU architecture information. Often, you only need specific lines from its extensive output. You can usegrepwith a regular expression to filter for lines that start with "CPU".lscpu | grep '^CPU'Let's break down this command:
lscpu: Generates the CPU information.|: This is a pipe, which takes the standard output oflscpuand feeds it as standard input to thegrepcommand.grep '^CPU': Searches for lines that start with the literal string "CPU". The^(caret) is a regular expression anchor that matches the beginning of a line.
Expected output (may vary slightly based on environment):
CPU op-mode(s): 32-bit, 64-bit CPU(s): 4 CPU family: 6Filter configuration files, ignoring comments and empty lines. Configuration files often contain comments (lines starting with
#) and empty lines that are not relevant to the actual configuration. You can usegrepwith multiple patterns to exclude these lines. Let's demonstrate this with the/etc/passwdfile.grep -v '^#' /etc/passwd | head -5Let's break down this command:
grep -v '^#' /etc/passwd: The-voption inverts the match, meaning it selects lines that do not match the pattern.^#matches lines that start with a#. So, this part filters out comment lines.|: Pipes the output of the firstgrepcommand to the next command.head -5: Shows only the first 5 lines of the output.
Expected output (showing user account entries without comments):
root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologinSearch for specific patterns in system files. You can use
grepto search for specific patterns in various system files. Let's search for shell-related entries in the/etc/passwdfile.grep "bash" /etc/passwdExpected output (showing users with bash shell):
root:x:0:0:root:/root:/bin/bash labex:x:1000:1000::/home/labex:/bin/bashThis command helps you identify users who have bash as their default shell.
Build a Comprehensive RHEL System Information Script
In this final step, you will combine all the concepts learned so far – Bash scripting, for loops, ssh for remote execution, and grep with regular expressions for filtering – to build a comprehensive script that gathers system information from multiple RHEL servers. The script will save the collected data to separate output files for each server.
Navigate to your scripts directory. Ensure you are in the
~/project/scriptsdirectory.cd ~/project/scriptsCreate a new script named
system_info.sh. This script will gather system information using different approaches to demonstrate the concepts, and redirect the output to distinct files in your~/projectdirectory.Open
system_info.shusingnano:nano system_info.shAdd the following content to the file:
#!/usr/bin/bash ## Define variables for output directory OUT_DIR='/home/labex/project' ## Loop through different information gathering approaches for APPROACH in "basic" "detailed"; do OUTPUT_FILE="${OUT_DIR}/output-${APPROACH}.txt" echo "Gathering ${APPROACH} system information..." ## Clear previous output file or create a new one > "${OUTPUT_FILE}" ## Get hostname information echo "#### Hostname Information ###" >> "${OUTPUT_FILE}" if [ "${APPROACH}" = "basic" ]; then hostname >> "${OUTPUT_FILE}" else hostname -f >> "${OUTPUT_FILE}" fi echo "" >> "${OUTPUT_FILE}" ## Add a blank line for readability ## Get CPU information (only lines starting with CPU) echo "#### CPU Information ###" >> "${OUTPUT_FILE}" lscpu | grep '^CPU' >> "${OUTPUT_FILE}" echo "" >> "${OUTPUT_FILE}" ## Get system users with bash shell echo "#### Users with Bash Shell ###" >> "${OUTPUT_FILE}" grep "bash" /etc/passwd >> "${OUTPUT_FILE}" echo "" >> "${OUTPUT_FILE}" ## Get system information based on approach if [ "${APPROACH}" = "basic" ]; then echo "#### Basic System Info ###" >> "${OUTPUT_FILE}" uname -r >> "${OUTPUT_FILE}" else echo "#### Detailed System Info ###" >> "${OUTPUT_FILE}" uname -a >> "${OUTPUT_FILE}" fi echo "" >> "${OUTPUT_FILE}" echo "Information saved to ${OUTPUT_FILE}" echo "-----------------------------------------------------" done echo "Script execution complete."Save the file by pressing
Ctrl+O, thenEnter, andCtrl+Xto exitnano.Key elements of this script:
OUT_DIR='/home/labex/project': Variable is used to make the script more flexible and readable.OUTPUT_FILE="${OUT_DIR}/output-${APPROACH}.txt": Constructs the output filename dynamically for each approach.> "${OUTPUT_FILE}": This redirects the output of an empty command to the file, effectively clearing its content if it exists or creating it if it doesn't. This ensures a fresh file for each run.>> "${OUTPUT_FILE}": This appends the output of the command to the specified file.if [ "${APPROACH}" = "basic" ]; then ... else ... fi: Conditional statements that execute different commands based on the approach being used.echo "#### Section Header ###": Adds clear headers to the output file for better organization.
Make the script executable.
chmod +x system_info.shThere will be no direct output from this command if successful.
Execute the
system_info.shscript. Run your comprehensive script. It will gather system information using different approaches and save the results to separate files../system_info.shYou should see output in your terminal indicating the script's progress:
Gathering basic system information... Information saved to /home/labex/project/output-basic.txt ----------------------------------------------------- Gathering detailed system information... Information saved to /home/labex/project/output-detailed.txt ----------------------------------------------------- Script execution complete.Review the generated output files. Check the content of the
output-basic.txtandoutput-detailed.txtfiles in your~/projectdirectory to verify that the script collected the information as expected.cat ~/project/output-basic.txt cat ~/project/output-detailed.txtThe content of each file should be similar to this (actual values will vary):
output-basic.txt:
#### Hostname Information ### 684791f71c0e35fea6cc1243 #### CPU Information ### CPU op-mode(s): 32-bit, 64-bit CPU(s): 4 CPU family: 6 #### Users with Bash Shell ### root:x:0:0:root:/root:/bin/bash labex:x:1000:1000::/home/labex:/bin/bash #### Basic System Info ### 5.4.0-162-genericoutput-detailed.txt:
#### Hostname Information ### 684791f71c0e35fea6cc1243 #### CPU Information ### CPU op-mode(s): 32-bit, 64-bit CPU(s): 4 CPU family: 6 #### Users with Bash Shell ### root:x:0:0:root:/root:/bin/bash labex:x:1000:1000::/home/labex:/bin/bash #### Detailed System Info ### Linux 684791f71c0e35fea6cc1243 5.4.0-162-generic #179-Ubuntu SMP Mon Aug 14 08:51:31 UTC 2023 x86_64 x86_64 x86_64 GNU/LinuxThis final script demonstrates how you can combine various Bash features and Linux commands to create powerful automation tools for system administration tasks.
Summary
In this lab, you learned the fundamental steps of creating and executing Bash scripts for RHEL system administration. You began by setting up a dedicated directory for scripts and then crafted a simple Bash script, understanding the importance of the shebang line and using the echo command. You explored different methods of executing scripts, including directly with the bash interpreter and by making them executable.
Furthermore, you enhanced your scripting skills by incorporating system commands and automating tasks using for loops to gather system information with different approaches. You also learned how to filter command output effectively using grep and regular expressions, a crucial skill for parsing system information. Finally, you applied these concepts to build a comprehensive RHEL system information script, demonstrating how to combine various commands and scripting constructs to gather and present valuable system data.



