Quelqu'un peut-il aider à expliquer ce qui se passe avec tmux
, bash
et exec
? J'essaie de configurer une session tmux avec une fenêtre à 4 volets. Idéalement, je veux exécuter une commande dans 3 des volets: par ex. un Ruby serveur mince et quelques Ruby démons. C'est 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 que si j'appuie sur la touche haut, je n'obtiens pas le bundle exec thin start
commande ... J'obtiens une autre commande de mon historique bash. Je me demande s'il y a un moyen d'arranger ces scripts pour 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 sais pas trop ce qui se passe ...
Quelqu'un peut-il aider à expliquer ici l'idée générale de ce qui se passe avec tmux
et bash
et exec
?
Comme d'autres l'ont mentionné, vos commandes sont exécutées par le script Shell avant lancement de votre $Shell
; il n'y a pas de manière générale l'instance 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 envoyer 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 touches, puis utilisez interact
pour lier le tty au attendez - engendré $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
tmuxinator vous permet de spécifier cela avec un fichier Nice 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 bourrer (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 comme (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}