如何用C++实现tmux多窗格的输入输出交互及消息转发?
Tmux多窗格交互功能实现问题
下方代码用于在tmux中创建两个窗格,并执行倒计时至20的逻辑:
#include <iostream> #include <fstream> #include <thread> #include <vector> #include <chrono> #include <atomic> #include <mutex> #include <string> #include <array> #include <memory> // 执行shell命令并返回结果 std::string exec(const std::string& cmd) { std::array<char, 128> buffer; std::string result; std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose); if (!pipe) { throw std::runtime_error("popen() failed!"); } while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) { result += buffer.data(); } return result; } // 线程执行函数 void threadFunction(const std::string& tty, std::atomic<bool>& running, int threadId) { int messageCount = 0; std::ofstream ttyStream(tty); if (!ttyStream.is_open()) { std::cerr << "Failed to open tty: " << tty << std::endl; return; } while (running.load()) { ttyStream << "Thread " << threadId << " is running: message " << messageCount++ << std::endl; ttyStream.flush(); std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } } void kill(const std::string& sessionName){ std::string command = "tmux send-keys -t " + sessionName + " \" tmux kill-server\" Enter"; // 捕获输出用于调试 std::string output = exec(command); std::cerr << "Command output: " << output << std::endl; if (std::system(command.c_str()) != 0) { std::cerr << "Error executing command: " << command << std::endl; } } int main() { const std::string sessionName = "Client"; const int numThreads = 2; // 线程与窗格数量 // 创建tmux会话和窗格,并获取它们的TTY std::string createSessionCmd = "tmux new-session -d -s " + sessionName + " -PF '#{pane_id}' 'tail -f /dev/null'"; std::string pane1 = exec(createSessionCmd); pane1.pop_back(); // 移除换行符 std::string splitPaneCmd = "tmux split-window -t " + sessionName + " -PF '#{pane_id}' 'tail -f /dev/null'"; std::string pane2 = exec(splitPaneCmd); pane2.pop_back(); // 移除换行符 std::string getTtyCmd1 = "tmux display-message -p -t " + pane1 + " '#{pane_tty}'"; std::string tty1 = exec(getTtyCmd1); tty1.pop_back(); // 移除换行符 std::string getTtyCmd2 = "tmux display-message -p -t " + pane2 + " '#{pane_tty}'"; std::string tty2 = exec(getTtyCmd2); tty2.pop_back(); // 移除换行符 std::cout << "TTY1: " << tty1 << std::endl; std::cout << "TTY2: " << tty2 << std::endl; std::atomic<bool> running(true); // 创建并运行线程 std::thread t1(threadFunction, tty1, std::ref(running), 1); std::thread t2(threadFunction, tty2, std::ref(running), 2); std::thread t3([&sessionName]() { std::this_thread::sleep_for(std::chrono::seconds(20)); // 延长测试休眠时间 std::string command = "tmux new-window -t " + sessionName + " -n thread" + std::to_string(2); std::system(command.c_str()); kill(sessionName); }); t1.detach(); t2.detach(); t3.detach(); // 附加到tmux会话 std::string cmd = "tmux attach -t " + sessionName; std::system(cmd.c_str()); return 0; }
当前问题与期望效果
- 现有代码问题:窗格无法接收任何输入,甚至无法执行命令,关闭tmux会话必须新建窗口执行
tmux kill-server。 - 期望实现:
- 线程在指定窗格显示计数消息
- 用户在某窗格输入内容时,计数暂停
- 输入内容转发至另一窗格显示
- 输入完成后从暂停位置继续计数
替代方案的问题
若不直接操作TTY,尝试让每个窗格将用户输入写入文件,再通过新线程读取内容并显示到指定窗格,但会出现两个问题:
- 用户输入回车后,系统会提示输入内容不是有效命令
- C++程序需通过
echo命令显示消息,导致消息重复显示(如下图):

内容的提问来源于stack exchange,提问作者Karan Patel
相关产品推荐
相关产品推荐

