Tengo un archivo de configuración que se parece a esto:

#!/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.

Cuando lo incluyo en el script de configuración e itero las claves del AA, las obtengo sin ningún orden en particular. Las partes derechas de las claves (DEV, MNT ...) son fijas, pero no todas son obligatorias, mientras que las partes de la izquierda pueden ser algo aleatorias (solo un mnemónico).

Lo que necesito es una lista de las partes de la izquierda para saber qué particiones deben crearse, luego averiguar cuáles de las partes de la derecha están definidas (y si no, establecer un valor predeterminado), de modo que cada partición esté bien definida antes de crearse realmente la partición, agregarla a fstab, montar ...

Estamos hablando de nuevos sistemas aquí. Las únicas dos opciones para realizar la tarea son Bash y / o Perl. Sin JavaScript, sin Python, sin C # Script, lo siento. Sed y Awk están disponibles. Debido a que los pasos de configuración anteriores se realizan en Bash, preferiría una solución Bash simple (más Sed / Awk, si es necesario).

Por supuesto, es posible cambiar el archivo de configuración. Lo único obligatorio es mantener la flexibilidad de la parte izquierda de las teclas.

0
CarstenP 29 ene. 2016 a las 17:51

2 respuestas

La mejor respuesta

Si bien tiendo a estar de acuerdo con el comentario de @ EdMorton de que awk es una herramienta superior, este problema no es particularmente complicado, y bash probablemente esté bien:

# 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
1
rici 29 ene. 2016 a las 21:52

¡awk al rescate!

$ 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

Puede cambiar el separador entre los componentes correctos configurando OFS.

1
karakfa 29 ene. 2016 a las 15:04