1044 Stimmen

Wie funktioniert "cat << EOF" in der Bash?

Ich musste ein Skript schreiben, um eine mehrzeilige Eingabe in ein Programm ( psql ).

Nach einigem Googeln habe ich folgende Syntax gefunden, die funktioniert:

cat << EOF | psql ---params
BEGIN;

`pg_dump ----something`

update table .... statement ...;

END;
EOF

Dies konstruiert die mehrzeilige Zeichenkette korrekt (aus BEGIN; a END; (einschließlich) und leitet es als Eingabe an psql .

Aber ich habe keine Ahnung, wie/warum das funktioniert, kann mir das bitte jemand erklären?

Ich beziehe mich hauptsächlich auf cat << EOF Ich weiß. > Ausgaben in eine Datei, >> an eine Datei anhängt, < liest die Eingabe aus der Datei.

Was bedeutet << genau tun?

Und gibt es eine Manpage dafür?

837voto

Vojtech Vitek Punkte 21769

Le site cat <<EOF Syntax ist sehr nützlich, wenn man mit mehrzeiligem Text in der Bash arbeitet, z.B. wenn man einen mehrzeiligen String einer Shell-Variablen, einer Datei oder einer Pipe zuweist.

Beispiele für cat <<EOF Verwendung der Syntax in der Bash:

1. Mehrzeilige Zeichenkette einer Shell-Variablen zuweisen

$ sql=$(cat <<EOF
SELECT foo, bar FROM db
WHERE foo='baz'
EOF
)

Le site $sql Variable enthält nun auch die Zeilenumbruchzeichen. Sie können dies überprüfen mit echo -e "$sql" .

2. Übergabe einer mehrzeiligen Zeichenkette an eine Datei in der Bash

$ cat <<EOF > print.sh
#!/bin/bash
echo \$PWD
echo $PWD
EOF

Le site print.sh Datei enthält nun:

#!/bin/bash
echo $PWD
echo /home/user

3. Übergabe eines mehrzeiligen Strings an eine Pipe in der Bash

$ cat <<EOF | grep 'b' | tee b.txt
foo
bar
baz
EOF

Le site b.txt Datei enthält bar y baz Zeilen. Die gleiche Ausgabe wird auf stdout .

750voto

kennytm Punkte 488916

Dies wird als heredoc Format um eine Zeichenkette in stdin bereitzustellen. Siehe https://en.wikipedia.org/wiki/Here_document#Unix_shells für weitere Einzelheiten.


から man bash :

Hier Dokumente

Diese Art der Umleitung weist die Shell an, die Eingabe von der aktuellen Quelle zu lesen, bis eine Zeile die nur ein Wort (ohne nachfolgende Leerzeichen) zu sehen ist.

Alle bis zu diesem Punkt gelesenen Zeilen werden dann als Standardeingabe für einen Befehl verwendet.

Das Format der here-Dokumente ist:

          <<[-]word
                  here-document
          delimiter

Keine Parametererweiterung, Befehlssubstitution, arithmetische Erweiterung oder Pfadnamen-Expansion wird durchgeführt bei Wort . Wenn irgendwelche Zeichen in Wort sind zitiert, die Begrenzungszeichen ist das Ergebnis der Entfernung von Zitaten auf Wort und die Zeilen im hier-Dokument werden nicht erweitert. Wenn Wort nicht in Anführungszeichen gesetzt ist, werden alle Zeilen der hier-Dokument werden einer Parametererweiterung unterzogen, Befehl Substitution und arithmetische Expansion. Im letzteren Fall wird die Zeichenfolge \<newline> ist ignoriert, und \ muss verwendet werden, um die Zeichen zu zitieren \ , $ et ` .

Wenn der Umleitungsoperator <<- , dann alle führenden Tabulatorzeichen aus den Eingabezeilen entfernt und die Zeile mit Begrenzungszeichen . Diese können Here-Dokumente in Shell-Skripten auf natürliche Weise eingerückt werden.

518voto

edelans Punkte 7439

In Ihrem Fall ist "EOF" als "Here Tag" bekannt. Im Grunde genommen <<Here sagt der Shell, dass Sie eine mehrzeilige Zeichenkette bis zum "Tag" eingeben werden Here . Sie können diesen Tag benennen, wie Sie wollen, er ist oft EOF o STOP .

Einige Regeln zu den Here-Tags:

  1. Der Tag kann eine beliebige Zeichenkette sein, in Groß- oder Kleinbuchstaben, obwohl die meisten Leute aus Konvention Großbuchstaben verwenden.
  2. Die Markierung wird nicht als Here-Markierung betrachtet, wenn es in dieser Zeile andere Wörter gibt. In diesem Fall wird es lediglich als Teil der Zeichenkette betrachtet. Das Tag sollte in einer separaten Zeile stehen, um als Tag zu gelten.
  3. Der Tag sollte keine führenden oder nachfolgenden Leerzeichen in der Zeile haben, um als Tag zu gelten. Andernfalls wird es als Teil der Zeichenkette betrachtet.

Beispiel:

$ cat >> test <<HERE
> Hello world HERE <-- Not by itself on a separate line -> not considered end of string
> This is a test
>  HERE <-- Leading space, so not considered end of string
> and a new line
> HERE <-- Now we have the end of the string

151voto

POSIX 7

kennytm zitiert man bash aber das meiste davon ist auch POSIX 7: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_07_04 :

Die Umleitungsoperatoren "<<" und "<<-" ermöglichen die Umleitung von Zeilen aus einer Shell-Eingabedatei, dem so genannten "here-document", in die Eingabe eines Befehls.

Das Hier-Dokument wird als ein einzelnes Wort behandelt, das nach dem nächsten <newline> und fährt fort, bis es eine Zeile gibt, die nur das Trennzeichen und ein <newline> , ohne <blank> Zeichen dazwischen. Dann beginnt das nächste here-Dokument, falls es eines gibt. Das Format ist wie folgt:

[n]<<word
    here-document
delimiter

wobei das optionale n für die Nummer des Dateideskriptors steht. Wenn die Nummer weggelassen wird, bezieht sich das here-Dokument auf die Standardeingabe (Dateideskriptor 0).

Wenn ein Zeichen in word in Anführungszeichen steht, wird das Trennzeichen durch Entfernen der Anführungszeichen in word gebildet, und die Zeilen des here-Dokuments werden nicht erweitert. Andernfalls ist das Begrenzungszeichen das Wort selbst.

Wenn keine Zeichen im Wort in Anführungszeichen stehen, werden alle Zeilen des here-Dokuments für die Parameterexpansion, Befehlssubstitution und arithmetische Expansion expandiert. In diesem Fall wird die <backslash> in der Eingabe verhält sich wie der <backslash> in doppelten Anführungszeichen (siehe Doppelte Anführungszeichen). Das Zeichen für doppelte Anführungszeichen ( '"' ) wird jedoch innerhalb eines here-Dokuments nicht besonders behandelt, außer wenn das doppelte Anführungszeichen innerhalb von "$()", "``" oder "${}" erscheint.

Wenn das Umleitungssymbol "<<-" ist, werden alle führenden <tab> Zeichen werden aus den Eingabezeilen und der Zeile mit dem nachgestellten Begrenzer entfernt. Wird mehr als ein "<<"- oder "<<-"-Operator in einer Zeile angegeben, so wird das mit dem ersten Operator verbundene here-Dokument von der Anwendung zuerst geliefert und von der Shell zuerst gelesen.

Wenn ein here-Dokument von einem Terminalgerät gelesen wird und die Shell interaktiv ist, schreibt sie den Inhalt der Variable PS2, die wie in Shell-Variablen beschrieben verarbeitet wird, in den Standardfehler, bevor sie jede Eingabezeile liest, bis das Trennzeichen erkannt wurde.

Exemples

Einige noch nicht genannte Beispiele.

Anführungszeichen verhindern die Erweiterung der Parameter

Ohne Anführungszeichen:

a=0
cat <<EOF
$a
EOF

Ausgabe:

0

Mit Zitaten:

a=0
cat <<'EOF'
$a
EOF

oder (hässlich, aber gültig):

a=0
cat <<E"O"F
$a
EOF

Ausgänge:

$a

Der Bindestrich entfernt führende Tabulatoren

Ohne Bindestrich:

cat <<EOF
<tab>a
EOF

donde <tab> ist ein wörtlicher Tabulator und kann mit Ctrl + V <tab>

Ausgabe:

<tab>a

Mit Bindestrich:

cat <<-EOF
<tab>a
<tab>EOF

Ausgabe:

a

Dies dient natürlich dazu, dass Sie Ihre Dokumente einrücken können. cat wie der umgebende Code, was einfacher zu lesen und zu pflegen ist. Z.B.:

if true; then
    cat <<-EOF
    a
    EOF
fi

Leider funktioniert dies nicht für Leerzeichen: POSIX bevorzugt tab Einrückung hier. Igitt.

37voto

Chris Halcrow Punkte 25120

<< EoF bedeutet im Grunde genommen:

<< - die mehrzeilige Eingabe ab der nächsten Zeile lesen und so behandeln, als ob es sich um Code in einer separaten Datei handelt"

EoF - "Lesen Sie sofort nach dem Wort EoF in der mehrzeiligen Eingabe gefunden wird"

Wie in anderen Antworten bereits erläutert, wird die mehrzeilige Eingabe als Hier Dokument

Ein Here-Dokument wird häufig verwendet, um eine Ausgabe zu erzeugen, die an einen nachfolgenden Prozess übergeben wird. Zum Beispiel cat << EoF kann verwendet werden, um mit Hilfe eines Here-Dokuments eine gewünschte Ausgabe zu erzeugen.

Hier ein Beispiel für die Verwendung eines Here-Dokuments zur Erstellung eines Textdokuments im laufenden Betrieb:

cat << EoF > ./my-document.txt
Hello world
Have a nice day
EoF

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X