Heredocsへの入力に一重引用符を使用する

Heredocsへの入力に一重引用符を使用する

tcshスクリプトをデバッグするのに助けが必要です。 heredocsを使用してください。パスワード:

<pre_setup> <<EOF1
<setup> <<EOF2

<command>

exit 0
EOF2
exit 0
EOF1

これは<pre_setup>、あらかじめ設定されたコマンド(たとえばwash)とsetupそれ以降に実行されるいくつかの設定です。動作しますが、setup一重引用符が含まれていると失敗することがわかりました。私の設定は次のとおりです。

run_setup -cmd '$SOME_ENV -o outdir'

以下を設定run_setupして$SOME_ENV実行します$SOME_ENV -o outdir

wash -n group_name <<EOF1
run_setup -cmd '$SOME_ENV -o outdir' <<EOF2

<command>

exit 0
EOF2
exit 0
EOF1

失敗するSOME_ENV: Undefined variable.。 (または)asを使用すると、まだ同じエラーで失敗するため、washinでは問題になりません。これはheredocsがどのように機能するかに関するものです。どのように動作させることができますか?脱出の問題ですか?この文書をどのようにデバッグできますか?pre_setupsetenv X 1catpre_setup

run_setup -cmd '$SOME_ENV -o outdir'また、シェルで実行すると機能することにも言及したいと思います。それとも走るだけpre_setupですsetup。だからこれはheredocsに関連しています。

編集する:引用符で囲み、次のようにコードを区切ります。

/bin/tcsh <<EOF
$WORK_AREA/script.sh.$1
echo \$status > $WORK_AREA/.$1.result
exit 0
EOF

ここで、$ 1 $はthisを含むスクリプトへの入力ですheredocs。一重引用符で囲まれている場合、$1in$WORK_AREA/script.sh.$1は空です。しかし、引用符がない場合は動作します。なぜ?どうすれば解決できますか?

ベストアンサー1

一般的なhere-docは、変数などを拡張するという点で二重引用符で囲まれた文字列と少し似ています。

foo=there
cat <<EOF
hello $foo
EOF

「こんにちは」を出力します。 sh-likesでは、変数が定義されていない場合、通常はエラーは発生せず、空の文字列のみが表示されます。

引用は関係ありません。一重引用符が二重引用符では特別ではないように、ここでは特別なものではありません。たとえば、次も拡張されます$fooecho "hello '$foo'"

拡張を防止したいと思うので、区切り文字を引用すればいいです。しかし、shに似たシェルと(t)cshの間には若干の違いがあるようです。

sh-likeでは次のようになります。

foo=there
cat <<'EOF'
hello $foo
EOF

prints hello $foo、つまり変数を拡張しようとする試みは行われません。

(t)cshでは、同じ方法で閉じる区切り文字を引用する必要があるようです。

foo=there
cat <<'EOF'
hello $foo
'EOF'

これDebian の tcsh のマニュアルページ説明する:

<< word
次の行が表示されるまでシェル入力を読みます。言葉言葉変数、ファイル名、コマンド置換の影響を受けず、各入力行は次のようになります。言葉この入力ラインを置き換える前に。

\"または引用しない'場合`言葉[、]変数とコマンドの置換は、およびを引用して\中間行で行われます。$\`

私は、「最大行が同じ」(および「置き換える前の比較」)は、参照が同じであることを意味すると思います。 (これはBashのマニュアルページで言うのとは異なります:「もし言葉引用符が付いている場合、区切り文字は引用符を削除した結果です。言葉、[...]".)

2番目の部分はPOSIX shと同じです。ここで引用された区切り文字は、文書テキストの拡張を抑制します。


この資料でシェルを提供すると、すべての変数を拡張できる2つのシェルが提供されます。 here-docのシェルを構築し、内部シェルを実行して読みます。彼らは変数が何であるかについて異なる考えを持つことができます。たとえば、内部変数には基本スクリプトの引数がありません。引用とエスケープ処理によって、拡張される変数が決まります。

したがって、これを実行すると:

#!/usr/bin/tcsh
set foo = outer
echo in outer shell, foo is: $foo

tcsh <<EOF
set foo = inner
echo "not escaped, outer shell expands: $foo"
echo "    escaped: inner shell expands: \$foo"
EOF

見える内部シェル

set foo = inner
echo "not escaped, outer shell expands: outer"
echo "    escaped: inner shell expands: $foo"

最初のものは$fooすでに拡張されており、バックスラッシュはから拡張されています\$foo。代わりにそれを使用すると、<<'EOF'シェルは拡張されません。

したがって、ここでは引用符なしで使用する必要があり<<EOF、必要な日に応じてすべての変数を個別にエスケープまたは処理しないように注意する必要があります。

おすすめ記事