Bird
Raised Fist0
Bash Scriptingscripting~20 mins

Long option parsing in Bash Scripting - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Long Option Parsing Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
💻 Command Output
intermediate
2:00remaining
Output of a script parsing long options with getopts
What is the output of this Bash script when run with arguments --name=John --age=30?
Bash Scripting
#!/bin/bash
while getopts ":-:" opt; do
  case $opt in
    -)
      case $OPTARG in
        name=*)
          name=${OPTARG#*=}
          echo "Name: $name"
          ;;
        age=*)
          age=${OPTARG#*=}
          echo "Age: $age"
          ;;
        *)
          echo "Unknown option: --$OPTARG"
          ;;
      esac
      ;;
    *)
      echo "Invalid option: -$OPTARG"
      ;;
  esac
done
A
Name: John
Age: 30
B
Unknown option: --name=John
Unknown option: --age=30
C
Name: --name=John
Age: --age=30
D
Invalid option: -n
Invalid option: -a
Attempts:
2 left
💡 Hint
Look at how the script extracts values after the '=' sign in long options.
📝 Syntax
intermediate
2:00remaining
Identify the syntax error in long option parsing
Which option contains a syntax error that prevents parsing long options correctly?
Bash Scripting
while getopts ":-" opt; do
  case $opt in
    -)
      case $OPTARG in
        name=*)
          name=${OPTARG#*=}
          echo "Name: $name"
          ;;
        age=*)
          age=${OPTARG#*=}
          echo "Age: $age"
          ;;
        *)
          echo "Unknown option: --$OPTARG"
          ;;
      esac
      ;;
    *)
      echo "Invalid option: -$OPTARG"
      ;;
  esac
done
AMissing quotes around variable expansions in echo statements
BUsing $OPTARG instead of $OPTIND inside the case statement
CIncorrect variable expansion syntax: ${OPTARG#*=} should be ${OPTARG:=*}
DMissing colon after '-' in getopts string: ":-" should be ":-:"
Attempts:
2 left
💡 Hint
Check the getopts option string carefully.
🔧 Debug
advanced
2:00remaining
Why does this long option parsing script fail to capture option values?
Given this script snippet, why does it fail to print the expected values when run with --file=example.txt?
while getopts ":-:" opt; do
  case $opt in
    -)
      case $OPTARG in
        file)
          file=$2
          echo "File: $file"
          shift 2
          ;;
        *)
          echo "Unknown option: --$OPTARG"
          ;;
      esac
      ;;
  esac
done
AMissing colon after 'file' in getopts string to accept an argument
BUsing $2 inside getopts loop is invalid; should use $OPTARG instead
CThe script expects the value as a separate argument, but the option is passed as --file=example.txt
DThe shift command inside the case breaks the getopts loop prematurely
Attempts:
2 left
💡 Hint
Think about how getopts treats options with '=' signs.
🚀 Application
advanced
3:00remaining
Write a snippet to parse --mode= and --verbose long options
Which code snippet correctly parses --mode=fast and --verbose options using getopts in Bash?
A
while getopts ":-:" opt; do
  case $opt in
    -)
      case $OPTARG in
        mode=*)
          mode=${OPTARG#*=}
          ;;
        verbose)
          verbose=1
          ;;
      esac
      ;;
  esac
done
B
while getopts ":m:v" opt; do
  case $opt in
    m)
      mode=$OPTARG
      ;;
    v)
      verbose=1
      ;;
  esac
done
C
while getopts ":-:" opt; do
  case $opt in
    -)
      case $OPTARG in
        mode)
          mode=$2
          shift 2
          ;;
        verbose)
          verbose=1
          ;;
      esac
      ;;
  esac
done
D
while getopts ":-:" opt; do
  case $opt in
    -)
      case $OPTARG in
        mode=*)
          mode=$OPTARG
          ;;
        verbose=*)
          verbose=$OPTARG
          ;;
      esac
      ;;
  esac
done
Attempts:
2 left
💡 Hint
Remember that options with '=' need to be parsed from $OPTARG.
🧠 Conceptual
expert
3:00remaining
Why is getopts limited for complex long option parsing?
Which statement best explains why getopts is not ideal for parsing complex long options in Bash scripts?
Agetopts automatically converts all long options to short options internally, causing conflicts
Bgetopts does not natively support long options with optional or multiple arguments and requires complex workarounds
Cgetopts requires external libraries to parse any options longer than one character
Dgetopts cannot parse any options starting with a dash (-) and only works with positional arguments
Attempts:
2 left
💡 Hint
Think about the design and limitations of getopts.

Practice

(1/5)
1. What is the main advantage of using long option parsing in bash scripts?
easy
A. It makes scripts easier to use with clear option names
B. It speeds up script execution significantly
C. It reduces the number of lines in the script
D. It automatically fixes syntax errors in scripts

Solution

  1. Step 1: Understand the purpose of long options

    Long options use descriptive names like --help instead of short flags like -h, making scripts easier to understand.
  2. Step 2: Compare benefits

    While long options improve clarity, they do not inherently speed up execution or reduce code length, nor fix syntax errors automatically.
  3. Final Answer:

    It makes scripts easier to use with clear option names -> Option A
  4. Quick Check:

    Long options improve clarity = D [OK]
Hint: Long options are about clarity, not speed or length [OK]
Common Mistakes:
  • Confusing long options with performance improvements
  • Thinking long options reduce script size
  • Assuming long options fix syntax errors automatically
2. Which of the following is the correct syntax to start parsing long options in a bash script?
easy
A. if [ "$1" == "--help" ]; then echo help; fi
B. while [[ "$1" == --* ]]; do case "$1" in ... ;; esac; shift; done
C. for arg in $@; do if [[ $arg == -* ]]; then ... fi; done
D. while getopts "h" opt; do case $opt in ... ;; esac; done

Solution

  1. Step 1: Identify long option parsing pattern

    Long options start with --, so checking if $1 starts with -- in a while loop is correct.
  2. Step 2: Analyze options

    while [[ "$1" == --* ]]; do case "$1" in ... ;; esac; shift; done uses while [[ "$1" == --* ]] and case to parse options, which is standard for long options. for arg in $@; do if [[ $arg == -* ]]; then ... fi; done checks short options, A is a single if, and D uses getopts which doesn't support long options.
  3. Final Answer:

    while [[ "$1" == --* ]]; do case "$1" in ... ;; esac; shift; done -> Option B
  4. Quick Check:

    Long option parsing uses while + case + --* check = C [OK]
Hint: Long options start with --, use while and case to parse [OK]
Common Mistakes:
  • Using getopts which only supports short options
  • Checking only single dash options
  • Not shifting arguments after processing
3. Given this snippet, what will be the output if the script is run with --name=John?
while [[ "$1" == --* ]]; do
  case "$1" in
    --name=*)
      name="${1#*=}"
      ;;
    --help)
      echo "Help requested"
      exit 0
      ;;
  esac
  shift
 done
 echo "Name is $name"
medium
A. Name is
B. Name is --name=John
C. Help requested
D. Name is John

Solution

  1. Step 1: Understand parameter expansion

    The pattern --name=* matches --name=John. The expression ${1#*=} removes everything up to and including the first '=' sign, extracting 'John'.
  2. Step 2: Follow script flow

    The script assigns 'John' to variable name, shifts arguments, then prints "Name is $name".
  3. Final Answer:

    Name is John -> Option D
  4. Quick Check:

    Parameter expansion extracts value = A [OK]
Hint: Use ${var#*=} to get value after '=' in long options [OK]
Common Mistakes:
  • Printing the whole argument instead of value after '='
  • Confusing option with its value
  • Not shifting arguments causing infinite loop
4. What is wrong with this long option parsing snippet?
while [[ "$1" == --* ]]; do
  case "$1" in
    --file)
      file="$2"
      shift
      ;;
    --help)
      echo "Help"
      exit 0
      ;;
  esac
  shift
done
medium
A. It should not shift twice in the loop
B. It uses single brackets instead of double brackets
C. It does not check if $2 exists before using it
D. It should use getopts for long options

Solution

  1. Step 1: Analyze argument usage

    The script assigns file="$2" without checking if $2 exists, which can cause errors if no value is provided.
  2. Step 2: Review other options

    Using double brackets is valid, shifting twice is correct here (once after reading value, once at loop end), and getopts does not support long options well.
  3. Final Answer:

    It does not check if $2 exists before using it -> Option C
  4. Quick Check:

    Missing check for $2 causes errors = A [OK]
Hint: Always verify next argument exists before using it [OK]
Common Mistakes:
  • Not checking if option value is missing
  • Confusing shift usage causing argument skipping
  • Trying to parse long options with getopts
5. You want to parse long options --user and --password where values can be given as --user=alice or --user alice. Which approach correctly handles both forms in bash?
hard
A. Use case with patterns --user=* and --user, assign value from ${1#*=} or $2 accordingly, shift once or twice
B. Use getopts with "user:" and "password:" options
C. Only accept --user=alice form and reject space-separated values
D. Parse all arguments with a for loop and split on '=' manually

Solution

  1. Step 1: Understand option forms

    Long options can be given as --user=alice or --user alice. The script must handle both.
  2. Step 2: Implement parsing logic

    Use case with --user=* to get value from ${1#*=}, and --user to get value from next argument $2. Shift accordingly to consume arguments.
  3. Step 3: Evaluate other options

    Getopts does not support long options, rejecting space-separated values reduces usability, and manual splitting in a for loop is error-prone.
  4. Final Answer:

    Use case with patterns --user=* and --user, assign value from ${1#*=} or $2 accordingly, shift once or twice -> Option A
  5. Quick Check:

    Handle both forms with case and shifts = B [OK]
Hint: Match both --option=* and --option, shift args properly [OK]
Common Mistakes:
  • Using getopts which lacks long option support
  • Ignoring space-separated values
  • Not shifting arguments correctly causing errors
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard