Comment démarrer XTerm avec l'invite en bas?

Lors du démarrage de XTerm, l'invite démarre à la première ligne du terminal. Lorsque vous exécutez des commands, l'invite se déplace vers le bas jusqu'à ce qu'elle atteigne le bas, et à partir de là, elle rest là (pas même ShiftPage Down ou la souris peut changer cela). Plutôt que d'avoir le début de la durée de vie du terminal être "spécial" l'invite devrait toujours être au bas du terminal. S'il vous plaît noter que j'ai une invite de plusieurs lignes .

Bien sûr, il devrait normalement fonctionner comme auparavant (redimensionnable, scrollable, sans returns inutiles dans la sortie, et aucune sortie ne disparaît mystérieusement), donc PROMPT_COMMAND='echo;echo;...' ou similaire n'est pas une option. Idéalement, la solution ne devrait pas être spécifique à la coquille.

Edit: La solution actuelle , en travaillant dans des cas simples, a quelques problèmes:

  • C'est Bash spécifique . Une solution idéale devrait être portable vers d'autres coquilles.
  • Il échoue si d'autres process modifient PS1 . Un exemple est virtualenv, qui ajoute (virtualenv) au début de PS1 , qui disparaît alors toujours juste au-dessus du pli.
  • Ctrll supprime maintenant la dernière page de l'historique.

Y at-il un moyen d'éviter ces problèmes, à less de forcer XTerm?

Si vous utilisez bash , ce qui suit devrait faire l'affaire:

 TOLASTLINE=$(tput cup "$LINES") PS1="\[$TOLASTLINE\]$PS1" 

Ou (less efficace car il exécute une command tput avant chaque invite, mais fonctionne après la redimensionnement de la window du terminal):

 PS1='\[$(tput cup "$LINES")\]'$PS1 

Pour empêcher tput de modifier le code de sortie, vous pouvez explicitement le sauvegarder et le réinitialiser:

 PS1='\[$(retval=$?;tput cup "$LINES";exit $retval)\]'$PS1 

Notez que la variable retval est locale; cela n'affecte aucune variable de retval vous auriez pu définir autrement dans le shell.

Étant donné que la plupart des terminaux sont en mesure d' cup capacité \e[y;xH , vous pouvez aussi le coder en dur:

 PS1='\[\e[$LINES;1H\]'$PS1 

Si vous voulez qu'il soit sécurisé contre la réinitialisation ultérieure de PS1, vous pouvez également utiliser la variable PROMPT_COMMAND . S'il est défini, il est exécuté en tant que command avant que l'invite ne soit sortie. Donc, l'effet peut également être réalisé par

 PROMPT_COMMAND='(retval=$?;tput cup "$LINES";exit $retval)' 

Bien sûr, tout en réinitialisant PS1 n'affectera pas cela, certains autres logiciels peuvent également changer PROMPT_COMMAND .

Comme une légère simplification à la réponse précédente, j'ai trouvé plus facile de courir:

 tput cup $LINES 

au début de .bashrc ou .zshrc . C'est juste le travail.

Avantages:

  • il n'imprime qu'une seule fois, lorsque vous démarrez votre shell

Les inconvénients:

  • lors de l'effacement de l'écran avec ^ L, il ne s'imprime pas et alias clear pour clear; tput ... clear; tput ... n'aide pas;
  • l'invite se déplace ailleurs lorsque le terminal est redimensionné

Les réponses utilisant $LINES sont inutilement non-portables. Comme pour le resize , vous pouvez simplement requestr à xterm de définir la position sur un numéro de ligne arbitrairement grand, par exemple,

 tput cup 9999 0 

(en supposant que vous avez une window inférieure à 10 mille lignes, sans tenir count du scrollback ).

Comme la string ne changera pas en tant qu'effet secondaire du redimensionnement de la window, vous pouvez la calculer une fois et la coller dans votre string d'invite comme une constante, par exemple,

 TPUT_END=$(tput cup 9999 0) 

et ensuite

 PS1="${TPUT_END} myprompt: " 

selon vos preferences.

Comme pour les autres process modifiant PS1 : vous devrez recomstackr PS1 après ces changements, pour vous assurer qu'il ressemble à ce que vous voulez. Mais il n'y a pas assez de détails dans la question pour indiquer apporter les changements.

Et enfin: le comportement de tabulation-complétion ne correspond pas à ce genre de changement, dû aux hypothèses de bash.