使用 tmux 启动4窗格窗口的 Bash 脚本

有人能解释一下 tmuxbashexec是怎么回事吗?我正在尝试建立一个四窗格窗口的 Tmux 会话。理想情况下,我想在3个窗格中运行一个命令: 比如一个 Ruby 瘦服务器和几个 Ruby 守护进程。以下是我目前掌握的情况:

返回文章页面

#!/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。但是,这个命令不在历史记录中; 也就是说,如果我按了 up 键,就不会得到 bundle exec thin start命令... ... 我会从 bash 历史记录中得到一些其他的命令。我想知道是否有办法安排这些脚本,以便在 bash 历史记录中获取命令。

还有... 我试过很多 execexec $SHELL -s ...exec $SHELL -s ... -I的组合,我不太清楚是怎么回事..。

有没有人能帮忙解释一下 tmuxbashexec到底是怎么回事?

81284 次浏览

您正在运行该命令,然后进入交互式 shell; 从脚本运行的命令(不在交互式 shell 中)不会被记录在历史记录中。你真的需要一种方法来填充(这是一个技术术语:)很久以前,它是 TIOCSTI的“终端 ioctl () : stuff input”)输入,用于将 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}

正如其他人所提到的,您的命令是由启动 $SHELL的 shell 脚本 之前运行的; 在启动 $SHELL之前,$SHELL实例不可能知道它的父实例运行了什么。

要将“初始命令”放入 shell 历史记录中,您需要将命令击键直接提供给 $SHELL本身的实例(当然是在启动之后)。在其他上下文中,我可能建议使用一个小的 Expect 程序生成一个 $SHELL实例,向它提供击键,然后使用 interact将 tty 绑定到由 期待生成的 $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

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

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

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

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

现在你可以使用这个命令和任何你喜欢的脚本语言一起使用[如果使用 perl... 或者其他语言,你需要将转义字符{反斜杠字符}加倍]。

这将在较新的 tmux 面板中运行后续命令,恢复到第一个面板,并在结束时分割它。