Zuerst müssen Sie einen beliebigen Teil EOF
kurz danach zitieren <<
. Der natürlichste Weg ist <<"EOF"
, aber <<E"OF"
oder <<""EOF
wird es auch tun. Ohne diese envsubst
wird die Zeichenfolge mit $
bereits erweitert. Da envsubst
Zeichenfolgen mit Literal- $foo
oder Teilzeichenfolgen $
bearbeitet werden, bedeutet envsubst
das, sie zuvor zu erweitern, nichts. Außerdem wird die Shell in Ihrem Fall höchstwahrscheinlich $
zu einer leeren Zeichenfolge erweitert, da die Variablendefinition in Ihrem Code nur envsubst
die Shell selbst betrifft . es sei denn, die Variable mit dem gleichen Namen wurde (versehentlich?) zuvor in der Shell gesetzt.
Nun kommen wir zu Ihrer expliziten Frage. Sie können das Ergebnis an einen beliebigen Befehl weiterleiten, Sie müssen jedoch das endgültige EOF in einer separaten Zeile aufbewahren. Eine Möglichkeit, dies zu tun, ist wie folgt:
passphrase=$(<passphrase) envsubst <<"EOF" | oc create -f - apiVersion: v1 kind: Secret metadata: name: openshift-passphrase stringData: passphrase: $ EOF
Oder Sie können den Code ausführen, den Sie in einer Subshell haben:
( passphrase=$(<passphrase) envsubst <<"EOF" apiVersion: v1 kind: Secret metadata: name: openshift-passphrase stringData: passphrase: $ EOF ) | oc create -f -
Hinweis Bash Reference Manual sagt
Jeder Befehl in einer Pipeline wird in einer eigenen Subshell ausgeführt
Selbst in der ersten Lösung, wenn wir es geschafft haben, unsere Pipe ohne zu bauen ( )
, |
läuft der erste Teil (vorher ) sowieso in einer Subshell. Die zweite Lösung macht diese Subshell explizit. Nachdem wir explizit verwendet haben (
, wartet die Shell auf explizit )
. Dies ermöglicht uns, nach der Beendigung etwas zu platzieren EOF
.
Überraschenderweise können Sie auch bei der ersten Lösung mehrere document ( <<
) in einem einzigen zusammengesetzten Befehl verwenden. Solche Weiterleitungen sind in einer Pipe wenig sinnvoll, können aber mit &&
und nützlich sein ||
.
command1 <<EOF && command2 <<EOF || command3 <<EOF content1 EOF content2 EOF content3 EOF
Das gleiche umgeordnet mit expliziten Subshells:
( command1 <<EOF content1 EOF ) && ( command2 <<EOF content2 EOF ) || command3 <<EOF content3 EOF
Je nach Situation bevorzugen Sie eine Notation vor der anderen.
Zurück zu Ihrem spezifischen Beispiel. Mit einer Subshell benötigen Sie nicht einmal envsubst
:
( passphrase=$(<passphrase); oc create -f - <<EOF apiVersion: v1 kind: Secret metadata: name: openshift-passphrase stringData: passphrase: $ EOF )
Es gibt interessante Unterschiede zwischen diesem Weg und den vorherigen beiden:
- Dieses Mal ist die Subshell selbst sollte erweitern
$
, daher<<EOF
nicht<<"EOF"
. - Damit dies funktioniert, muss die Variable der Subshell bekannt sein, nicht nur
oc
; Dies bedeutet… passphrase=$(<passphrase) oc create -f - <<…
(beachten Sie das Fehlen eines Semikolons) würde nicht funktionieren. - Technisch würde derselbe Code, der nicht in einer Subshell (dh ohne
( )
) ist, auch funktionieren, aber dann würde die Variable in der Mainshell bleiben. Wenn Sie den Code in einer Subshell ausführen, stirbt die Variable mit. In Ihrem ursprünglichen Code ist die Variable nicht für die Main-Shell festgelegt. Ich denke, das ist, was Sie wollen.