< を使用するときにサブシェル内で変数を設定する

< を使用するときにサブシェル内で変数を設定する

「newgrp」によって起動されるサブシェルにコマンドを渡すために、次の方法を使用しています。

#!/bin/csh
echo "Before newgrp"
/usr/bin/newgrp users <<EONG
echo "hello from within newgrp"
id
EONG
echo "After newgrp"

サブシェルで何かを「設定」しようとしない限り、正常に動作します。

つまり

#!/bin/csh
echo "Before newgrp"
/usr/bin/newgrp users <<EONG
echo "hello from within newgrp"
set a=npy
echo $a
id
EONG
echo "After newgrp"

上記のように、サブシェル内で a=npy を設定し、echo $a を実行すると npy が返されるはずです。ただし、a が宣言されていないため、エラーが表示されます。

使用中にサブシェル内で環境変数を設定する方法を教えてください。<<

答え1

この<<構造はシェルを導入するここに文書これは、読み取られるときに二重引用符で囲まれた文字列として扱われるため、変数はシェルによって読み取られるとすぐに展開されます。未定義の変数について通知するシェル機能を有効にすると、これが明確にわかります。ここでは、BASH シェルでその機能を使用します。

$ set -o nounset
$ echo "$a"
bash: a: unbound variable
$ bash <<EOF
> a=foo
> echo "$a"
> EOF
bash: a: unbound variable

シェルがヒアドキュメントの変数を展開するのを止めるには、タグをシングルクォートで囲むか、バックスラッシュで囲みます。 の使用変数:

$ bash <<'EOF'
> a=foo
> echo "$a"
> EOF
foo

$ bash <<EOF
> a=foo
> echo "\$a"
> EOF
foo

ヒアドキュメント内の変数を囲む引用符の種類は、ヒアドキュメントの読み取り時にシェルによって変数が展開されるかどうかとは関係がないことに注意してください。

追伸意図しない GLOB ファイル名の一致がトリガーされないように、変数の展開は常に二重引用符で囲みます。

ppsシェルで未定義変数のチェックをオンにして、入力エラーを検出します。これにより、問題の原因がわかるはずです。

pppsスクリプトには C シェルを使用しないでください。 バグが多い そして矛盾

答え2

文字列で区切られたヒアドキュメントを使用していますEONG

でヒアドキュメントを導入する場合<<word、ヒアドキュメントが展開されるかどうかは、言葉引用符で囲まれていない文字がある場合、ヒアドキュメントはパラメータ展開、コマンド置換、算術展開の対象となります。少なくとも1つの文字が引用符で囲まれている場合、ヒアドキュメントは展開の対象となりません。BourneおよびKorn(およびPOSIX)シェルは、完全に引用符で囲まれていない文字を使用します。言葉最後の区切り文字としてCシェルでは言葉そのまま。

例を次のように書き直すことができます。

#!/bin/csh
echo "Before newgrp"
/usr/bin/newgrp users <<"EONG"
echo "hello from within newgrp"
set a=npy
echo $a
id
"EONG"
echo "After newgrp"

それ以外の場合は、引用符なしの言葉、に標準入力として渡される前にシェルによって置換されないように$aエスケープする必要があります。\$anewgrp

#!/bin/csh
echo "Before newgrp"
/usr/bin/newgrp users <<EONG
echo "hello from within newgrp"
set a=npy
echo \$a
id
EONG
echo "After newgrp"

関連情報