set -u は bash スクリプトの heredoc で設定されていない値を探します。

set -u は bash スクリプトの heredoc で設定されていない値を探します。

ここでスクリプトを簡素化しました。

#!/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キャプチャされます。optopt$@

親スクリプト自体の一部ではないため、区切り文書のすべての変数とテキストを無視する方法はありますか?私の考えでは、heredocをスクリプト構文に基づいて解析するのではなく、巨大な文字列として扱うようです。

答え1

Heredocは巨大な文字列ですが、終端文字列(SCRIPTyours << 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

関連情報