C语言自定义shell实现stderr重定向、查看路径及重置功能求助
C语言自定义shell stderr查询与重置实现方案
前置准备
要实现重置功能,必须在程序启动、还未执行任何重定向操作前,先保存原始stderr的文件描述符副本,建议定义为全局或静态变量:
// 放在全局作用域,所有函数都能访问 static int saved_stderr; // main函数启动第一时间执行以下逻辑 saved_stderr = dup(STDERR_FILENO); if (saved_stderr == -1) { perror("Failed to save original stderr"); exit(EXIT_FAILURE); }
这个副本会一直保留初始stderr的指向(默认是终端设备),全程不要关闭,直到程序退出。
1. 查询当前stderr输出目标实现
Linux环境下可以通过读取/proc/self/fd/2软链接的指向获取stderr当前的输出目标,代码如下:
if(tokens[1] == NULL){ char path[1024]; char fd_path[256]; snprintf(fd_path, sizeof(fd_path), "/proc/self/fd/%d", STDERR_FILENO); ssize_t len = readlink(fd_path, path, sizeof(path)-1); if (len == -1) { perror("Failed to read stderr target"); return 0; } path[len] = '\0'; printf("Current stderr output target: %s\n", path); return 0; }
如果是其他类Unix系统没有/proc文件系统,可以用fstat获取文件属性判断是终端、普通文件还是管道等类型,无法直接获取路径。
2. 重置stderr为初始状态实现
直接用提前保存的原始stderr副本覆盖当前的STDERR_FILENO即可:
if(strcmp(tokens[1], "-reset") == 0){ if (dup2(saved_stderr, STDERR_FILENO) == -1) { perror("Failed to reset stderr"); return 0; } printf("stderr has been restored to original state\n"); return 0; }
优化建议
你现有重定向逻辑可以做小调整,兼容目标文件不存在的场景:
int fd; // 增加O_CREAT标志,文件不存在时自动创建,指定权限为644 if((fd = open(tokens[1], O_RDWR | O_CREAT | O_TRUNC, 0644)) == -1){ perror("Error opening: "); return 0; } if(dup2(fd, STDERR_FILENO) == -1){ perror("Error redirect stderr: "); close(fd); return 0; } close(fd);
内容的提问来源于stack exchange,提问作者rascadux
相关产品推荐
相关产品推荐

