这几乎是一个代码审查问题,但非常*nixy,更多的是关于配置而不是代码。自从我tmux
转而使用以来,多年来screen
我一直遇到一些棘手的问题,这些问题使我无法按照我想要的方式工作。由于我将 shell 设置为在 tmux 会话中执行,我最终决定是时候修复这个问题了。
默认情况下,当您将两个 tmux 客户端附加到同一会话时,它们会被锁定在一起。在其中一个窗格中切换,并且两个窗格同步切换。这与屏幕不同,屏幕的默认行为是一组共享的窗格,但客户端本身是独立的。
我想要的是一种解除绑定到同一会话的两个 tmux 客户端的方法。如果您在 tmux 之外并启动新客户端,那么这很容易做到。只需引用父会话即可开始一个新会话:
tmux new-session -t original_session -s new_session
不过尝试这样做后您位于客户端中,并且想要将其与共享该会话的任何其他客户端取消链接,事情会变得更加复杂。我尝试了几十种方法,但从未找到一种行之有效的方法。我得到的最接近的是使用bind <key> prompt-command ...
提示输入旧的和新的会话名称。无论出于何种原因, tmux 都不会扩展a或 的#{session_name}
参数内的变量。new-session
prompt-command
它在许多其他命令的参数中起作用(例如我在run
下面使用它),但如果没有这种扩展,这个特定的任务就会突然变得复杂。即使手动输入值,它也只能起到一定的作用。
今天我终于开始工作了。然而,结果比我想要的更丑陋。它需要一个 shell 函数来完成大部分的工作。为了将其包含在配置文件中而不涉及外部脚本(为了点文件的可移植性),我使用了一种 hack。如果去掉前两列,该配置实际上可以作为 shell 脚本执行。将所有内容都封装在函数中,您可以从任何键绑定中仅调用所需的脚本部分。 shell 脚本位是配置中的注释,而在 shell 脚本中,配置位会被此处文档丢弃。
今天的解决方案出来了这样的东西(我的完整.tmux.conf
文件):
# : << ENDOFCONF
# Clear the default binding
unbind C-c
# Pass the name of the current session to a function to clone it
bind C-c run "cut -c3- ~/.tmux.conf | sh -s clone #S"
# ENDOFCONF
# clone () {
# orig=${1%-*}
# copy="$orig-$(($( tmux list-sessions -F '#S' | sed -nE "/^${orig}-[0-9]+$/{s/[^0-9]//g;p}" | tail -n1 )+1))"
# TMUX= tmux new-session -d -t $orig -s $copy
# tmux switch-client -t $copy
# tmux set -q -t $copy destroy-unattached on
# }
# $@
请注意,这有效。从正在运行的 tmux 客户端,++Ctrl创建一个新会话,并在当前会话的名称后附加一个数字,使用当前会话作为窗格的目标,然后切换到它。B CtrlC
我对此很满意,除了一个挥之不去的想法:我刚刚把一些简单的事情变得比它需要的复杂得多。有没有更简单的方法来实现这一目标?
答案1
这就是我所做的:
alias ta='export NEW_SESSION=\$(uuidgen) ; tmux new-session -t 0 -s \$NEW_SESSION ; tmux kill-session -t \$NEW_SESSION'
其作用是从名为“0”的会话(如果未指定,第一个会话的名称)创建一个新会话,命名为唯一随机的内容(使用 uuidgen),然后在分离时杀死它。
请注意,我使用的是 zsh。 “ta”是“tmux Attach”的缩写