我使用以下方法将命令传递到由“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 中打开未定义变量检查,以捕获输入错误。这会让你了解你的问题。
答案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"