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

使用tmux启动4窗格窗口的Bash脚本,bash,exec,tmux,Bash,Exec,Tmux,有人能解释一下tmux、bash和exec的情况吗?我正在尝试使用4窗格窗口设置tmux会话。理想情况下,我希望在3个窗格中运行一个命令:例如,一个Ruby瘦服务器和两个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

有人能解释一下
tmux
bash
exec
的情况吗?我正在尝试使用4窗格窗口设置tmux会话。理想情况下,我希望在3个窗格中运行一个命令:例如,一个Ruby瘦服务器和两个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/bash
cd ~/projects/foo
rvm use ree

# here I want to execute command1 2 3 or 4...

exec $SHELL
~/.bin/pfoo

#!/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/bash
cd ~/projects/foo
rvm use ree

# here I want to execute command1 2 3 or 4...

exec $SHELL
一切都很好。。。但是,当运行精简服务器的第一个窗格中出现I
ctlr-c
时,它会停止精简服务器并返回shell。然而,这一命令并没有出现在历史上;i、 e.如果我按向上键,我将无法获得
bundle exec thin start
命令。。。我从bash历史记录中获得了一些其他命令。我想知道是否有办法安排这些脚本,以便在bash历史记录中获得命令

还有。。。我尝试了多种组合,包括
exec
exec$SHELL-s…
,和
exec$SHELL-s-我
不太清楚发生了什么事


有人能在这里解释一下
tmux
bash
exec
的大致情况吗?

您正在运行命令,然后进入交互式shell;从脚本运行的命令不在交互式shell中,不会记录在历史记录中。你真的需要一种方法来填充(这是一个技术术语:)很久以前,shell的“terminal ioctl():stuff input”(终端ioctl():stuff input))输入是
TIOCSTI

对于
tmux
,您似乎使用了缓冲区来实现这一点。类似于(未经测试的)的东西


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

要将“初始命令”放入shell历史记录中,您需要将命令击键直接输入到
$shell
本身的实例中(当然,在启动之后)。在其他上下文中,我可能建议使用一个小的Expect程序生成
$SHELL
的实例,为其输入击键,然后使用
交互
将tty绑定到Expect生成的
$SHELL

但是在tmux的上下文中,我们可以只使用
发送键

#!/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
允许您使用一个漂亮的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面板(我知道这不是问题所在,但这看起来比我所看到的要简单一些):

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


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

Hmm。。。这不太管用,但我明白你的意思。我会试着玩弄这个主意。非常感谢。在(较新的?)ksh中,有一个环境变量设置,它是HIST*变量之一,如果设置正确,它会将从.profile文件执行的别名和函数定义捕获到当前(非交互式)shell的历史记录中。由于新的ksh和bash都兼容Posix,所以bash很可能也能做到这一点。(很抱歉,这是一个很长的故事,关于为什么我不能挖掘出并给出关于如何执行此操作的确切语法;-()作为记录,我现在使用(而不是tmuxinator,它具有非shell依赖项)。如果tmux是后端,这也将通过Byobu工作。请问,
'exec pfoo'
应该做什么?我尝试在我的实例上运行该行,但它没有创建会话(它似乎在尝试创建会话后立即退出,然后添加了一些字符)。不知道它是否与我的PuTTy设置有关。
'exec pfoo'
是您实际要执行的任何命令的占位符。
'exec pfoo'
正在执行一个
pfoo
脚本,保存在一个
$PATH
目录中。很高兴了解tmuxinator,谢谢!