web-dev-qa-db-fra.com

Titre du volet dans Tmux

Sur ma machine locale, 3 instances de node.js s'exécutent simultanément. Chacun a son propre volet dans une fenêtre tmux appelée "serveurs". Le problème est qu'il n'est pas facile de savoir quel nœud est en cours d'exécution dans quel volet, car leurs journaux sont similaires.

Ce dont j'ai besoin, c'est un titre pour chaque volet. Comme je l’ai compris, tmux n’a pas cette fonctionnalité: il contient uniquement des titres pour les fenêtres et non pour les volets. Lancer une session tmux distincte dans chaque volet pour chaque instance de node.js ressemble à une overkill.

Alors, y a-t-il un petit programme qui lance une commande, enveloppant sa sortie avec une barre d'état spécifiée?

Merci d'avance

73
Andrey Lushnikov

tmux prend en charge les titres par volet, mais il ne fournit pas d'emplacement par volet pour afficher ces titres.

Vous pouvez définir le titre d’un volet avec la séquence d’échappement ESC ]2; … ESC \ _ (voir par exemple la section intitulée Noms et titres dans la page de manuel tmux). Vous pouvez faire ceci depuis le shell comme ceci:

printf '\033]2;%s\033\\' 'title goes here'

Le titre de chaque volet correspond par défaut au nom d’hôte du système. Par défaut, le titre du volet actif s’affiche à droite de la ligne d’état tmux (valeur globale par défaut de la variable de session status-right est "#22T" %H:%M %d-%b-%y, qui présente 22 caractères du titre du volet, de l’heure et de la date).

Donc, tant que vous êtes satisfait de pouvoir voir le titre du volet actif (par exemple, vous êtes prêt à changer de volet pour voir le titre d’un volet inactif), vous pouvez vous débrouiller avec la fonctionnalité par défaut. Envoyez simplement la séquence d'échappement de définition de titre appropriée avant de lancer la commande principale pour chaque volet.


Si vous avez absolument besoin d'une ligne dédiée pour afficher certaines informations par volet, les sessions = tmux imbriquées peuvent ne pas être aussi inutiles que vous ne le pensez.

Dans le cas général, pour fournir une ligne d'état inviolée sur un terminal donné, vous aurez besoin d'un (ré) émulateur de terminal complet situé entre le terminal d'origine et un nouveau terminal (un avec un moins de lignes). Une telle (ré) émulation est nécessaire pour traduire les séquences de contrôle envoyées au terminal interne et les traduire pour le terminal d'origine. Par exemple, pour conserver une ligne d’état au bas du terminal externe, la commande

Aller à la dernière ligne.

envoyé au terminal interne doit être devenir

Passer à l'avant dernière ligne.

lorsqu’il est traduit et envoyé au terminal externe. De même, un LF envoyé au terminal interne doit devenir

Si le curseur se trouve sur l'avant-dernière ligne, faites défiler cette ligne et toutes les lignes supérieures au-dessus d'une ligne, pour obtenir une avant-dernière ligne claire (protégeant la ligne d'état sur la dernière ligne). Sinon, envoyez un LF.

dans le terminal externe.

Des programmes comme tmux et screen ne sont que des réémulateurs de terminaux. Bien sûr, il existe de nombreuses autres fonctionnalités entourant l'émulateur de terminal, mais vous auriez besoin d'une grande partie du code d'émulation de terminal uniquement pour fournir une ligne d'état fiable.


Il existe cependant une solution légère, dans la mesure où

  1. vos programmes (Node.js instances) ont des interactions de terminal limitées avec les volets dans lesquels ils s'exécutent (c'est-à-dire, aucun positionnement du curseur), et
  2. vous ne redimensionnez pas les volets lorsque vos programmes sont en cours d'exécution.

Comme beaucoup d'émulateurs de terminaux, tmux prend en charge une commande de contrôle de terminal "définir la région de défilement" dans ses volets. Vous pouvez utiliser cette commande pour limiter la zone de défilement au haut (ou au bas) N-1 lignes du terminal et écrire un type de texte d'identification d'instance dans la ligne sans défilement.

Les restrictions (aucune commande de déplacement de curseur autorisée, aucun redimensionnement) sont requises car le programme qui génère la sortie (par exemple, une instance Node.js) n'a aucune idée du fait que le défilement a été limité à une région particulière. Si le programme générateur de sortie déplaçait le curseur en dehors de la zone de défilement, la sortie risque alors d'être tronquée. De même, l'émulateur de terminal réinitialise probablement automatiquement la zone de défilement lorsque le terminal est redimensionné (la "ligne non défilante" finira donc probablement par disparaître).

J'ai écrit un script qui utilise tput pour générer les séquences de contrôle appropriées, écrire dans la ligne sans défilement et exécuter un programme après avoir déplacé le curseur dans la zone de défilement:

#!/bin/sh

# usage: no_scroll_line top|bottom 'non-scrolling line content' command to run with args
#
#     Set up a non-scrolling line at the top (or the bottom) of the
#     terminal, write the given text into it, then (in the scrolling
#     region) run the given command with its arguments. When the
#     command has finished, pause with a Prompt and reset the
#     scrolling region.

get_size() {
    set -- $(stty size)
    LINES=$1
    COLUMNS=$2
}
set_nonscrolling_line() {
    get_size
    case "$1" in
        t|to|top)
            non_scroll_line=0
            first_scrolling_line=1
            scroll_region="1 $(($LINES - 1))"
            ;;
        b|bo|bot|bott|botto|bottom)
            first_scrolling_line=0
            scroll_region="0 $(($LINES - 2))"
            non_scroll_line="$(($LINES - 1))"
            ;;
        *)
            echo 'error: first argument must be "top" or "bottom"'
            exit 1
            ;;
    esac
    clear
    tput csr $scroll_region
    tput cup "$non_scroll_line" 0
    printf %s "$2"
    tput cup "$first_scrolling_line" 0
}
reset_scrolling() {
    get_size
    clear
    tput csr 0 $(($LINES - 1))
}

# Set up the scrolling region and write into the non-scrolling line
set_nonscrolling_line "$1" "$2"
shift 2

# Run something that writes into the scolling region
"$@"
ec=$?

# Reset the scrolling region
printf %s 'Press ENTER to reset scrolling (will clear screen)'
read a_line
reset_scrolling

exit "$ec"

Vous pourriez l'utiliser comme ceci:

tmux split-window '/path/to/no_scroll_line bottom "Node instance foo" node foo.js'
tmux split-window '/path/to/no_scroll_line bottom "Node instance bar" node bar.js'
tmux split-window '/path/to/no_scroll_line bottom "Node instance quux" node quux.js'

Le script devrait également fonctionner en dehors de tmux tant que le terminal prend en charge et publie ses capacités csr et cup terminfo.

75
Chris Johnsen

Cette fonctionnalité a été ajoutée à tmux git dans this commit . Ce n'est pas dans la version 2.2, mais il semble que ce sera dans la version 2.3.

Pour l'activer:

tmux set -g pane-border-status top

ou si vous préférez:

tmux set -g pane-border-status bottom

Pour définir un texte personnalisé comme ligne d'état de la bordure du volet, vous pouvez utiliser pane-border-format, par exemple. ainsi:

tmux set -g pane-border-format "#{pane_index} #{pane_current_command}"
60
kevmitch

Je travaille sur la barre d'état du volet pour tmux-ticket. Ma branche de développement peut être trouvée ici sur github: https://github.com/jonathanslenders/tmux

À l'heure actuelle, cela ajoute déjà une commande de travail de renommer le volet "titre" . Il y a encore des bugs et l'API va s'améliorer. L'idée est de créer une barre d'état par volet, pouvant avoir un formatage similaire à la barre d'état de la session. Comme le reste de tmux, tout devrait devenir scriptable et personnalisable. Une fois terminé et stable, il sera probablement inclus dans le tux officiel.

14
Jonathan Slenders

J'utilise tmux version 2.3, je pense que le style de bordure n'est pas pris en charge dans les versions précédentes. C'est ce qui a fonctionné pour moi:

Pour chaque volet, définissez le titre:

printf '\033]2;My Pane Title\033\\'

Ensuite:

tmux set -g pane-border-format "#{pane_index} #T"
12
OriG

Un gif vaut mille mots. ( source )

tmux-xpanes est un diviseur de terminal basé sur tmux, qui prend en charge l’affichage du titre de chaque volet via le -t option.

9
navigaid

Puisque tmux 2.6 tu peux faire:

$ tmux select-pane -t {pane} -T {title}

# Examples:
$ tmux select-pane -T title1          # Change title of current pane
$ tmux select-pane -t 1 -T title2     # Change title of pane 1 in current window
$ tmux select-pane -t 2.1 -T title3   # Change title of pane 1 in window 2

Vous pouvez voir le titre par volet dans une barre d'état avec:

$ tmux set pane-border-status bottom      # For current window
$ tmux set -g pane-border-status bottom   # For all windows

Désactiver la barre d'état avec:

$ tmux set pane-border-status off       # For current window
$ tmux set -g pane-border-status off    # For all windows
9
Eyal Levin

Oui, il existe une telle commande: tmux. Donnez à votre session un nom et il sera affiché dans une barre d'état interne:

TMUX=0 tmux new-session -s my-new-session
6
event_jr

Cela n'est pas utile à court terme, mais il existe une demande de fonctionnalité pour les titres par volet dans tmux: http://sourceforge.net/tracker/?func=detail&aid=3495916&group_id=200378&atid=973265#

En attendant, comme d'autres l'ont mentionné, imbriquer tmux fonctionne correctement.

4
Newtonx