
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 EONG
string.
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 $a
para \$a
evitar 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"