74

任何人都可以帮助解释 , 和 的tmux情况bashexec?我正在尝试使用 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在运行瘦服务器的第一个窗格中时,它会停止瘦服务器并返回到外壳。但是,该命令不在历史记录中;即,如果我按向上键,我没有得到bundle exec thin start命令……我从我的 bash 历史记录中得到了一些其他命令。我想知道是否有任何方法可以安排这些脚本,以便我获得 bash 历史记录中的命令。

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

任何人都可以帮助解释这里发生的事情的总体思路tmux吗?bashexec

4

4 回答 4

71

正如其他人所提到的,在启动您的;之前,您的命令正在由 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
于 2011-10-11T02:43:49.313 回答
19

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

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

于 2012-04-18T20:01:19.630 回答
4

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

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

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

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

于 2020-10-31T22:21:21.080 回答
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}
于 2011-03-27T05:26:09.867 回答