Capturar salida de varias líneas en una variable Bash

Resuelto Parker asked hace 15 años • 7 respuestas

Tengo un script 'myscript' que genera lo siguiente:

abc
def
ghi

en otro script, llamo:

declare RESULT=$(./myscript)

y $RESULTobtiene el valor

abc def ghi

¿Hay alguna manera de almacenar el resultado con las nuevas líneas o con el carácter '\n' para poder generarlo con ' echo -e'?

Parker avatar Mar 05 '09 11:03 Parker
Aceptado

En realidad, RESULTADO contiene lo que desea: demostrar:

echo "$RESULT"

Lo que muestras es lo que obtienes de:

echo $RESULT

Como se señaló en los comentarios, la diferencia es que (1) la versión entre comillas dobles de la variable ( echo "$RESULT") conserva el espaciado interno del valor exactamente como se representa en la variable (nuevas líneas, tabulaciones, múltiples espacios en blanco y todo), mientras que (2 ) la versión sin comillas ( echo $RESULT) reemplaza cada secuencia de uno o más espacios en blanco, tabulaciones y nuevas líneas con un solo espacio. Por lo tanto (1) preserva la forma de la variable de entrada, mientras que (2) crea una única línea de salida potencialmente muy larga con 'palabras' separadas por espacios simples (donde una 'palabra' es una secuencia de caracteres que no son espacios en blanco; no es necesario (No debe haber ningún alfanumérico en ninguna de las palabras).

Jonathan Leffler avatar Mar 05 '2009 04:03 Jonathan Leffler

Otro problema con esto es que la sustitución de comandos$() elimina las nuevas líneas finales. Probablemente no siempre sea importante, pero si realmente desea conservar exactamente lo que se generó, tendrá que usar otra línea y algunas comillas:

RESULTX="$(./myscript; echo x)"
RESULT="${RESULTX%x}"

Esto es especialmente importante si desea manejar todos los nombres de archivos posibles (para evitar comportamientos indefinidos como operar en el archivo incorrecto).

l0b0 avatar Mar 16 '2011 09:03 l0b0

En caso de que esté interesado en líneas específicas, utilice una matriz de resultados:

declare RESULT=($(./myscript))  # (..) = array
echo "First line: ${RESULT[0]}"
echo "Second line: ${RESULT[1]}"
echo "N-th line: ${RESULT[N]}"
user2574210 avatar Jul 11 '2013 20:07 user2574210

Analizando múltiples salidas

Introducción

Entonces myscript, las 3 líneas de salida podrían verse así:

myscript() { echo $'abc\ndef\nghi'; }

o

myscript() { local i; for i in abc def ghi ;do echo $i; done ;}

Ok, esta es una función, no un script (no necesita ruta ./), pero el resultado es el mismo

myscript
abc
def
ghi

Considerando el código de resultado

Para verificar el código de resultado, la función de prueba será:

myscript() { local i;for i in abc def ghi ;do echo $i;done;return $((RANDOM%128));}

1. Almacenar múltiples resultados en una sola variable, mostrando nuevas líneas

Tu funcionamiento es correcto:

RESULT=$(myscript)

Acerca del código de resultado , puede agregar:

RCODE=$?

incluso en la misma línea:

RESULT=$(myscript) RCODE=$?

Entonces

echo $RESULT $RCODE
abc def ghi 66
echo "$RESULT"
abc
def
ghi
echo ${RESULT@Q}
$'abc\ndef\nghi'
printf '%q\n' "$RESULT"
$'abc\ndef\nghi'

pero para mostrar la definición de variable, use declare -p:

declare -p RESULT RCODE
declare -- RESULT="abc
def
ghi"
declare -- RCODE="66"

2. Analizar múltiples resultados en una matriz, usandomapfile

Almacenamiento de respuesta en myvarvariable:

mapfile -t myvar < <(myscript)
echo ${myvar[2]}
ghi

Mostrando $myvar:

declare -p myvar
declare -a myvar=([0]="abc" [1]="def" [2]="ghi")

Considerando el código de resultado

En caso de que tenga que verificar el código de resultado, puede:

RESULT=$(myscript) RCODE=$?
mapfile -t myvar <<<"$RESULT"

declare -p myvar RCODE
declare -a myvar=([0]="abc" [1]="def" [2]="ghi")
declare -- RCODE="40"

3. Análisis de múltiples resultados por consecutivos readen el grupo de comandos

{ read firstline; read secondline; read thirdline;} < <(myscript)
echo $secondline
def

Mostrando variables:

declare -p firstline secondline thirdline
declare -- firstline="abc"
declare -- secondline="def"
declare -- thirdline="ghi"

A menudo uso:

{ read foo;read foo total use free foo ;} < <(df -k /)

Entonces

declare -p use free total
declare -- use="843476"
declare -- free="582128"
declare -- total="1515376"

Considerando el código de resultado

Mismo paso antepuesto:

RESULT=$(myscript) RCODE=$?
{ read firstline; read secondline; read thirdline;} <<<"$RESULT"

declare -p firstline secondline thirdline RCODE
declare -- firstline="abc"
declare -- secondline="def"
declare -- thirdline="ghi"
declare -- RCODE="50"
F. Hauri - Give Up GitHub avatar Oct 13 '2020 07:10 F. Hauri - Give Up GitHub