Festlegen von Variablen innerhalb der Subshell bei Verwendung von

Festlegen von Variablen innerhalb der Subshell bei Verwendung von

Ich verwende die folgende Methode, um Befehle an eine Subshell zu übergeben, die von „newgrp“ gestartet wird.

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

Es funktioniert einwandfrei, solange ich nicht versuche, in der Subshell etwas „einzustellen“.

dh

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

Wie Sie oben sehen können, habe ich in der Subshell a=npy gesetzt und ein echo $a sollte npy zurückgeben. Allerdings wird mir ein Fehler angezeigt, da a nicht deklariert ist.

Kann mir jemand sagen, wie ich Umgebungsvariablen in einer Subshell festlegen kann, während ich<<

Antwort1

Das <<Konstrukt führt eine Schale einhier Dokumentdas wird beim Lesen so behandelt, als wäre es ein String in doppelten Anführungszeichen, sodass Variablen sofort erweitert werden, wenn sie von der Shell gelesen werden. Sie würden dies deutlich sehen, wenn Sie eine Shell-Funktion aktivieren, die Sie über undefinierte Variablen informiert. Ich werde diese Funktion hier in der BASH-Shell verwenden:

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

Um zu verhindern, dass die Shell Variablen im Here-Dokument erweitert, während es gelesen wird, können Sie das Tag oder den Backslash entweder in einfache Anführungszeichen setzenjeden Gebrauch vonjedenVariable:

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

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

Beachten Sie, dass die Art der Anführungszeichen, die um die Variable im Here-Dokument verwendet werden, nichts damit zu tun hat, ob die Variable beim Lesen des Here-Dokuments von der Shell erweitert wird oder nicht.

psSetzen Sie Ihre Variablenerweiterungen immer in doppelte Anführungszeichen, damit sie keine unbeabsichtigten Übereinstimmungen mit GLOB-Dateinamen auslösen.

ppsAktivieren Sie die Prüfung auf undefinierte Variablen in Ihren Shells, um Tippfehler zu erkennen. Dadurch wären Sie auf Ihr Problem aufmerksam geworden.

pppsVerwenden Sie keine C-Shells zum Skripting. Sie haben viele Fehler UndInkonsistenzen

Antwort2

Sie verwenden ein Here-Dokument, das durch die EONGZeichenfolge getrennt ist.

Bei der Einführung von Here-Dokumenten mit <<wordhängt die Frage, ob das Here-Dokument einer Erweiterung unterliegt, davon ab, ob ein beliebiges Zeichen inWortist in Anführungszeichen gesetzt. Wenn kein Zeichen in Anführungszeichen gesetzt ist, unterliegt das Here-Dokument der Parametererweiterung, Befehlsersetzung und arithmetischen Erweiterung. Wenn mindestens ein Zeichen in Anführungszeichen gesetzt ist, unterliegt das Here-Dokument nicht der Erweiterung; Bourne- und Korn-Shells (und POSIX-Shells) verwenden ein völlig unangeführtesWortals letztes Trennzeichen, während C-ShellsWortwie es ist.

Sie könnten Ihr Beispiel wie folgt umschreiben:

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

Andernfalls mit einem nicht zitiertenWort, müssen Sie es als Escapezeichen verwenden $a, um \$azu verhindern, dass es von der Shell ersetzt wird, bevor es als Standardeingabe an Folgendes übergeben wird 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"

verwandte Informationen