Question

Quelqu'un peut-il m'aider à expliquer ce qui se passe tmux, bash, et exec?J'essaie de configurer une session tmux avec une fenêtre à 4 volets.Idéalement, je souhaite exécuter une commande dans 3 des volets :par exemple.un serveur Ruby Thin et quelques démons Ruby.Voici ce que j'ai jusqu'à présent :

~/.bin/tmux-foo:

#!/bin/sh

tmux new-session -d -s foo 'exec pfoo "bundle exec thin start"'
tmux rename-window 'Foo'
tmux select-window -t foo:0
tmux split-window -h 'exec pfoo "bundle exec compass watch"'
tmux split-window -v -t 0 'exec pfoo "rake ts:start"'
tmux split-window -v -t 1 'exec pfoo'
tmux -2 attach-session -t foo

~/.bin/pfoo:

#!/bin/bash
cd ~/projects/foo
rvm use ree

# here I want to execute command1 2 3 or 4...

exec $SHELL

Tout fonctionne...mais quand je ctlr-c dans le premier volet qui exécute le serveur léger, il arrête le serveur léger et revient au shell.Cependant, la commande n’est pas dans l’histoire ;c'est à dire.si j'appuie sur la touche haut, je n'obtiens pas le bundle exec thin start commande...Je reçois une autre commande de mon historique bash.Je me demande s'il existe un moyen d'organiser ces scripts afin que j'obtienne les commandes dans l'historique bash.

Aussi...J'ai essayé de nombreuses combinaisons de exec, exec $SHELL -s ..., et exec $SHELL -s ... -I et je ne suis pas sûr de ce qui se passe...

Quelqu'un peut-il m'aider à expliquer l'idée générale de ce qui se passe tmux et bash et exec ici?

Était-ce utile?

La solution

Comme d'autres l'ont mentionné, vos commandes sont exécutées par le script shell avant lancer votre $SHELL;il n'y a pas de méthode générale pour l'exemple de $SHELL peut savoir ce que son parent a exécuté avant de le démarrer.

Pour obtenir la "commande initiale" dans l'historique du shell, vous devez transmettre les frappes de commande directement à l'instance de $SHELL lui-même (après son démarrage, bien sûr).Dans d'autres contextes, je pourrais suggérer d'utiliser un petit programme Expect pour générer une instance de $SHELL, donnez-lui les frappes au clavier, puis utilisez interact attacher le terminal au attendre-généré $SHELL.

Mais dans le contexte de tmux, nous pouvons simplement utiliser send-keys:

#!/bin/sh

tmux new-session -d -s foo 'exec pfoo'
tmux send-keys 'bundle exec thin start' 'C-m'
tmux rename-window 'Foo'
tmux select-window -t foo:0
tmux split-window -h 'exec pfoo'
tmux send-keys 'bundle exec compass watch' 'C-m'
tmux split-window -v -t 0 'exec pfoo'
tmux send-keys 'rake ts:start' 'C-m'
tmux split-window -v -t 1 'exec pfoo'
tmux -2 attach-session -t foo

Autres conseils

tmuxinateur vous permet de spécifier cela avec un joli fichier yaml.Pour votre cas, vous pourriez avoir :

# ~/.tmuxinator/foo.yml
# you can make as many tabs as you wish...

project_name: foo
project_root: ~/projects/foo
rvm: ree
tabs:
  - main:
      layout: tiled
      panes:
        - bundle exec thin start
        - bundle exec compass watch
        - #empty, will just run plain bash
        - rake ts:start

Vous pouvez bien sûr avoir des fenêtres supplémentaires, etc.

Vous exécutez la commande, puis entrez dans le shell interactif ;la commande exécutée à partir du script, n'étant pas dans un shell interactif, n'est pas enregistrée dans l'historique.Vous voulez vraiment un moyen de faire des trucs (c'est un terme technique :) il était une fois TIOCSTI pour "terminal ioctl() :stuff input") entrée pour le shell dans la fenêtre.

Avec tmux, il semble que vous utilisiez des tampons pour cela.Quelque chose du genre (non testé)

#! /bin/bash
cd ~/projects/foo
rvm use ree

if [[ $# != 0 ]]; then
  tmux set-buffer "$(printf '%s\n' "$*")" \; paste-buffer -d
fi

exec ${SHELL:-/bin/sh}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top