如何在Bash终端测试?以及如何为filter函数创建输入文件描述符?
1. 如何在Bash终端中进行测试?
在Bash里做测试主要围绕命令执行结果、文件属性、字符串/数值比较这几个核心场景,下面是实用的实现方法:
验证命令执行状态
每个命令执行后都会返回退出状态码(0=成功,非0=失败),直接用if语句判断即可:# 检查日志中是否存在目标关键词 if grep -q "error" app.log; then echo "日志中发现错误记录" else echo "日志未检测到错误" fi文件与目录属性测试
用[ ]或[[ ]]语法快速检查文件状态,比单独调用test命令更直观:# 检查文件是否存在且可执行 if [[ -x ./start.sh ]]; then echo "脚本可执行,正在启动..." ./start.sh fi # 检查目录是否为空 if [ -z "$(ls -A temp_dir)" ]; then echo "临时目录为空" fi常用测试选项:
-f(普通文件)、-d(目录)、-r(可读)、-w(可写)、-s(非空文件)。字符串与数值比较
字符串比较优先用[[ ]]避免空格等特殊字符问题,数值比较用专用的比较符:# 字符串匹配测试 if [[ "$USER" == "dev" ]]; then echo "欢迎开发用户" fi # 数值范围判断 if [ "$process_count" -ge 5 ]; then echo "进程数量已达阈值" fi脚本调试与流程验证
要测试脚本的执行细节,用bash -x追踪每一步命令:bash -x deploy.sh也可以在脚本开头加
set -e,让脚本在任意命令失败时立即退出,提前暴露问题。
2. 如何为输入创建readfd文件描述符?
针对你提到的filter函数,创建readfd的方式完全取决于输入来源,下面分场景说明:
在C代码内部创建readfd
如果是在调用filter的C程序中生成输入描述符,常见实现方式有这些:
从普通文件读取
用open()打开目标文件,获取可读的文件描述符:#include <fcntl.h> #include <stdio.h> #include <unistd.h> int main() { int m = 3; // 以只读模式打开输入文件 int readfd = open("numbers.txt", O_RDONLY); if (readfd == -1) { perror("打开文件失败"); return 1; } // 用标准输出作为写端 int writefd = STDOUT_FILENO; int result = filter(m, readfd, writefd); close(readfd); return result; }从标准输入读取
直接使用系统预定义的STDIN_FILENO(值为0)作为readfd,这样filter会读取终端输入或重定向的内容:int result = filter(m, STDIN_FILENO, writefd);从管道读取
如果输入来自另一个进程的输出,用pipe()创建管道,将读端传给filter:#include <unistd.h> #include <sys/wait.h> int main() { int pipefd[2]; if (pipe(pipefd) == -1) { perror("创建管道失败"); return 1; } pid_t pid = fork(); if (pid == 0) { close(pipefd[0]); // 子进程关闭读端 // 写入测试数据 int nums[] = {2,3,4,5,6,7}; write(pipefd[1], nums, sizeof(nums)); close(pipefd[1]); _exit(0); } else { close(pipefd[1]); // 父进程关闭写端 filter(3, pipefd[0], STDOUT_FILENO); close(pipefd[0]); wait(NULL); } return 0; }从内存缓冲区读取
用memfd_create()创建匿名内存文件,写入临时数据后作为readfd,适合不需要持久化的输入:#include <sys/memfd.h> #include <unistd.h> int main() { int memfd = memfd_create("temp_input", MFD_CLOEXEC); if (memfd == -1) { perror("创建内存文件失败"); return 1; } int nums[] = {8,9,10,11,12}; write(memfd, nums, sizeof(nums)); lseek(memfd, 0, SEEK_SET); // 回到文件起始位置 filter(3, memfd, STDOUT_FILENO); close(memfd); return 0; }
在Bash终端中为程序预设readfd
如果你的程序通过命令行参数接收readfd数值,可以在Bash中预先打开文件描述符再传给程序:
# 将文件描述符3关联到input.txt exec 3<input.txt # 运行程序,把3作为readfd参数,1作为标准输出写端 ./filter_app 3 3 1 # 关闭文件描述符3 exec 3<&-
这样程序中的readfd就会指向input.txt的内容。
内容的提问来源于stack exchange,提问作者heskinreaper

