Comment limiter le nombre de lignes dont une sortie de commande dispose en bash?

11

J'ai commencé à télécharger un gros fichier en arrière-plan en utilisant

$ nohup wget http://example.tld/big.iso &

ce qui me donne également un nohup.outfichier qui inclut la sortie de wget.

Maintenant, si je veux plus tard regarder le processus de téléchargement, je pourrais utiliser $ tail -f nohup.outmais cela remplit ma fenêtre de terminal plus rapidement que je ne le souhaiterais. Ce que j'aimerais voir, c'est la dernière ligne constamment mise à jour (comme lorsque vous l'utilisez wgetseule).

J'ai essayé $ tail -n 1 -f nohup.outmais cela semble n'affecter que le tailin initial.

D'une manière générale, s'il est possible de limiter (dans ce cas à 1) le nombre de lignes qu'une sortie de commande a disponible / visible, cela résoudrait ce problème. Sorte d'avoir la sortie dans un tampon circulaire - pensez simplement à la barre de progression normale $ wget example.tld/big.isoqui s'imprimerait.

Existe-t-il une telle solution?

Ou suis-je en train de grimper dans le mauvais sens? (Ce qui signifie qu'il serait plus facile de limiter nohupla sortie de ou de faire autre chose?)

Jari Keinänen
la source

Réponses:

10

Si vous ne souhaitez pas limiter la zone de défilement (voir mon autre réponse), vous pouvez également utiliser le retour chariot pour revenir au début de la ligne avant d'imprimer la ligne suivante. Il existe une séquence d'échappement qui efface le reste de la ligne, ce qui est nécessaire lorsque la ligne actuelle est plus courte que la ligne précédente.

nohup wget http://cdimage.debian.org/debian-cd/6.0.3/amd64/iso-dvd/debian-6.0.3-amd64-DVD-1.iso &
el="$(tput el)"; # Clear to the end of the line
tail -n 1 -f nohup.out | while read -r line; do echo -n $'\r'"$el$line"; done;
janmoesen
la source
6

Vous pouvez utiliser watchici:

watch -n 0.5 -e "tail -n 1 nohup.out"

Modifier : l' option -e(alias --exec) semble appropriée ici. Surtout si vous visez à courir watchavec de très petits intervalles, cela réduit les frais généraux causés par le fonctionnement sh -cinterne watchà chaque cycle.

rozcietrzewiacz
la source
2
Notez que cela engendre un nouveau tailprocessus chaque seconde, qui pourrait ou non être quelque chose qui vous tient à cœur. Veillez également à spécifier un intervalle d'une sous-seconde (par exemple watch -n 0.1) pour simuler la partie "constamment mise à jour". (Cela augmente évidemment le nombre de processus et de fichiers ouverts également.) Enfin, si vous utilisez OS X, vous pouvez obtenir watchde MacPorts, car il n'est pas disponible par défaut.
janmoesen
C'est un peu contournant, mais génial en tant que tel. Je m'attendais à une réponse non plein écran, pour que je puisse voir les sorties précédentes - mais vraiment je pourrais utiliser watchdans une nouvelle fenêtre de terminal. J'ai également découvert que l'utilisation tail -n 2est plus utile -n 1qu'avec wget, au moins avec un watchintervalle de 1 seconde, car sinon le dernier pourcentage pourrait ne pas être vu; ce n'est pas un défaut dans votre réponse, mais je l'ai mentionné si quelqu'un d'autre décide de regarder la sortie de nohup à queue wgets.
Jari Keinänen
@janmoesen Pour ce scénario spécifique, avoir un nouveau tailprocessus n'est probablement pas trop exagéré; mais comme réponse générale, il est bon d'en tenir compte. J'ai également noté que watch -n 0.1cela ne fonctionnait pas, mais watch -n 0,1fonctionnait - il pourrait y avoir des paramètres régionaux appliqués, bien que je n'ai jamais vu de paramètres régionaux appliqués aux options de commande de terminal auparavant. En passant: brew install watcha aussi bien fonctionné :-)
Jari Keinänen
Une note latérale: si watchcela fonctionnera avec 0,1ou 0.1dépend de vos paramètres régionaux (il utilise le symbole décimal défini pour vos paramètres régionaux). Vérifiez LC_ALL=C watch -n 0.1 "date +%S.%N".
rozcietrzewiacz
3

Il existe certaines séquences de contrôle Xterm que vous pouvez utiliser pour limiter les lignes de votre terminal qui défilent. Recherchez «Définir la région de défilement». C'est un peu compliqué, cependant. Assurez-vous de réinitialiser votre terminal par la suite:

nohup wget http://cdimage.debian.org/debian-cd/6.0.3/amd64/iso-dvd/debian-6.0.3-amd64-DVD-1.iso &
clear; echo -n $'\e[1;2r'; tail -f nohup.out | grep --line-buffered .
# The "grep" line is to ensure a single line; you can also use "awk 1" or "sed" etc.
janmoesen
la source
<Insérez ici la note habituelle sur la non-portabilité>
janmoesen
C'est une autre excellente alternative, mais celle qui est également mieux utilisée dans la fenêtre dédiée car tail -felle remplit toujours le tampon et également parce que le terminal doit être réinitialisé par la suite de toute façon. Ce n'est pas aussi en ligne que je l'espérais, mais sinon ce pourrait être ce que je cherchais.
Jari Keinänen
0

Si vous ne voulez pas que la sortie occupe toute la fenêtre de terminal actuelle, vous pouvez utiliser une whileboucle simple :

while true; do 
  XXX=$( tail -n1 my.log )
  echo -en " \r$XXX\r"
  sleep 0.5
done; echo
rozcietrzewiacz
la source
1
Notez que pour pouvoir faire défiler la sortie du terminal pendant l' exécution de toute commande de production de sortie, vous devez modifier les paramètres de l'émulateur de terminal et désactiver scrollTtyOutput(ou similaire) l'option.
rozcietrzewiacz