bash - create - tmux quick start
Scripts Bash con tmux para iniciar una ventana de 4 panes (3)
¿Alguien puede ayudarme a explicar qué está pasando con tmux
, bash
y exec
? Estoy tratando de configurar una sesión de tmux con una ventana de 4 paneles. Idealmente, quiero ejecutar un comando en 3 de los paneles: por ejemplo, un servidor Ruby Thin y un par de daemons Ruby. Esto es lo que tengo hasta ahora:
~/.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
Todo funciona ... pero cuando ctlr-c
en el primer panel que ejecuta el servidor delgado, detiene el servidor delgado y vuelve al shell. Sin embargo, el comando no está en la historia; es decir, si toco la tecla arriba no obtengo el comando bundle exec thin start
... obtengo otro comando de mi historial de bash. Me pregunto si hay alguna manera de organizar estos scripts para que obtenga los comandos en el historial de bash.
Además ... He intentado muchas combinaciones de exec
, exec $SHELL -s ...
, y exec $SHELL -s ... -I
y no estoy muy seguro de lo que está pasando ...
¿Puede alguien ayudar a explicar la idea general de lo que está pasando con tmux
y bash
y el exec
aquí?
Como otros han mencionado, tus comandos están siendo ejecutados por el script de shell antes de iniciar tu $SHELL
; no hay una forma general de que la instancia de $SHELL
pueda saber qué ejecutó su padre antes de iniciarlo.
Para obtener el "comando inicial" en el historial de shell, necesita alimentar las pulsaciones de teclado directamente a la instancia de $SHELL
(después de que se haya iniciado, por supuesto). En otros contextos, podría sugerir usar un pequeño programa Esperar para generar una instancia de $SHELL
, alimentarlo con las teclas, luego usar interact
para unir el tty con el esperado $SHELL
.
Pero en el contexto de tmux , podemos usar 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
Está ejecutando el comando y luego ingresando el shell interactivo; el comando ejecutado desde el script, que no está en un shell interactivo, no se registra en el historial. Realmente quieres una forma de rellenar (ese es un término técnico :) alguna vez fue TIOCSTI
para la entrada "terminal ioctl (): cosas ingresadas" para el shell en la ventana.
Con tmux
, parece que usa búferes para esto. Algo en la línea de (no probado)
#! /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}
tmuxinator te permite especificar esto con un buen archivo yaml. Para su caso, podría tener:
# ~/.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
Por supuesto, puede tener ventanas adicionales, etc.