Rediriger la sortie vers less à partir du script interne
Je peux rediriger la sortie d'un script vers un fichier journal depuis l'intérieur du script avec exec:
#!/bin/bash
exec > stdout.log 2>&1
echo hello world
Est-il possible de rediriger la sortie vers lessau lieu d'un fichier? j'ai essayé
#!/bin/bash
exec > >(less) 2>&1
# output some text
for (( i=1; i <= 500; i++ )); do echo "hello world $i"; done
mais cela échoue d'une manière étrange ... la moins invite est visible mais vous vous retrouvez au terminal.
Je voudrais configurer cela au début du script (afin qu'il puisse être conditionnel, en fonction des arguments, tty, etc.).
Réponses
Votre script devrait attendre le lessprocessus enfant, sinon votre script se terminera avant lui et lessse retrouvera soudainement en dehors du groupe de processus de premier plan, incapable de lire les commandes du terminal ou de restaurer les paramètres du terminal.
De plus, pour éviter lessd'attendre indéfiniment la fin de son entrée, votre script doit fermer le tube.
Mettre tout cela ensemble:
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
Mais ce n'est pas très agréable, pas portable pour la plupart des autres shells, et s'appuyant sur un comportement non documenté (et peu fiable) de bash: waitcela ne fonctionnera pas bien si vous en avez plus d'un exec > >(...)dans votre script, et il attendra également sur un autre arrière-plan les processus ont commencé avec &.
Une meilleure idée serait de faire appeler votre script lui-même, en utilisant une variable d'environnement pour éviter une récursion infinie:
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
Essayez juste ceci (sans la execligne):
for (( i=1; i <= 500; i++ )); do echo "hello world $i"; done | less
(mettre à jour)
Si vous souhaitez inclure tout le script, vous pouvez envelopper le script avec { ... }
#!/bin/bash
{
# output some text
for (( i=1; i <= 500; i++)) do echo "hello world $i"; done
# whatever output you want...
} | less