有人可以帮助解释tmux
,bash
和exec
的情况吗?我正在尝试使用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历史记录中获取命令。
另外......我尝试了exec
,exec $SHELL -s ...
和exec $SHELL -s ... -I
的多种组合,我不太确定发生了什么......
有人可以帮助解释tmux
以及bash
和exec
在这里发生了什么的一般概念吗?
答案 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面板中运行后续命令,还原为第一个命令并在末尾将其分割。