You should have your script wait for the less
child process, otherwise your script will terminate before it, and less
will suddenly find itself outside the foreground process group, not able to read commands from the terminal or restore the terminal settings anymore.
Also, in order to prevent less
for waiting forever for the end of its input, your script should close the pipe to it.
Putting all that together:
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
But this is not very nice, not portable to most other shells, and relying on undocumented (and unreliable) behaviour of bash: the wait
won't work fine if you have more than one exec > >(...)
in your script, and it will also wait on other background processes started with &
.
A better idea would be to have your script call itself, using an environment variable to avoid infinite recursion:
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