Если "баш" работает, почему "источник" выдает ошибку?

Если "баш" работает, почему "источник" выдает ошибку?

У меня есть следующий скрипт:

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

Если я запускаю bash /tmp/file, aотображается эхо, но если я запускаю source /tmp/file, я получаю:

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

Выход:

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

Вывод команд shopt -pи set -o:http://pastebin.com/bsqc8aru

Вывод set:http://pastebin.com/S9KpqZAL

declare -fpничего не производит.

Я думал, что это sourceделает то же самое, что и bash, но вместо того, чтобы начать новую сессию, запускает код в текущей. Может кто-нибудь объяснить мне эту ошибку?

Я использую bash GNU bash версии 4.2.53(1)-release (x86_64-redhat-linux-gnu).

решение1

Я могу воспроизвести ваше поведение, если назову себя fi:

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

Он работает, когда вы его запускаете, но дает сбой, когда вы его используете, поскольку псевдонимы недоступны в неинтерактивных оболочках (тип оболочки, которая запускает скрипты оболочки). Как объяснено вруководство по bash:

Псевдонимы не раскрываются, когда оболочка не является интерактивной, если только не expand_aliasesзадан параметр оболочки с помощью shopt(см.Магазин Builtin).

Однако когда вы sourceчто-то делаете, это запускается в вашей текущей оболочке, которая, поскольку она интерактивна, уже загрузила псевдонимы, и поэтому псевдоним fiраспознается и нарушает источник.

Связанный контент