
Puedo redirigir la salida de un script a un archivo de registro desde dentro del script con exec
:
#!/bin/bash
exec > stdout.log 2>&1
echo hello world
¿Es posible redirigir la salida a less
un archivo en lugar de hacerlo? Lo intenté
#!/bin/bash
exec > >(less) 2>&1
# output some text
for (( i=1; i <= 500; i++ )); do echo "hello world $i"; done
pero esto falla de una manera extraña... cuanto menos mensaje es visible, terminas de regreso en la terminal.
Me gustaría configurar esto al inicio del script (para que pueda ser condicional, dependiendo de los argumentos, tty, etc.).
Respuesta1
Debe hacer que su secuencia de comandos espere al less
proceso hijo; de lo contrario, su secuencia de comandos terminará antes que él y less
de repente se encontrará fuera del grupo de procesos de primer plano, sin poder leer comandos desde la terminal ni restaurar la configuración de la terminal.
Además, para evitar less
esperar eternamente hasta el final de su entrada, su script debe cerrar la tubería.
Juntando todo eso:
exec > >(less) 2>&1
trap 'exec >&- 2>&-; wait' EXIT
# >&- 2>&- => close stdout and stderr => cause EOF on less' stdin
seq 1 50000
# the rest of your script
Pero esto no es muy agradable, no es portátil para la mayoría de los otros shells y depende del comportamiento no documentado (y poco confiable) de bash: wait
no funcionará bien si tiene más de uno exec > >(...)
en su script y también esperará en otros antecedentes. procesos iniciados con &
.
Una mejor idea sería hacer que su script se llame a sí mismo, usando una variable de entorno para evitar la recursividad infinita:
if [ ! "$CALLED_MYSELF" ]; then
set -o pipefail # supported in bash, but not in all the shells
CALLED_MYSELF=1 "$0" "$@" 2>&1 | less
exit
fi
seq 1 50000
# the rest of your script
Respuesta2
Pruebe solo esto (sin la exec
línea):
for (( i=1; i <= 500; i++ )); do echo "hello world $i"; done | less
(actualizar)
Si desea incluir el script completo, puede envolver el script con{ ... }
#!/bin/bash
{
# output some text
for (( i=1; i <= 500; i++)) do echo "hello world $i"; done
# whatever output you want...
} | less