Reputation: 241
I have a configuration file which looks like this:
#!/bin/bash
# lots of other stuff
declare -A PARTITIONS
PARTITIONS[ROOT,DEV]=/dev/mmcblk0p2
PARTITIONS[ROOT,MNT]=/
PARTITIONS[ROOT,FSTYPE]=ext4
PARTITIONS[ROOT,OPTS]='rw,suid,exec,auto,nouser,async,errors=remount-ro,noatime,nodiratime,commit=120 0 1'
PARTITIONS[ROOT,START]=64MB
PARTITIONS[ROOT,END]=6143.9MB
PARTITIONS[ROOT,OWNER]=root.root
PARTITIONS[ROOT,PERMS]=755
PARTITIONS[DATA,DEV]=/dev/mmcblk0p7
PARTITIONS[DATA,MNT]=/data
PARTITIONS[DATA,FSTYPE]=xfs
PARTITIONS[DATA,OPTS]='rw,noexec,auto,user,suid,noatime,nodiratime,async,logbufs=4,noquota 0 3'
PARTITIONS[DATA,START]=12288MB
PARTITIONS[DATA,END]=-1s
PARTITIONS[DATA,OWNER]=root.root
PARTITIONS[DATA,PERMS]=755
etc etc etc.
When I include it in the configuring script and iterate the keys of the AA, I get them in no particular order. The right parts of the keys (DEV, MNT...) are fixed, but not all are mandatory, while the left parts can be kind of random (just a mnemonic).
What I need is a list of the left parts to know which partitions must be created, then find out which of the right parts are defined (and if not, set a default value), so each partition will be well-defined before actually creating the partition, adding it to fstab, mounting...
We are talking about fresh systems here. The only two options to accomplish the task are Bash and/or Perl. No JavaScript, no Python, no C# Script, sorry. Sed and Awk are available. Because the setup steps before are done in Bash, I'd prefer a plain Bash (plus Sed/Awk, if needed) solution.
Of course its possible to change the configuration file. The only mandatory thing is to keep the flexibility of the left part of the keys.
Upvotes: 0
Views: 61
Reputation: 241881
While I tend to agree with @EdMorton's comment that awk is a superior tool, this problem is not particularly complicated, and bash is probably just fine:
# Find all the left-hand keys
declare -A keys
for key in "${!PARTITIONS[@]}"; do
keys[${key%%,*}]=1
done
# Set defaults and/or check validity
errors=0
for key in "${!keys[@]}"; do
# Set a default
: "${PARTITIONS[$key,FSTYPE]:=ext4}"
# Make sure a setting exists.
# -v requires v4.2; otherwise use -n/-z. Maybe you
# want those anyway, since a blank config might be an error.
if [[ ! -v PARTITIONS[$key,MNT] ]]; then
printf "MNT key missing for partition %s\n" "$key" >>/dev/stderr
# Remove it from the set so it doesn't show up later
unset keys[$key]
((errors++))
fi
# Etc.
done
# For debugging purposes, just print out the settings
for key in "${!keys[@]}"; do
printf "$key:"
for field in DEV MNT FSTYPE OPTS START END OWNER PERMS; do
printf " %s=%b" $field "${PARTITIONS[$key,$field]}"
done
echo
done
if ((errors)); then
printf "Config errors. Not proceeding\n" >> /dev/stderr
return 1
fi
# Do what needs to be done
# probably another loop over keys
Upvotes: 1
Reputation: 67507
awk
to the rescue!
$ awk -F'[\\]\\[,]' '/^PARTITIONS/{a[$2]=a[$2]?a[$2] OFS $3:$3}
END{for(k in a) print k ": " a[k]}' conf
DATA: DEV MNT FSTYPE OPTS START END OWNER PERMS
ROOT: DEV MNT FSTYPE OPTS START END OWNER PERMS
you can change the separator between the right components by setting up OFS.
Upvotes: 1