如何在Bash中解析命令变量里的重定向目标以适配模拟器执行格式
如何从Bash命令变量中提取重定向目标?
其实Bash并没有内置你设想的那种-secret_option_to_parse_redirect_target参数,但我们可以利用Bash自身的解析机制,通过简单的脚本实现自动提取输入、输出、错误重定向的目标文件,完全不需要手动写复杂的字符串解析逻辑。
核心思路
我们的目标是让Bash帮我们解析命令字符串,同时替换掉原始命令的执行逻辑——只捕获重定向的文件路径,不实际运行那个二进制文件。这里主要用到Bash的DEBUG陷阱和eval命令来实现。
实现脚本
你可以把下面的代码放到你的shell环境里(或者保存成脚本):
# 定义提取重定向的函数 extract_redirect() { local cmd="$1" local target_type="$2" # 空函数,用来替代原始二进制文件的执行,避免实际运行程序 noop() { :; } case "$target_type" in input) # 捕获输入重定向(< filename) trap '[[ "$BASH_COMMAND" == "<"* ]] && echo "${BASH_COMMAND:1}"' DEBUG # 用noop替换原始命令的执行,eval解析整个命令 eval "${cmd//\./noop }" 2>/dev/null trap - DEBUG # 关闭DEBUG陷阱 ;; output) # 捕获标准输出重定向(> filename) trap '[[ "$BASH_COMMAND" == ">"* ]] && echo "${BASH_COMMAND:1}"' DEBUG eval "${cmd//\./noop }" 2>/dev/null trap - DEBUG ;; error) # 捕获标准错误重定向(2> filename) trap '[[ "$BASH_COMMAND" == "2>"* ]] && echo "${BASH_COMMAND:2}"' DEBUG eval "${cmd//\./noop }" 2>/dev/null trap - DEBUG ;; *) echo "用法错误:请指定 input、output 或 error 作为第二个参数" return 1 ;; esac }
使用示例
按照你的场景,这样调用函数即可:
CMD="./binary -long=list -of=args <input.txt >std.out 2>std.err" # 获取输入重定向目标 extract_redirect "$CMD" input # 输出:input.txt # 获取输出重定向目标 extract_redirect "$CMD" output # 输出:std.out # 获取错误重定向目标 extract_redirect "$CMD" error # 输出:std.err
原理说明
DEBUG陷阱:Bash会在每一条命令执行前触发这个陷阱,我们通过判断BASH_COMMAND的内容,识别出重定向操作,然后截取对应的文件路径。eval命令:用来让Bash解析我们传入的命令字符串,包括其中的重定向语法。noop空函数:我们把命令中的./binary替换成noop,这样Bash解析完重定向后,只会执行一个空操作,不会实际运行那个基准测试的二进制文件。2>/dev/null:用来屏蔽解析过程中可能出现的无关错误信息。
扩展说明
如果你的命令中有更复杂的重定向(比如>>追加输出、2>&1合并错误输出等),只需要调整trap里的判断条件即可。比如要捕获>>,可以把判断改成[[ "$BASH_COMMAND" == ">>"* ]] && echo "${BASH_COMMAND:2}"。
内容的提问来源于stack exchange,提问作者Emil Vatai
相关产品推荐
相关产品推荐

