ここでスクリプトを簡素化しました。
#!/bin/bash
# test.sh
set -u
### test-script ###
cat <<SCRIPT > ~/test-file-output
#!/bin/bash
set -e
usage() {
cat <<EOF
Does a thing
EOF
}
for opt in "$@"; do
case $opt in
-h|--help)
usage
exit 0
;;
*)
echo "Invalid option: $opt" >&2
usage
exit 1
;;
esac
done
SCRIPT
chmod +x ~/test-file-output
親スクリプトにあるため、heredocのサブスクリプトのvarはサブスクリプトに設定された値でset -u
キャプチャされます。opt
opt
$@
親スクリプト自体の一部ではないため、区切り文書のすべての変数とテキストを無視する方法はありますか?私の考えでは、heredocをスクリプト構文に基づいて解析するのではなく、巨大な文字列として扱うようです。
答え1
Heredocは巨大な文字列ですが、終端文字列(SCRIPT
yours << SCRIPT
)が引用符で囲まれていない場合は、次のように動作します。二重引用符文字列なので、すべての変数が展開されます。リダイレクトでターミネータの一部が参照されている場合(たとえば<< "SCRIPT"
、)、これは次のように機能します。アポストロフィ文字列なので、変数拡張はありません。
次のスクリプトを考えてみましょう。
$ cat heredoc.sh
#!/bin/bash
var=xyz
cat <<EOF
var=$var
EOF
cat <<'EOF'
var=$var
EOF
$ ./heredoc.sh
var=xyz
var=$var
最初の項目はEOF
引用されていないので$var
拡張されます。 2つ目は、文字列にcat
リテラルが含まれることです$var
。