我正在尝试编写一个执行以下操作的 bash 脚本:
- 打开 8 个 tmux 终端
- 每个终端都通过 ssh 连接到远程服务器
- 在 3 台服务器上启动脚本 X,完成后
- 在 3 个不同的服务器中启动另一个脚本 Y
操作(尤其是最后两个)必须按照这个精确的顺序执行。我设法创建了所有 tmux 终端,但我发现由于某些原因,tmux 执行命令的速度非常快,以至于它不会等待命令完成。
例如,只写:
tmux send-keys -t 0 "ls"
脚本中并不总是生成主文件夹中包含的文件的完整列表。
不同服务器上的两个脚本也会发生同样的情况,有时会在 X 之前执行 Y。
这是我的脚本:
######################################
# Setup tmux
######################################
tmux new-session -d -s sss
tmux new-window -t sss
for (( i = 0; i < 3; i++ )); do
tmux split
tmux select-layout even-vertical
done
for (( i = 0; i < 8; i=i+2 )); do
tmux select-pane -t $i
tmux split-window -h
done
######################################
######################################
# Ssh Connection
######################################
for (( i = 0; i < 8; i++ )); do
tmux send-keys -t $i "$connection ${port[$i]}" C-m
done
######################################
for (( i = 0; i < 3; i++ )); do
tmux send-keys -t $i "cd scripts" C-m
tmux send-keys -t $i "./X.sh" C-m
done
for (( i = 3; i < 6; i++ )); do
tmux send-keys -t $i "cd scripts" C-m
tmux send-keys -t $i "./Y.sh ${servers_ips[${i}-3]}" C-m
done
更新
另外,我如何在同一个 tmux 窗格中等待命令完成?比如在长命令运行后才执行其他操作
先感谢您。
答案1
如果您确实需要使用 tmux,并且您的命令不是交互式的,那么您可以在第一个命令中添加第二个命令,以某种方式发出信号,表示第一个命令已完成。使用内置 tmux 命令执行此操作的一种简单方法是使用锁定和解锁wait-for
选项。您可以拥有许多任意频道。当您锁定频道时,进一步的锁定尝试将被阻止,直到解锁。-L channel
-U channel
以下是一个例子:
tmux wait-for -L my1\; \
send-keys 'sleep 5' Enter 'tmux wait-for -U my1' Enter\; \
wait-for -L my1
这将锁定通道my1
,将命令发送sleep 5
到 shell,然后立即发送tmux wait-for
解锁 shell 命令,然后尝试再次获取锁,因此它会阻塞。
5秒后,睡眠结束,shell执行tmux unlock,现在可以获取锁,然后上面的tmux命令才会返回。
为了恢复正常,wait-for -U
现在应该采取行动,或许可以通过发出send-keys ... wait-for -U ...
如上所述的另一个组合命令。