使用tmux进行Bash脚本以启动4-paned窗口

时间:2011-03-27 04:42:30

标签: bash exec tmux

有人可以帮助解释tmuxbashexec的情况吗?我正在尝试使用4窗格窗口设置tmux会话。理想情况下,我想在3个窗格中运行命令:例如一个Ruby Thin服务器和几个Ruby守护进程。这就是我到目前为止所做的:

~/.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

一切正常......但是当我在运行瘦服务器的第一个窗格中ctlr-c时,它会停止瘦服务器并返回到shell。但是,该命令不在历史中;即如果我按下向上键我没有得到bundle exec thin start命令......我从我的bash历史中得到了一些其他命令。我想知道是否有任何方法可以安排这些脚本,以便我在bash历史记录中获取命令。

另外......我尝试了execexec $SHELL -s ...exec $SHELL -s ... -I的多种组合,我不太确定发生了什么......

有人可以帮助解释tmux以及bashexec在这里发生了什么的一般概念吗?

4 个答案:

答案 0 :(得分:57)

正如其他人所提到的,在启动$SHELL之前,您的命令由shell脚本运行; $SHELL的实例没有一般的方法可以在启动之前知道其父运行的内容。

要将“初始命令”放入shell历史记录中,您需要将命令键击直接提供给$SHELL本身的实例(当然,在它启动之后)。在其他情况下,我可能建议使用一个小的Expect程序来生成$SHELL的实例,将其提供给击键,然后使用interact将tty绑定到 expect -spawned $SHELL

但是在 tmux 的上下文中,我们可以使用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

答案 1 :(得分:14)

tmuxinator允许您使用一个漂亮的yaml文件指定它。对于您的情况,您可以:

# ~/.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

你当然可以有额外的窗户等。

答案 2 :(得分:3)

您正在运行该命令,然后进入交互式shell;从脚本运行的命令(不在交互式shell中)不会记录在历史记录中。你真的想要一种方法来填充(这是一个技术术语:)曾经是TIOCSTI的“终端ioctl():东西输入”)shell输入窗口。

使用tmux,看起来您使用缓冲区。 (未经测试的)

的东西
#! /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}

答案 3 :(得分:0)

将以下内容放入命令提示符(全部作为一行),它将自动打开4个tmux面板(我知道这不是问题,但这看起来比我看到的要容易一些):

    tmux new-session \; \split-window -v \; \split-window -h \; \select-pane -t 0 \; \split-window -h

现在,您可以使用该命令并将其与您喜欢的任何脚本语言一起使用[如果使用perl以及其他语言,则需要将转义字符{反斜杠字符}加倍。

这将在较新的tmux面板中运行后续命令,还原为第一个命令并在末尾将其分割。