Capturar salida de varias líneas en una variable Bash
Tengo un script 'myscript' que genera lo siguiente:
abc
def
ghi
en otro script, llamo:
declare RESULT=$(./myscript)
y $RESULT
obtiene 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
'?
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).
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).
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]}"
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 myvar
variable:
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 read
en 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"