带有 tmux 的 Bash 脚本以启动 4 窗格窗口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5447278/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 20:20:06  来源:igfitidea点击:

Bash scripts with tmux to launch a 4-paned window

bashexectmux

提问by Aaron Gibralter

Can anyone help explain what's going on with tmux, bash, and exec? I'm trying to set up a tmux session with a 4-pane window. Ideally, I want to run a command in 3 of the panes: e.g. a Ruby Thin server and a couple of Ruby daemons. This is what I have so far:

任何人的帮助能解释这是怎么回事用tmuxbashexec?我正在尝试使用 4 窗格窗口设置 tmux 会话。理想情况下,我想在 3 个窗格中运行一个命令:例如一个 Ruby 瘦服务器和几个 Ruby 守护进程。这是我到目前为止:

~/.bin/tmux-foo:

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

#!/bin/bash
cd ~/projects/foo
rvm use ree

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

exec $SHELL

It all works... but when I ctlr-cin the first pane that is running the thin server, it stops the thin server and returns to the shell. However, the command is not in the history; i.e. if I hit the up key I don't get the bundle exec thin startcommand... I get some other command from my bash history. I'm wondering if there's any way to arrange these scripts so that I get the commands in the bash history.

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

Also... I've tried many combinations of exec, exec $SHELL -s ..., and exec $SHELL -s ... -Iand I'm not quite sure what is going on...

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

Can anyone help explain the general idea of what is going on with tmuxand bashand exechere?

任何人的帮助能解释一下是怎么回事的总体思路tmux,并bashexec这里?

采纳答案by Chris Johnsen

As others have mentioned, your commands are being run by the shell script beforelaunching your $SHELL; there is no general way the instance of $SHELLcan know what its parent ran before starting it.

正如其他人所提到的,您的命令启动您的$SHELL;之前由 shell 脚本运行。$SHELL在启动它之前,没有通用的方法可以知道它的父级运行了什么。

To get the “initial command”?into the shell history, you need to feed the command keystrokes directly to the instance of $SHELLitself (after it has been started, of course). In other contexts I might suggest using a small Expect program to spawn an instance of $SHELL, feed it the keystrokes, then use interactto tie the tty to the expect-spawned $SHELL.

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

But in the context of tmux, we can just use send-keys:

但是在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

回答by Hamish Downer

tmuxinatorlets you specify this with a nice yaml file. For your case you could have:

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

You can of course have extra windows etc.

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

回答by geekosaur

You are running the command and then entering the interactive shell; the command run from the script, not being in an interactive shell, doesn't get recorded in the history. You really want a way to stuff (that's a technical term :) once upon a time it was TIOCSTIfor "terminal ioctl(): stuff input") input for the shell into the window.

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

With tmux, it looks like you use buffers for this. Something along the lines of (untested)

使用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}