タイトルと本文の2つの文字列パラメータを使用する関数(notify_dba)があります。 (修正)シェルプロンプトではうまく機能しますが、cronでは機能しません。 Err、シェルや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
あなたの質問に対するコメントに示されているように、表示されるエラーはunquotingによって引き起こされ、${
これはパラメータ拡張をトリガします(「拡張」セクションの「パラメータ拡張」を参照)。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
2番目の引数は、次の理由で二重引用符で囲む必要があります。 1)引用符がない場合はシェルで展開され、複数の単語が生成されると次のように変換されます。1つ以上の引数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