Ist eval $ (Katzendateiname) mit dem Quelldateinamen identisch?

8

Bei der Arbeit an einigen Bash-Funktionen kannte ich den source ...Befehl nicht und habe ihn eval $(cat ...)stattdessen verwendet. Jetzt frage ich mich, ob ich jede Verwendung davon ändern soll, oder ist es nur die gleiche Funktion?

Sie scheinen jetzt gleich zu funktionieren, aber vielleicht gibt es später einige irreführende Unterschiede, ich möchte es nur wissen.

Benjamin
quelle

Antworten:

5

eval $(cat ...)funktioniert nicht in allen Fällen. Beispielsweise werden Zeilenumbrüche bis zu einem einzelnen Leerzeichen konvertiert, $(cat ...)bevor der Inhalt von verarbeitet wird eval. Dies unterbricht häufig mehrzeilige Anweisungen wie Schleifen und hier Dokumente.

Versuchen Sie zum Beispiel die folgende Datei mit beiden Methoden:

for i in 1 2 3; do
 echo $i
done

cat<<EOF
a
b
c
EOF
Florian Diesch
quelle
3
Wenn Sie Anführungszeichen verwenden, bleibt das Leerzeichen intakt:eval "$(cat file)"
Glenn Jackman
1
Ja, das sollte auch funktionieren. Aber wenn man den Code trotzdem ändern muss, bevorzuge ich, sourceda es sich um einen Befehl handelt, der speziell dafür erstellt wurde.
Florian Diesch
8

Wie bereits von @glennjackman erwähnt, möchten Sie die Befehlsersetzung zitieren. Andernfalls wird der Inhalt durch Wortaufteilung und Pfadnamenerweiterung geändert, bevor er ausgewertet wird. Und während beide die Befehle aus der Datei ausführen, gibt es Unterschiede.

  • Wenn Sie ein Skript beziehen, werden verschiedene spezielle Shell - Variablen geändert werden, vor allem die BASH_SOURCE, BASH_LINENOund FUNCNAMEArrays. Diese sind nützlich zum Drucken von Fehlermeldungen und zum Debuggen.

  • Sie können mit dem returnBefehl ( help return) von einem Skriptskript zurückkehren . Mit der Bewertung erhalten Sie diesen Effekt nicht. Ebenso wird für die Auswertung keine RETURN-Falle ausgelöst.

  • Bei der Beschaffung eines Skripts können Sie Argumente an dieses übergeben. Mit dieser Bewertung kann man das nicht machen.

  • Bei der Auswertung liest die Befehlsersetzung den gesamten Inhalt der Datei in den Speicher, bevor sie an die Auswertung weitergeleitet wird. Wenn Sie es als Quelle verwenden, liest bash sofort aus der Datei.

Geirha
quelle
1

Es gibt eine schöne Zusammenfassung dessen, was Source, Eval und Exec hier tun: http://www.unix.com/shell-programming-scripting/54347-bash-shell-exec-eval-source-looking-help-understand.html

Ich würde denken, dass Ihre Verwendung von eval und source'ing der Datei dasselbe bewirkt. Ich bin mir jedoch nicht ganz sicher, ob sich Variablen im Index auf jeden Fall gleich verhalten. Ich würde empfehlen, wenn möglich die Quelle zu verwenden, da dies der einfachere Weg ist und Ihren Code lesbarer macht.

Hinz
quelle
3
vollständig tangential: Bash hat eine Abkürzung für $(cat file)->$(< file)
Glenn Jackman