Wenn "bash" funktioniert, warum ist "Quelle" einen Fehler auslösen?

Wenn "bash" funktioniert, warum ist "Quelle" einen Fehler auslösen?

Ich habe folgendes Skript:

#!/bin/bash
set -x
if :; then
    echo a
fi

Wenn ich ausführe bash /tmp/file, awird wiederholt, aber wenn ich ausführe source /tmp/file, erhalte ich:

bash: /tmp/test: line 6: syntax error: unexpected end of file

Die Ausgabe:

knezi@holly tmp]$set -x; source /tmp/test; set +x
+ source /tmp/test
++ set -x
bash: /tmp/test: line 6: syntax error: unexpected end of file
+ set +x

knezi@holly tmp]$set -x; command source /tmp/test; set +x
+ set -x
+ command source /tmp/test
+ source /tmp/test
++ set -x
bash: /tmp/test: line 6: syntax error: unexpected end of file
+ set +x

knezi@holly tmp]$bash -c "source /tmp/test"
+ bash -c 'source /tmp/test'
++ :
++ echo a
a


knezi@holly tmp]$od -c /tmp/test
0000000   #   !   /   b   i   n   /   b   a   s   h  \n   s   e   t    
0000020   -   x  \n   i   f       :   ;       t   h   e   n  \n  \t   e
0000040   c   h   o       a  \n   f   i  \n
0000051

Ausgabe von Befehlen shopt -pund set -o:http://pastebin.com/bsqc8aru

Ausgabe von set:http://pastebin.com/S9KpqZAL

declare -fpbringt nichts.

Ich dachte, das sourcemacht dasselbe wie bash, aber anstatt eine neue Sitzung zu starten, wird der Code in der aktuellen ausgeführt. Kann mir jemand diesen Fehler erklären?

Ich verwende Bash GNU Bash, Version 4.2.53(1)-Release (x86_64-redhat-linux-gnu).

Antwort1

Ich kann Ihr Verhalten reproduzieren, wenn ich den Alias ​​verwende fi:

$ alias fi=:
+ alias fi=:
$ . ./test
+ . ./test
++ set -x
bash: ./test: line 6: syntax error: unexpected end of file

Es funktioniert, wenn Sie es ausführen, schlägt aber fehl, wenn Sie es als Quelle verwenden, da Aliase in nicht-interaktiven Shells (der Art von Shell, die Shell-Skripte ausführt) nicht verfügbar sind. Wie indas Bash-Handbuch:

Aliase werden nicht erweitert, wenn die Shell nicht interaktiv ist, es sei denn, die expand_aliasesShell-Option wird mit gesetzt shopt(sieheDer Shopt Builtin).

Wenn Sie jedoch sourceetwas tun, wird es in Ihrer aktuellen Shell ausgeführt, die, da sie interaktiv ist, die Aliase bereits geladen hat, sodass der fiAlias ​​erkannt wird und die Beschaffung unterbricht.

verwandte Informationen