使用 < 时在子 shell 内设置变量

使用 < 时在子 shell 内设置变量

我使用以下方法将命令传递到由“newgrp”启动的子 shell 中。

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

只要我不尝试在子 shell 中“设置”任何内容,它就可以正常工作。

IE

#!/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"

正如您在上面看到的,我在子 shell 中设置了 a=npy 并执行 echo $a 应该返回 npy。但是,我看到一个错误,因为 a 未声明。

有人可以告诉我如何在使用时在子 shell 内设置环境变量<<

答案1

<<构造引入了一个 shell这里的文档它在读取时被视为双引号字符串,因此变量在被 shell 读取时立即扩展。如果您启用告诉您未定义变量的 shell 功能,您会清楚地看到这一点。我将在此处的 BASH shell 中使用该功能:

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

要阻止 shell 在读取此处文档时扩展变量,您可以使用单引号标记或反斜杠每一个 用于每一个多变的:

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

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

请注意,此处文档内变量周围使用的引号类型与读取此处文档时 shell 是否扩展该变量无关。

附注始终用双引号引用变量扩展,这样它们就不会触发意外的 GLOB 文件名匹配。

聚苯硫醚在 shell 中打开未定义变量检查,以捕获输入错误。这会让你了解你的问题。

点对点不要使用 C shell 编写脚本。 他们有很多错误不一致之处

答案2

您正在使用由字符串分隔的此处文档EONG

当用 引入here-documents时<<word,here-document是否会扩展取决于是否有字符单词被引用。当没有引用任何字符时,此处文档会进行参数扩展、命令替换和算术扩展。当至少一个字符被引用时,这里的文档不会被扩展; Bourne 和 Korn(以及 POSIX)shell 使用完全不带引号的单词作为最终分隔符,而 C shell 使用单词照原样。

您可以将示例重写为:

#!/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\$a防止它在作为 stdin 传递到之前被 shell 替换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"

相关内容