81 votes

Exécutez ou envoyez une commande à une fenêtre tmux dans une session tmux en cours d'exécution

Je veux écrire un script shell qui va se connecter à une session tmux nommée, sélectionner une fenêtre (ou volet) dans cette session et exécuter une commande dans cette fenêtre (ou volet) sélectionné.

Comment puis-je faire cela à partir d'un script bash?

Je sais

tmux new-window -n:mywindow 'exec something'

me permet d'envoyer des commandes à une fenêtre fraîchement créée, mais j'ai besoin de quelque chose comme

tmux select-window -t:0 'my command'

Je suppose que je pourrais utiliser send-keys mais il semble qu'il devrait y avoir quelque chose qui prend une commande ou une liste de commandes à exécuter.

113voto

Chris Johnsen Points 36743

Chaque tmux panneau est une interface pour un seul pty (pseudo tty). Les fenêtres non divisées ont un seul panneau; les fenêtres divisées ont plusieurs panneaux.

tmux ne fournit pas de moyen d'ajouter des processus supplémentaires à un panneau une fois qu'il a été démarré avec sa commande initiale. C'est au processus de cette commande initiale (généralement un shell) de fournir le contrôle des tâches1 pour ce terminal.

Si vous voulez écraser ce qui est actuellement en cours d'exécution dans le panneau, vous pouvez utiliser respawn-pane -k pour tuer la commande existante et la remplacer par une nouvelle (par exemple, respawn-pane -t sessionname:0.4 -k 'some -new command').

Mais, si vous voulez maintenir ce qui est actuellement en cours d'exécution dans le panneau, alors il n'y a peut-être pas de meilleure option que de simplement "taper dessus" avec send-keys.

Vous pouvez écrire un script comme ceci (attachez le dernier, car sinon le script attendra simplement que vous vous détachiez avant de continuer):

session=whatever
window=${session}:0
pane=${window}.4
tmux send-keys -t "$pane" C-z 'some -new command' Enter
tmux select-pane -t "$pane"
tmux select-window -t "$window"
tmux attach-session -t "$session"

Notez que, sur la commande send-keys, vous devriez réellement taper les lettres E n t e r, pour dire à tmux d'envoyer une touche de retour à la fenêtre.  (Bien sûr, chaque commande se termine par la touche Enter.)


1Le contrôle des tâches est l'arbitrage entre plusieurs groupes de processus d'une session unique qui utilise le tty comme terminal de contrôle. C'est-à-dire, la touche de suspension Ctrl+Z, et les commandes shell jobs, fg, et bg.

3 votes

Merci pour ça! J'ai mis #{session_name}: #{window_index}. #{pane_index} dans ma ligne d'état afin de pouvoir rapidement voir à quelle fenêtre envoyer les commandes.

0 votes

C'est bien de prévenir la fermeture de la fenêtre lorsque la commande se termine.

21voto

Zeynel Points 2255

Vous pouvez utiliser C-m plutôt que Enter. C'est la même chose. De plus, tmux facilite l'envoi à la bonne / mauvaise fenêtre en utilisant -t right ou -t left. Et si vous voulez cibler une fenêtre dans une autre fenêtre, il suffit de la préfixer par le numéro de la fenêtre suivi d'un point, comme -t 0.right.

Maintenant vous pouvez écrire une simple fonction Bash pour obtenir la séquence de touches comme argument et l'envoyer facilement vers la fenêtre cible.

0 votes

Vous pouvez également utiliser sélectionner-pane -t {last} pour la dernière (précédente) fenêtre active.

1voto

wattahay Points 111

Ajouter des commandes à une file d'attente de fichiers texte simple :

Ceci est seulement un dernier recours, si vous voulez vraiment exécuter la commande après la dernière sans l'arrêter.

Exemple

  1. Écrivez un script bash qui prend une [commande CLI] et un [nom de fenêtre tmux] en tant que variables
  2. Le script ajoute la commande à un fichier de file d'attente qu'il intitule pour correspondre uniquement à cette fenêtre
  3. Cependant, la première ligne du fichier de file d'attente est simplement un 0 ou 1
  4. Le script boucle à travers une tentative simple de changer le 0 en 1 via une commande send-keys tmux à la fenêtre tmux correspondante. (S'il y a une commande en cours d'exécution dans la fenêtre, la commande send-keys ne fait évidemment rien. Sinon, elle change le 0 en 1.)
  5. Dans la même boucle, le script tente ensuite de détecter un 1 dans le fichier de file d'attente.
  6. Lorsque le script détecte que le 0 est un 1, il exécute la prochaine commande dans la file d'attente, et la supprime du fichier. Il rechange le 1 en un 0.

Pour stocker des commandes, vous pourriez également utiliser un "tableau associatif"

Le script cesse de boucler lorsque le tableau est vide.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X