programas - scripts bash ejemplos
Capturando salida de mĂșltiples lĂneas en una variable Bash (6)
Tengo un script ''myscript'' que genera lo siguiente:
abc
def
ghi
en otro guión, llamo:
declare RESULT=$(./myscript)
y $RESULT
obtiene el valor
abc def ghi
¿Hay alguna forma de almacenar el resultado con las nuevas líneas o con el carácter ''/ n'' para que pueda mostrarlo con '' echo -e
''?
¿Qué tal esto, leerá cada línea a una variable y se puede usar posteriormente? digamos que la salida de myscript se redirige a un archivo llamado myscript_output
awk ''{while ( (getline var < "myscript_output") >0){print var;} close ("myscript_output");}''
Además de la respuesta dada por @ l0b0, acabo de tener la situación en la que necesitaba mantener el resultado de las nuevas líneas finales por el script y verificar el código de retorno del script. ¿Y el problema con la respuesta de l0b0 es que el ''echo x'' estaba reiniciando $? de vuelta a cero ... así que logré encontrar esta solución muy astuta:
RESULTX="$(./myscript; echo x$?)"
RETURNCODE=${RESULTX##*x}
RESULT="${RESULTX%x*}"
Después de probar la mayoría de las soluciones aquí, lo más fácil que encontré fue lo obvio: usar un archivo temporal. No estoy seguro de lo que quiere hacer con su salida de múltiples líneas, pero luego puede lidiar con ella línea por línea utilizando la función de lectura. Lo único que realmente no se puede hacer es pegarlo todo en la misma variable, pero para la mayoría de los propósitos prácticos, esto es mucho más fácil de manejar.
./myscript.sh > /tmp/foo
while read line ; do
echo ''whatever you want to do with $line''
done < /tmp/foo
Truco rápido para que haga la acción solicitada:
result=""
./myscript.sh > /tmp/foo
while read line ; do
result="$result$line/n"
done < /tmp/foo
echo -e $result
Tenga en cuenta que esto agrega una línea extra. Si trabajas en él puedes codificarlo, soy demasiado vago.
EDITAR: Si bien este caso funciona perfectamente bien, las personas que lo lean deben ser conscientes de que puede aplastar fácilmente su stdin dentro del bucle while, lo que le brinda un script que ejecutará una línea, borrará el stdin y saldrá. Como ssh va a hacer eso creo? Acabo de verlo recientemente, otros ejemplos de código aquí: https://unix.stackexchange.com/questions/24260/reading-lines-from-a-file-with-bash-for-vs-while
¡Una vez más! Esta vez con un identificador de archivo diferente (stdin, stdout, stderr son 0-2, así que podemos usar & 3 o más en bash).
result=""
./test>/tmp/foo
while read line <&3; do
result="$result$line/n"
done 3</tmp/foo
echo -e $result
También puede usar mktemp, pero esto es solo un ejemplo de código rápido. El uso para mktemp se ve como:
filenamevar=`mktemp /tmp/tempXXXXXX`
./test > $filenamevar
Luego use $ filenamevar como lo haría con el nombre real de un archivo. Probablemente no sea necesario explicarlo aquí, pero alguien se quejó en los comentarios.
En caso de que esté interesado en líneas específicas, use una matriz de resultados:
declare RESULT=($(./myscript)) # (..) = array
echo "First line: ${RESULT[0]}"
echo "Second line: ${RESULT[1]}"
echo "N-th line: ${RESULT[N]}"
En realidad, RESULTADO contiene lo que quieres, para 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 de la variable con comillas dobles ( 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, pestañas y líneas nuevas con un solo espacio. Por lo tanto (1) conserva la forma de la variable de entrada, mientras que (2) crea una línea de salida única potencialmente muy larga con ''palabras'' separadas por espacios individuales (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 escollo con esto es que la sustitución de comandos - $()
- elimina las líneas finales. Probablemente no siempre es importante, pero si realmente desea conservar exactamente lo que se obtuvo, tendrá que usar otra línea y algunas citas:
RESULTX="$(./myscript; echo x)"
RESULT="${RESULTX%x}"
Esto es especialmente importante si desea manejar todos los nombres de archivo posibles (para evitar comportamientos indefinidos como operar en el archivo incorrecto).