如何在macOS Shell中实现进程输入输出Diff对比(无临时文件/命名管道)
实现输入与命令输出的差异对比包装器(兼容macOS Shell)
需求说明
需要为一个从stdin接收数据、stdout输出结果的命令编写包装器,仅输出该命令的原始输入与处理后输出的差异。要求不使用临时文件或命名管道,且兼容macOS Shell。流程示意如下:
/---> 目标命令 --->\ stdin--->+ diff ---> stdout \----------------->/
解决方案
利用Shell的进程替换、文件描述符结合tee和diff即可实现,以下是具体写法:
直接命令写法
将你的目标命令替换为实际需要包装的命令(如sed 's/foo/bar/'、tr 'a-z' 'A-Z'),执行以下命令:
diff <(tee /dev/fd/3) <(你的目标命令) 3<&0
可复用包装器函数
如果需要重复使用,可定义Shell函数:
diff_cmd_input_output() { # 用法:diff_cmd_input_output "目标命令" local target_cmd="$1" diff <(tee /dev/fd/3) <(eval "$target_cmd") 3<&0 }
使用示例
# 测试:将输入的foo替换为bar,对比输入与输出差异 echo -e "foo\nhello\nfoo" | diff_cmd_input_output "sed 's/foo/bar/'"
工作原理
3<&0:将文件描述符3绑定到当前stdin,让后续命令可通过fd3读取原始输入流。<(tee /dev/fd/3):tee读取stdin的所有数据,一方面将原始数据输出作为diff的第一个对比源,另一方面将数据写入fd3,确保目标命令能获取完整的原始输入。<(你的目标命令):目标命令通过fd3读取原始输入,处理后的结果作为diff的第二个对比源。diff对比两个数据源,仅输出差异到stdout。
该方案未使用临时文件或命名管道,兼容macOS默认的bash和zsh Shell。
内容的提问来源于stack exchange,提问作者Droopycom
相关产品推荐
相关产品推荐

