脚本向二进制程序传入STDIN导致重复输入问题
问题分析与解决
你推测是换行符持续传入的情况不对,真实原因是:当通过管道或heredoc传入用户名和密码后,标准输入流(stdin)的内容被读完,流会被关闭,导致后续的fgets()调用直接返回NULL。而你的代码没有处理fgets()返回NULL的情况,所以会陷入无限循环,持续打印菜单提示。
代码修复
修改菜单循环部分,增加对fgets()返回值的判断,当输入流关闭时退出循环:
#include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { char username[32] = {0}; printf("Username: "); if (fgets(username, sizeof(username), stdin) == NULL) { return 1; } username[strcspn(username, "\n")] = '\0'; char password[32] = {0}; printf("Password: "); if (fgets(password, sizeof(password), stdin) == NULL) { return 1; } password[strcspn(password, "\n")] = '\0'; printf("\nWelcome!\n"); while (1) { char command_buffer[1024] = {0}; printf("Enter one of the following commands (EDG, UED, SCS, DTE, AED, UVF, OUT): "); // 检测输入流是否关闭 if (fgets(command_buffer, sizeof(command_buffer), stdin) == NULL) { printf("\nInput ended, exiting.\n"); break; } command_buffer[strcspn(command_buffer, "\n")] = '\0'; // 可以添加命令处理逻辑,比如支持OUT命令退出 if (strcmp(command_buffer, "OUT") == 0) { printf("Exiting program.\n"); break; } } return 0; }
脚本调用优化
如果希望传入用户名密码后,程序能继续接受手动输入,推荐用expect工具模拟交互式会话:
#!/usr/bin/expect spawn ./example expect "Username: " send "dev\n" expect "Password: " send "pass\n" interact # 切换到手动交互模式
如果坚持用管道/ heredoc,修改后的代码会在输入流关闭时自动退出循环,此时用以下脚本即可:
./example <<<$'dev\npass'
内容的提问来源于stack exchange,提问作者Edward Chamberlain
相关产品推荐
相关产品推荐

