嵌入换行符的bash函数参数

时间:2017-08-04 05:00:27

标签: bash arguments newline

我已经在bash中编写了一个名为 trace()的通用记录器函数,其第三个参数以及其他内容应该以文本形式标记和打印,保留任何嵌入的换行符。但它并没有。 我正在寻找类似于echo命令的效果,并按预期执行(在下面尝试过)。 看起来像俱乐部在一起的事情应该归咎于($ {@:3})?

<input type="date"> 

试验/输出

timeStamp() { echo `date "+%Y-%m-%d %H:%M:%S:%3N %Z"` ;}

trace() {
  lineNum=$1
  traceType=$2
  traceText=${@:3} #Input Parameters 3rd and beyond
  #echo -en "[${lineNum}][$(timeStamp)][${traceType}]: ${traceText}"
  #printf "[%s][%s][%s]: %s\n" ${lineNum} "$(timeStamp)" ${traceType} "${traceText}"
  printf "[${lineNum}][$(timeStamp)][${traceType}]: ${traceText}"
}

2 个答案:

答案 0 :(得分:2)

问题确实在traceText=${@:3}。通常情况下,$@相当于$1 $2 $3...(以及${@:3}$3 $4 $5...),并且因为它不是双引号,所以每个都经过分词和通配符扩张。但是在var=$@的情况下,它无法为var分配多个值,因此单词拆分和通配符扩展会被抑制......但显然不完全。它显然做了足够的单词拆分,将换行符转换为空格。

我不清楚这是不是一个错误;由于$@(将每个参数视为单独的项目)与=(只能分配一个值)之间的冲突,IMO这种情况实际上没有意义。 IMO您应该使用的是traceText="${*:3}",这是明确的 - 双引号明确地抑制了单词拆分和通配符扩展,而$*意味着将所有参数与空格(或任何IFS的第一个字符是)。

在我的测试中(使用bash v3.2.57),所有这些都按预期工作:

traceText=${*:3}
traceText="${*:3}"
traceText="${@:3}"

唯一产生奇怪结果的是@而没有双引号。

答案 1 :(得分:0)

除了评论之外,您还可以完全重写trace()以包含date命令替换,并只使用位置参数printf 格式字符串中。例如:

trace() { 
    printf "[$1]$(date "+%Y-%m-%d %H:%M:%S:%3N %Z")][$2]: ${@:3}"
}

示例使用/输出

$ trace 123 "some error" "this
is my
multi-line
text
"
[123]2017-08-04 01:01:29:765 CDT][some error]: this
is my
multi-line
text

注意:可以传递的位置参数的数量有限制,因此如果您的多行文字超出限制,trace不管用。请参阅:Bash command line and input limit