
Я использую следующий метод для передачи команд в подоболочку, запускаемую «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
Чтобы запретить оболочке расширять переменные в документе here во время его чтения, можно заключить тег в одинарные кавычки или использовать обратную косую черту.каждый использованиекаждыйпеременная:
$ bash <<'EOF'
> a=foo
> echo "$a"
> EOF
foo
$ bash <<EOF
> a=foo
> echo "\$a"
> EOF
foo
Обратите внимание, что типы кавычек, используемых вокруг переменной внутри документа Here, не имеют никакого отношения к тому, расширяется ли переменная оболочкой при чтении документа Here.
псВсегда заключайте расширения переменных в двойные кавычки, чтобы они не вызывали непреднамеренных совпадений имен файлов GLOB.
ппсВключите проверку неопределенных переменных в своих оболочках, чтобы отлавливать ошибки ввода. Это указало бы вам на вашу проблему.
пппсНе используйте оболочки C для написания скриптов. У них много ошибок инесоответствия
решение2
Вы используете документ, разделенный строкой EONG
.
При введении here-документов с помощью <<word
, то, подлежит ли here-документ расширению, зависит от того, есть ли в нем какой-либо символсловозаключен в кавычки. Если ни один символ не заключен в кавычки, то документ here-document подлежит расширению параметров, подстановке команд и арифметическому расширению. Если хотя бы один символ заключен в кавычки, документ here-document не подлежит расширению; оболочки 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
, чтобы \$a
предотвратить его замену оболочкой перед передачей в качестве stdin в 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"