Reindirizza l'output a less dall'interno dello script
Posso reindirizzare l'output di uno script a un file di registro dall'interno dello script con exec:
#!/bin/bash
exec > stdout.log 2>&1
echo hello world
È possibile reindirizzare l'output a lessinvece che a un file? Provai
#!/bin/bash
exec > >(less) 2>&1
# output some text
for (( i=1; i <= 500; i++ )); do echo "hello world $i"; done
ma questo fallisce in modo strano ... il prompt meno è visibile ma si finisce di nuovo al terminale.
Mi piacerebbe impostarlo all'inizio dello script (quindi può essere condizionale, a seconda degli argomenti, tty, ecc.).
Risposte
Dovresti fare in modo che il tuo script attenda il lessprocesso figlio, altrimenti il tuo script terminerà prima di esso e lesssi ritroverà improvvisamente fuori dal gruppo di processi in primo piano, non in grado di leggere i comandi dal terminale o ripristinare le impostazioni del terminale più.
Inoltre, per evitare lessdi aspettare per sempre la fine del suo input, lo script dovrebbe chiudere il pipe ad esso.
Mettendo tutto insieme:
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
Ma questo non è molto bello, non portabile alla maggior parte delle altre shell e fa affidamento su un comportamento non documentato (e inaffidabile) di bash: waitnon funzionerà bene se ne hai più di una exec > >(...)nel tuo script e aspetterà anche su un altro sfondo processi iniziati con &.
Un'idea migliore sarebbe quella di far chiamare lo script da solo, utilizzando una variabile di ambiente per evitare la ricorsione 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
Prova solo questo (senza la execlinea):
for (( i=1; i <= 500; i++ )); do echo "hello world $i"; done | less
(aggiornare)
Se vuoi includere l'intero script, puoi avvolgere lo script con { ... }
#!/bin/bash
{
# output some text
for (( i=1; i <= 500; i++)) do echo "hello world $i"; done
# whatever output you want...
} | less