Red Hat Certified System Administrator(RHCSA)

Use Looping constructs for etc 2

In this section, we'll explore the use of while loops in our scripts. Our previous implementation reported errors by using the rocket debug command if the rocket’s status was "failed." Recall that the rocket status command can return one of three states: launching, success, or failed. After liftoff, the rocket typically remains in the launching state for a period, eventually transitioning to either a success or failed state.

For example, executing the following command shortly after liftoff might display the status as "launching":

$ rocket-status lunar-mission
launching

Initially, our script checked the status only once immediately after liftoff:

mission_name=$1

mkdir $mission_name
rocket-add $mission_name

rocket-start-power $mission_name
rocket-internal-power $mission_name
rocket-start-sequence $mission_name
rocket-start-engine $mission_name
rocket-lift-off $mission_name

rocket_status=$(rocket-status $mission_name)
if [ "$rocket_status" = "failed" ]; then
    rocket-debug $mission_name
fi

If the rocket stays in the launching state for a few seconds and then fails, a single status check might miss the failure. Consider this case:

$ rocket-status lunar-mission
success

In this example, our script could potentially overlook a failure if it happens after the lone check.

Tip

To handle scenarios where the rocket's status remains "launching" beyond the initial check, it's important to add a mechanism that waits and keeps checking until the state transitions to either "success" or "failed."

One way to address this is to add nested conditionals with pauses:

mkdir $mission_name
rocket-add $mission_name

rocket-start-power $mission_name
rocket-internal-power $mission_name
rocket-start-sequence $mission_name
rocket-start-engine $mission_name
rocket-lift-off $mission_name

rocket_status=$(rocket-status $mission_name)
if [ "$rocket_status" = "launching" ]; then
    sleep 2
    rocket_status=$(rocket-status $mission_name)
    if [ "$rocket_status" = "launching" ]; then
        sleep 2
        rocket_status=$(rocket-status $mission_name)
        if [ "$rocket_status" = "launching" ]; then
            # Continue with additional nested checks…
            :
        fi
    fi
fi

if [ "$rocket_status" = "failed" ]; then
    rocket-debug $mission_name
fi

However, this method quickly becomes unwieldy when dealing with longer launch durations, as it requires an impractical number of nested conditionals to handle every possible state check.

A more robust solution is to replace the nested conditionals with a while loop. The while loop repeatedly executes commands as long as the specified condition remains true. Below is an improved version of our script using a while loop:

mission_name=$1
mkdir $mission_name
rocket-add $mission_name

rocket-start-power $mission_name
rocket-internal-power $mission_name
rocket-start-sequence $mission_name
rocket-start-engine $mission_name
rocket-lift-off $mission_name

rocket_status=$(rocket-status $mission_name)
while [ "$rocket_status" = "launching" ]; do
    sleep 2
    rocket_status=$(rocket-status $mission_name)
done

if [ "$rocket_status" = "failed" ]; then
    rocket-debug $mission_name
fi

With this approach, the script pauses for two seconds and then rechecks the rocket's status repeatedly until it is no longer "launching." Once the status changes, the loop exits, and if the final state is "failed," the script invokes the debug command.

When to Use While Loops

Looping structures like the while loop are essential when you need to repeat operations without knowing the exact number of iterations in advance. Unlike for loops that work with a predetermined count, while loops continuously execute until a specific condition is met.

The image is a slide explaining when to use a "while loop," listing scenarios such as executing commands multiple times, until a condition occurs, creating infinite loops, and for menu-driven programs.

Another common scenario where while loops shine is in creating menu-driven programs or infinite loops. Consider the example below that displays a menu with three options: shutdown, restart, or exit the menu. Based on the user's input, the corresponding action is executed:

while true; do
  echo "1. Shutdown"
  echo "2. Restart"
  echo "3. Exit Menu"
  read -p "Enter your choice: " choice
  if [ "$choice" -eq 1 ]; then
    shutdown now
  elif [ "$choice" -eq 2 ]; then
    shutdown -r now
  elif [ "$choice" -eq 3 ]; then
    break
  else
    continue
  fi
done

In this script:

  • Choosing option 1 triggers an immediate shutdown.
  • Option 2 restarts the system.
  • Option 3 breaks the loop, thus exiting the menu.
  • The continue statement ensures the loop restarts when an invalid choice is entered.

Summary

While loops offer a clean and efficient method to repeatedly execute commands until a desired condition is met, making them indispensable for scripting scenarios with unpredictable durations or outcomes.

Watch Video

Watch video content