我有一个函数(notify_dba),它有两个字符串参数,一个标题和一个主体。 (更正)在 shell 提示符下工作得很好,但在 cron 中不行Err,在 shell 或 cron 中都不起作用(但应该......?):
53 notify_dba "${FRIENDLY_SERVER_NAME}: New ORA errors in AlertLog" echo ${
54 "Please check full log in ${ALERT_LOG_LOCATION}.
55 =====================================================
56 `grep -A900000 "${LAST_LINE_FROM_ARCHIVE}:" ${TEMPORARY_LOG_WITH_ORA_ERRORS} | grep -v "${LAST_LINE_FROM_ARCHIVE}:"`
57 =====================================================
58 "}
得到错误:
Wed Jan 16 06:00:01 PST 2019
LAST_LINE_FROM_ARCHIVE=449843
LAST_LINE_FROM_TEMP= 452866
/u01/app/oracle/admin/chk_alertlog.sh: line 53: ${
"Please check full log in ${ALERT_LOG_LOCATION}.
=====================================================
`grep -A900000 "${LAST_LINE_FROM_ARCHIVE}:" ${TEMPORARY_LOG_WITH_ORA_ERRORS} | grep -v "${LAST_LINE_FROM_ARCHIVE}:"`
=====================================================
"}: bad substitution
答案1
正如对您的问题的评论中指出的那样,您看到的错误是由于未加引号的${
,它触发了参数扩展(请参阅“扩展”部分中的“参数扩展”)man bash
)。
也就是说,您当然可以传递多行文本块。你只需正确引用它:
如果是静态的,单引号就可以了:
$ mlblock='line 1
> line 2'
$ printf '%s\n' "$mlblock"
line 1
line 2
如果您希望在执行时构建它,则必须使用双引号,它保留$
,`
和的特殊含义\
,允许,除其他事项外、参数扩展和命令替换:
$ text="Sample text"
$ mlblock="$text
> date: $(date)
> end"
$ printf '%s\n' "$mlblock"
Sample text
date: Wed Jan 16 22:18:33 CET 2019
end
请注意,出现在双引号内的字符串中任何位置的扩展本身都会被引用。因此,它们的间距被保留(例如Sample text
)。
将复杂字符串传递给函数的最易读的方法可能是使用变量:
$ function notify_dba () {
printf '%s\n' "$1" # Print header
printf '%s\n' "$2" # Print body
}
$ notify_dba 'Header' "$mlblock"
Header
Sample text
date: Wed Jan 16 22:21:14 CET 2019
end
请注意,第二个参数必须出现在双引号中,因为: 1) 如果不加引号,它会被 shell 扩展,并且当产生多个单词时,会被翻译为不止一个论点到函数; 2) 如果用单引号括起来,它将按字面解释为字符串$mlblock
。
当然,您也可以在调用函数时构建参数字符串:
$ notify_dba 'Header' "Multi
> line body
> date: $(date)
> end"
Header
Multi
line body
date: Wed Jan 16 22:29:13 CET 2019
end