我有一个简单的 debug_print shell 函数,用于帮助编写更大的 shell 脚本。一般来说,我尽量只编写与 Bourne 兼容的脚本并避免使用 Bash 主义。在这种情况下,我的 debug_print 函数的 Bash 版本可以正常工作,但我一生都无法弄清楚为什么我的 Bourne 兼容版本会失败。具体来说,我的问题在于将 %s 格式修饰符与 printf 一起使用。
我在下面包含了我的测试脚本。debug_print 函数显示一个带有标签的标题栏、其字符串或文件参数的内容,最后是一个与标题宽度相同的页脚栏。问题在于显示页脚栏并以注释“显示页脚行...”开头。下面的两条未注释的行是我认为应该起作用的,但不是。
紧随其后的是“这些都不起作用”注释下的几行注释,您可以在其中看到我在尝试找出问题时使用的一些各种测试/方差。在这些行之后是一个工作的 Bourne 版本,最后是一个工作的 Bash 版本。
我已经详细阅读了手册页,并尝试了我能想到的各种格式字符串、引用和变量使用。到目前为止,这些尝试都没有奏效。在“这些都不起作用”注释下,没有工作的命令都打印出整个字符串,而不是我相信它们应该只打印由字段宽度修饰符指定的字符数。
为了确定“Bourne 兼容性”,我在我的系统上使用 dash 作为 /bin/sh,这是 Debian 系统的典型。Dash 用于高效的脚本执行而不是交互式使用。根据手册页,它力求严格兼容 Bourne,所以我推断如果我的脚本与 dash 一起使用,那么它应该是合理的 Bourne 兼容并且没有 bash 主义。此外,我认识到此功能不是调试打印的全部/全部,并且可能有许多极端情况和可以改进的区域。我欢迎所有建议,但我对这个 printf 问题特别感兴趣。鉴于这应该是多么简单,看来我一定犯了一些愚蠢的错误,但我无法发现它。
这是我的 debug_print 测试脚本:
#!/bin/sh
#
# Purpose: Debug print function. Outputs delimiting lines and will display
# either the contents of a file or the contents of a variable.
#
# Usage: debug_print label input
# Where label is the title to print in the header bar, usually the name of
# the input variable. Input is either a file on disk to be printed, or,
# if the argument is not a file then it is assumed to be a string and that
# will be displayed instead.
#
# Returns: If two parameters are not provided, returns false, otherwise it
# will always return true.
#
debug_print()
{
local header_bar header_len dashes
# Check for arguments
if [ $# -ne 2 ]; then
printf "Error: debug_print takes two parameters: 'label' and 'input'\n"
return 1
fi
header_bar="-------------------------$1-------------------------"
header_len=${#header_bar}
printf "%s\n" "$header_bar"
# Display either the contents of the input file or the input string
if [ -r "$2" ]; then
cat "$2"
else
printf "%s\n" "$2"
fi
# Display a footer line with the same length as the header line
dashes="------------------------------------------------------------"
printf "%*s\n" "$header_len" "$dashes"
# None of these work
# printf "%${header_len}s\n" "$dashes"
# printf "%${header_len}s\n" "------------------------------------------------------------"
# printf "%5s\n" xxxxxxxxxxxxxxxxxxxx
# printf '%5s\n' "xxxxxxxxxxxxxxxxxxxx"
# xxx="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# printf '%5s\n' $xxx
# This works with dash
# i=$header_len
# while [ $i -gt 0 ]; do
# printf "-"
# i=$(( $i - 1 ))
# done
# printf "\n"
# Working bash version
# printf -v foot_line '%*s' $header_len
# echo ${foot_line// /-}
return 0
}
# Test debug printing
debug_print "Label" "The contents of the debug input..."
谢谢你的帮助。