definindo variáveis ​​​​dentro do subshell ao usar

definindo variáveis ​​​​dentro do subshell ao usar

Estou usando o método a seguir para passar comandos para um subshell iniciado por "newgrp".

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

Funciona bem, desde que eu não tente "definir" nada no subshell.

ou seja

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

Como você pode ver acima, defini a=npy dentro do subshell e fazer um echo $a deve retornar npy. No entanto, vejo um erro porque a não foi declarado.

Alguém pode me dizer como posso definir env vars dentro de um subshell enquanto uso<<

Responder1

A <<construção introduz um shellaqui documentoque é tratado como se fosse uma string entre aspas duplas à medida que é lida, então as variáveis ​​se expandem imediatamente à medida que são lidas pelo shell. Você veria isso claramente se habilitasse um recurso de shell que informa sobre variáveis ​​indefinidas. Usarei esse recurso no shell BASH aqui:

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

Para impedir que o shell expanda variáveis ​​no documento here enquanto ele está sendo lido, você pode colocar a tag entre aspas simples ou barra invertidatodo uso detodovariável:

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

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

Observe que os tipos de aspas usadas em torno da variável dentro do documento here não têm nada a ver com o fato de a variável ser ou não expandida pelo shell enquanto o documento here está sendo lido.

obs:Sempre coloque aspas duplas em suas expansões de variáveis ​​para que elas não acionem correspondências indesejadas de nomes de arquivos GLOB.

ppsAtive a verificação de variáveis ​​indefinidas em seus shells para detectar erros de digitação. Isso teria lhe dado uma pista sobre o seu problema.

pppsNão use shells C para scripts. Eles têm muitos bugs einconsistências

Responder2

Você está usando um documento aqui delimitado pela EONGstring.

Ao introduzir documentos aqui com <<word, se o documento aqui está ou não sujeito a expansão depende se algum caractere empalavraé citado. Quando nenhum caractere é citado, o documento aqui está sujeito a expansão de parâmetros, substituição de comandos e expansão aritmética. Quando pelo menos um caractere é citado, o documento aqui não está sujeito a expansão; Os shells Bourne e Korn (e POSIX) usam um formato totalmente sem aspaspalavracomo delimitador final, enquanto os shells C usampalavracomo é.

Você poderia reescrever seu exemplo como:

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

Caso contrário, com um não citadopalavra, você precisa escapar $apara \$aevitar que ele seja substituído pelo shell antes de ser passado como stdin para 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"

informação relacionada