Para validar cada línea como usted lo lee, la manera segura de hacer esto es escribir una expresión regular y utilizar BASH_REMATCH
para extraer grupos de concordancia de ella .
Con el siguiente código:
re='^"(.*)" [{]([0-9a-f-]+)[}]$'
while read -r line; do
if [[ $line =~ $re ]]; then
name=${BASH_REMATCH[1]}; uuid=${BASH_REMATCH[2]}
echo "Found VM with name $name and uuid $uuid" >&2
else
echo "ERROR: Could not parse line: $line" >&2
fi
done < <(VBoxManage list runningvms)
... y la siguiente aplicación simulada de VBoxManage (para permitir que la gente sin VirtualBox para reproducir la prueba):
VBoxManage() { printf '%s\n' '"UbuntuServer" {7ef01f8d-a7d5-4405-af42-94d85f999dff}'; }
... de salida es de la siguiente manera:
Found VM with name UbuntuServer and uuid 7ef01f8d-a7d5-4405-af42-94d85f999dff
Tenga en cuenta las ventajas de este enfoque:
- No hace suposiciones infundadas, como excluir máquinas virtuales con espacios en blanco o citar literales en sus nombres de soporte.
- Detecta cualquier línea que no coincida con el patrón esperado, en lugar de comportarse de una forma no anticipada en presencia de tales valores.
- Todavía se comporta correctamente con los datos que hace coincide con el patrón, pero tiene valores imprevistos. (Por ejemplo, una máquina virtual llamada
*
no tendrá ese nombre reemplazado silenciosamente con el nombre de un archivo en el directorio actual).
- que no implica herramientas exteriores al depósito tal como
sed
, cut
, & c, sino que se basa exclusivamente en la funcionalidad shell-builtin -. Ver BashFAQ #1 documentar el uso de while read
, y the bash-hackers' wiki on regular expression matching documentar [[ $string =~ $re ]]
.
El "enfoque clásico" es una mala práctica, como lo es el enfoque 'array = ($ (...))'; ambos, por ejemplo, reemplazarán un solo token '*' en su entrada con una lista de archivos en el directorio actual. Consulte [No leer líneas con For] (http://mywiki.wooledge.org/DontReadLinesWithFor), [BashPitfalls # 50] (http://mywiki.wooledge.org/BashPitfalls#hosts.3D.28_.24.28aws_ .... 29_.29), y [BashFAQ # 1] (http://mywiki.wooledge.org/BashFAQ/001) –
Necesita división de palabras para este ejemplo específico, y el nombre VM que coincide con un patrón global parece improbable. – Mat
El peor evento de pérdida de datos en el que he estado presente sucedió porque alguien ignoró un evento "imposible" (un programa que crea archivos "posiblemente no podría" crear nada que no coincida [0-9a-f] {24}; un error en una biblioteca de terceros corrompió un puntero, volcando basura aleatoria que incluía un '' 'rodeado de espacios en blanco en el búfer utilizado para un nombre ... y un script de shell que iteraba sobre los nombres de archivo a la edad del sistema de respaldo y luego borraba *todo*). –