我有一个我写的函数,输出这样的彩色输出类型:
foo() {
local arrow="\033[1;32m↑\033[0m"
echo "1$arrow"
}
我想测试这个函数,所以我正在使用https://github.com/kward/shunit2对它进行单元测试。
test_foo() {
local green_arrow="\033[1;32m↑\033[0m"
assertEquals "1$green_arrow" "$(foo)"
}
但是shunit抱怨说:ASSERT:expected:< 1↑> but was:< 1↑>
。我猜这个函数输出隐藏字符有问题。
有没有办法去掉特殊字符,或者从变量中删除它们?
编辑:
运行以下命令显示\\033
转义字符正在被回显转换为文字\E
转义符:
printf '%q' "1$green_arrow"
' 1\\033[1;32m?\206\221\\033[0m'
printf '%q' "$(foo)"
' 1\E[1;32m?\206\221\E[0m'
答案 0 :(得分:4)
使用printf -v varname_quoted %q "$varname"
获取内容的转义形式将提供一种易于阅读且易于理解的表单,该表单也可以作为文字包含在您的代码中,无需额外引用或转义需要。 (如果你的目标是将引用的内容发送到stdout而不是另一个变量),这可以简化为printf %q "$varname"
。
也就是说,要将格式字符串转换为文字(支持参数的格式字符串,即。%s
,%02f
等):
printf -v green_arrow '\033[1;32m↑\033[0m'
...或者,反斜杠转义字符串(仅支持完整格式字符串语法的子集)到文字:
printf -v green_arrow '%b' '\033[1;32m↑\033[0m'
...然后,以逃逸的,人类可读的形式发出该文字,以便于比较和/或复制并粘贴到shell脚本中作为文字:
printf '%q\n' "$green_arrow"
将所有这些结合在一起,以下是获取更易读的错误消息的一种方法(请原谅StackOverflow的语法突出显示,在撰写本文时,并未完全了解嵌套引用上下文在bash中的工作方式):
test_foo() {
local green_arrow=$'\E[1;32m↑\E[0m'
assertEquals "$(printf '%q' " 1$green_arrow")" "$(printf '%q' "$(foo)")"
}
...或者,更有效率(避免不必要的子壳):
test_foo() {
local green_arrow=$'\E[1;32m↑\E[0m'
local desired_answer_quoted actual_answer_quoted
printf -v desired_answer_quoted '%q' " 1$green_arrow"
printf -v actual_answer_quoted '%q' "$(foo)"
assertEquals "$desired_answer_quoted" "$actual_answer_quoted"
}