问题描述
在 shell 脚本中编写了含有 tmux
的指令,希望规定的指令能在独立的某个会话中运行,防止特殊任务阻塞脚本的运行。然而在脚本执行!到“开启 tmux 窗口”时,后续指令并不会按照原意灌入指定的窗格,而是弥散到原面板或 tmux 窗口中。
解决思路
已验证的不可靠思路
认为错误原因是窗口的创建“来不及加载”导致后续打算在该窗口中运行的指令乱飞,故使用 sleep
穿插在代码中尝试解决问题。实际上,这种思路是不可靠的,因为运行在脚本中的tmux命令会在指令尾默认加上一条“分离指令 (detach)”,这会导致 tmux 无法理解紧接着执行的原生 sh 脚本指令 (no client found
)[3,4]。换言之,tmux 不知道后续的指令是否需要在当前的窗口中运行,包括上文说到的 sleep
指令。
可靠的解决方案
引用tmux中的send
参数按照规定的写法指定会话,指定窗口(窗格)执行指定的命令实现“指哪打哪”。参考代码如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| # -*- coding: utf-8 -*-
# Time : 2021/8/5 23:40
# Author : QIN2DIM
# Github : https://github.com/QIN2DIM
# Description: Tmux 脚本编程
import os
def systemctl_create_v2raycs():
# 创建一个后台运行的名为v2raycs的session会话,其默认窗口名为system
# [-s sessionName] [-n windowName] [-d daemon]
os.system(f"tmux new -s v2raycs -n system -d")
# 水平切割 v2raycs:system 使窗口分为上下屏(窗格),光标随splicer切换至下分屏
# 使用标识符指定后台运行的操作目标 [-t targetPane]
# os.system(f"tmux split-window -t 'v2raycs:system'")
# 向指定会话的指定窗格发出指令
# 使用标识符指定后台运行的操作目标 [-t targetPane]
os.system(f"tmux send -t 'v2raycs:system' "
f"'cd /qinse/V2RaycSpider1325/;python main.py deploy' Enter")
def systemctl_create_bot():
os.system(f"tmux new -s bot -n core -d")
os.system(f"tmux new -s go-cqhttp -n core -d")
os.system(f"tmux send -t 'bot:core' "
f"'cd /qinse/cqbot/bbot;python bot.py' Enter")
os.system(f"tmux send -t 'go-cqhttp:core' "
f"'cd /qinse/cqbot/go-cqhttp;./go-cqhttp ./device.json' Enter")
if __name__ == '__main__':
systemctl_create_v2raycs()
systemctl_create_bot()
|
参考资料
[1] Louis Tumux使用手册
[2] Tmux: Productive Mouse-Free Development 中文版
[3] FAQ · tmux/tmux Wiki
[4] bash - How to write a shell script that starts tmux session, and then runs a ruby script - Stack Overflow