通过SSH传递参数:嵌入式Linux系统非阻塞输入方案咨询
解决嵌入式Linux程序远程SSH动态调整的方案
嘿,这个需求我之前做嵌入式设备开发时刚好碰到过,给你几个实用的方案,完全能满足你“不中断输出、仅按+/-就能调整行为”的要求:
方案1:信号处理(最省心,无需修改终端逻辑)
这个方案不需要程序处理任何键盘输入,而是通过Linux的信号机制传递指令,完全不影响程序的持续输出,是我个人最推荐的方案。
实现步骤:
- 在你的程序中绑定两个自定义信号(比如
SIGUSR1和SIGUSR2),分别对应+和-的调整逻辑。 - SSH远程连接设备后,通过
kill命令给目标进程发送信号即可触发调整。
代码示例(C语言):
#include <signal.h> #include <stdio.h> #include <unistd.h> // 用来保存调整参数 int adjust_value = 0; // 处理SIGUSR1信号(对应+) void on_adjust_up(int sig) { adjust_value++; printf("\n[Adjust] Up! Current value: %d\n", adjust_value); } // 处理SIGUSR2信号(对应-) void on_adjust_down(int sig) { adjust_value--; printf("\n[Adjust] Down! Current value: %d\n", adjust_value); } int main() { // 绑定信号处理函数 signal(SIGUSR1, on_adjust_up); signal(SIGUSR2, on_adjust_down); // 模拟你的持续输出主循环 int counter = 0; while (1) { printf("Program running... Counter: %d\n", counter++); sleep(1); // 这里根据adjust_value调整你的业务逻辑 // 比如 if(adjust_value > 0) { /* 执行对应行为 */ } } return 0; }
远程操作方法:
- 先找到程序的进程ID:
ps aux | grep your_app_name - 发送+调整信号:
kill -SIGUSR1 <进程ID> - 发送-调整信号:
kill -SIGUSR2 <进程ID>
优点:实现简单,不需要修改程序的输入处理逻辑,完全不干扰输出;缺点:仅适合少量固定指令的场景,扩展更多命令不太方便。
方案2:非阻塞终端输入(直接用SSH键盘按键)
如果必须用笔记本键盘直接按+/-来操作,那就要把程序的标准输入改成非阻塞模式,同时关闭终端的行缓冲(不然按+后要回车才会生效)。
代码示例(C语言):
#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <termios.h> #include <stdlib.h> struct termios old_terminal; // 程序退出时恢复终端原设置 void restore_terminal() { tcsetattr(STDIN_FILENO, TCSANOW, &old_terminal); } int main() { // 保存原终端属性 tcgetattr(STDIN_FILENO, &old_terminal); atexit(restore_terminal); // 设置终端为Raw模式:关闭行缓冲、关闭回显 struct termios new_terminal = old_terminal; new_terminal.c_lflag &= ~(ICANON | ECHO); new_terminal.c_cc[VMIN] = 0; // 非阻塞模式,无输入也立即返回 new_terminal.c_cc[VTIME] = 0; tcsetattr(STDIN_FILENO, TCSANOW, &new_terminal); // 将stdin设置为非阻塞 int flags = fcntl(STDIN_FILENO, F_GETFL, 0); fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK); int adjust_value = 0; int counter = 0; while (1) { char key; // 检查是否有按键输入 if (read(STDIN_FILENO, &key, 1) == 1) { if (key == '+') { adjust_value++; printf("\n[Adjust] Up! Current value: %d\n", adjust_value); } else if (key == '-') { adjust_value--; printf("\n[Adjust] Down! Current value: %d\n", adjust_value); } else if (key == 'q') { // 可选:按q退出程序 break; } } // 持续输出业务内容 printf("Program running... Counter: %d\n", counter++); usleep(500000); // 模拟业务处理耗时 } return 0; }
使用方法:
SSH连接设备后直接运行程序,此时按+/-键会立即触发调整,不需要回车,程序的持续输出也不会中断。
优点:符合你“直接按键操作”的需求;缺点:需要修改终端属性,要注意程序退出时恢复原设置,避免影响后续终端使用。
方案3:命名管道(适合扩展更多命令)
如果以后可能需要添加更多调整指令,命名管道(FIFO)是个不错的选择,它允许你通过文件IO的方式给程序发送任意命令。
实现步骤:
- 在设备上创建一个命名管道:
mkfifo /tmp/app_control_pipe - 程序中以非阻塞方式打开这个管道,循环读取命令
- SSH远程时通过
echo命令向管道写入+/-指令
代码示例(C语言):
#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <string.h> #define PIPE_PATH "/tmp/app_control_pipe" int main() { // 创建命名管道(如果不存在) mkfifo(PIPE_PATH, 0666); // 非阻塞方式打开管道 int pipe_fd = open(PIPE_PATH, O_RDONLY | O_NONBLOCK); if (pipe_fd == -1) { perror("Failed to open pipe"); return 1; } int adjust_value = 0; int counter = 0; while (1) { char buf[16]; int read_len = read(pipe_fd, buf, sizeof(buf)-1); if (read_len > 0) { buf[read_len] = '\0'; if (strncmp(buf, "+", 1) == 0) { adjust_value++; printf("\n[Adjust] Up! Current value: %d\n", adjust_value); } else if (strncmp(buf, "-", 1) == 0) { adjust_value--; printf("\n[Adjust] Down! Current value: %d\n", adjust_value); } } // 持续输出业务内容 printf("Program running... Counter: %d\n", counter++); sleep(1); } close(pipe_fd); return 0; }
远程操作方法:
- 发送+调整:
echo "+" > /tmp/app_control_pipe - 发送-调整:
echo "-" > /tmp/app_control_pipe
优点:扩展性强,可支持任意字符串命令;缺点:比信号处理稍复杂,需要管理管道文件。
总结推荐
- 如果只是简单的+/-调整,优先选信号处理方案,实现最省心,完全不干扰程序输出;
- 如果必须用SSH键盘直接按键操作,选非阻塞终端输入方案;
- 如果未来有扩展更多命令的需求,选命名管道方案。
内容的提问来源于stack exchange,提问作者Leos313
相关产品推荐
相关产品推荐

