我想创建一个名为“-”的会话,general
并且希望其中有两个窗口-
- WIN1 系统
- WIN2 的
我需要在 win1 中运行 script1,在 win2 中运行 script2
目前我已经写了如下脚本-
SESSION="general"
echo $SESSION
tmux attach-session -d -t $SESSION || tmux new-session -s $SESSION -n win1 -c /my/path/ ./script1.sh
tmux new-window -n win2 tel_csr
使用此脚本,我可以创建名为 的会话general
。但只有一个窗口显示名称win1
并运行脚本 - script1.sh
。
第二条语句没有起作用。上面的脚本有什么问题。
注意:script1.sh
触发服务器程序,所以我猜它不会返回。
答案1
分析
上述脚本有什么问题?
运行sleep 5; echo done
。 您是否感到惊讶,echo
只有在退出后才有效sleep
? shell 按顺序运行这两个命令,而不是并行运行。
现在运行less /etc/fstab; echo done
。done
退出后你才会看到less
(使用Q)。
tmux new-session; tmux new-window
也没什么不同。
在你的脚本中tmux attach-session
或tmux new-session
附件到会话。其中一个tmux
命令将成为 tmux 客户端,并一直运行,直到您断开连接。脚本等待此命令tmux
退出后再执行下一个命令。在断开连接之前,您无法看到效果,tmux new-window
因为此命令尚未执行。
如果您断开连接,则脚本将继续运行。在不破坏会话的情况下执行此操作,然后再次连接,您将看到新窗口。
解决方案
一切设置完毕后进行连接。
使用不附加到会话的命令设置所有内容(例如tmux new-session -d
)。如果您最终想要附加,那么tmux attach-session
应该是最后的脚本中的命令(除非你故意地分离后,您可能想执行一些额外的操作)。此示例(在 tmux 之外运行)将附加到已存在附加窗口的会话:
tmux new-session -d
tmux new-window
tmux attach-session
一般来说,您想要命名并定位精确的会话、窗口等。并且您想要一些逻辑来处理命名会话存在的情况等。
选择
另一种方法是从异步运行的子 shell 调用一些“维护”命令,并从主 shell 提前附加,而“维护”部分仍并行运行。示例(在 tmux 之外运行):
(tmux new-session -d; sleep 5; tmux new-window) & sleep 2; tmux attach-session
sleep 5
模拟需要时间的命令。使用以前的解决方案,您必须等到所有命令完成。在这里,您不必等待那么长时间,您可以在tmux new-window
运行之前附加。这样,您实际上可以看到 tmux 中弹出一个新窗口。
但这种方法有严重的缺点:
- 您可以在一切设置完成之前与 tmux 进行交互。通过更改当前窗格(或窗口等)或销毁某个窗格(或窗口等),您可能会导致“维护”命令针对错误的窗格(或窗口等)或失败;除非它们经过精心设计以处理这种情况。
- 竞争条件。在上面的例子中,
sleep 2
延迟attach-session
,因此希望它在 之后运行new-session
。即使有sleep 2
(或即使有sleep 2000
),也不能保证new-session
先运行,只有很高的概率。有 来tmux wait-for
处理这种情况(但正确使用它可能很棘手;请参阅“处理竞争条件”这是我的另一个答案)。