I have an array that may or may not contain BMC, and I'm looping through each element of the array. If it does contain BMC I want BMC to be the last iteration of the loop.
The array is created with command line options so I don't think I can enforce the order of creation without making significant changes.
Example:
#!/usr/bin/env bash
while getopts cnBba opt; do
case $opt in
c) options+=(CPLD);;
n) options+=(NIC);;
B) options+=(BMC);;
b) options+=(BIOS);;
a) all=true;;
esac
done
# This is probably really confusing because it's redacted but this script also
# allows for -a to be used and then I'll query an endpoint that gives me a list
# of all available firmware for the given server. It could return some or all
# of the possible options in no particular order.
mapfile -t types < <(curl some_firmware_endpoint)
if [[ $all == true ]]; then
options=($(printf '%s\n' "${types[@]}" NIC | sort -u))
fi
for opt in "${options[@]}"; do
echo "option is $opt"
done
Which produces this output:
$ ./script.sh -Bbcn
option is BMC
option is BIOS
option is CPLD
option is NIC
But I would like this output:
$ ./script.sh -Bbcn
option is BIOS
option is CPLD
option is NIC
option is BMC
I sort of have a solution but it's creating a null element in the array, which I'm sure I could further deal with but there may be a more correct way to do this.
My solution:
#!/usr/bin/env bash
while getopts cnBba opt; do
case $opt in
c) options+=(CPLD);;
n) options+=(NIC);;
B) options+=(BMC);;
b) options+=(BIOS);;
a) all=true;;
esac
done
# This is probably really confusing because it's redacted but this script also
# allows for -a to be used and then I'll query an endpoint that gives me a list
# of all available firmware for the given server. It could return some or all
# of the possible options in no particular order.
mapfile -t types < <(curl some_firmware_endpoint)
if [[ $all == true ]]; then
options=($(printf '%s\n' "${types[@]}" NIC | sort -u))
fi
if [[ "${options[@]}" =~ BMC ]]; then
options=("${options[@]/BMC/}" BMC)
fi
for opt in "${options[@]}"; do
echo "option is $opt"
done
Which produces:
$ ./script.sh -Bbcn
option is
option is BIOS
option is CPLD
option is NIC
option is BMC
The -a all option:
The all option will query an endpoint (basically just a json object) that will have a list of firmware available for a server type. Some servers may only return BIOS BMC, some may return BIOS BMC NIC CPLD SATA StorageController or even more. Because of the way the json object is organized most of them will list NIC firmware separately so I'm manually adding that when -a is used and I handle that error separately if there is no firmware for that particular NIC, and then since some of them also have NIC I do a sort -u to remove NIC if it's listed twice.